Week 3
Week 3
Due Dates & Links
- Quiz 3 (will be released after class Monday) - Due 11:59am (just before noon) Wednesday October 12, 2022
- Week 3 Lab Report - Due 10pm (evening) Friday October 14, 2022
Lecture Materials
- Monday Lecture Handout (Google Slides)
- Monday Lecture Handout (PDF)
- Wednesday Lecture Handout (Google Slides)
- Wednesday Lecture Handout (PDF)
Notes from class
Links to Podcast
Note: Links will require you to log in as a UCSD student
To Read
- Read these two articles by Julia Evans (one summarized in a comic below):
- Read this article by John Regehr: How to Debug
- You don’t need to know what all the technical tools are in these readings (systems programming, CSS, divs, etc)
- From the Regehr article, focus on the vocabulary (symptom, bug, etc); from the Evans articles, focus on the vibes
- This article: https://drive.google.com/file/d/1zbMVZxsI1zOBPhSsvBi4kB5dPJuxyOJh/view?usp=sharing (Note that assigning an article doesn’t necessarily mean Joe agrees with everything in it…)
Lab Tasks
As usual, we publish these ahead of time, but they aren’t guaranteed to be final until the start of lab on Wednesday.
This week in lab, you will find symptoms of bugs by writing tests, and then narrow down the actual bug.
Setup
Make a fork of this repository (it’s OK if it’s public):
https://github.com/ucsd-cse15l-f22/lab3
There are a few relevant files for us:
ArrayExamples.java
ArrayTests.java
ListExamples.java
LinkedListExample.java
FileExample.java
The files that end in Example
or Examples
have code in them with bugs for you to find – in ListExamples
and ArrayExamples
, all the methods have bugs. In LinkedListExample
at least one of the methods on LinkedList
has a bug. in FileExample
, getFiles
has a bug. So many 🐛s!
The file ArrayTests.java
has some tests for the methods in ArrayExamples.java
. It uses a library called JUnit to run tests using methods called assertEquals
and assertArrayEquals
(and other assert...
methods). When we run this class with JUnit, it runs each method that has a @Test
annotation on it, and reports the success or failure of the assert
calls.
Since JUnit is an external library, it requires some extra work to compile and run. These two commands work well, and you should see output like the below when you run them:
MAC USERS:
local $ javac -cp .:lib/hamcrest-core-1.3.jar:lib/junit-4.13.2.jar *.java
local $ java -cp .:lib/hamcrest-core-1.3.jar:lib/junit-4.13.2.jar org.junit.runner.JUnitCore ArrayTests
JUnit version 4.13.2
..
Time: 0.006
OK (2 tests)
WINDOWS USERS:
local $ javac -cp ".;lib/hamcrest-core-1.3.jar;lib/junit-4.13.2.jar" *.java
local $ java -cp ".;lib/junit-4.13.2.jar;lib/hamcrest-core-1.3.jar" org.junit.runner.JUnitCore ArrayTests
..
Time: 0.006
OK (2 tests)
- The
*
in the first command tellsjavac
to compile all the.java
files in this directory. It’s a shorthand for writing them all out, so it’s a useful notation to start using now that we have several Java files to compile. - The
-cp
command-line argument stands for “classpath”. Java uses this command-line argument to know where to look for classes. It takes paths separated by:
, so the first place it will look is.
, the current directory. After that, it will look for classes in the two.jar
files in thelib
directory. A.jar
file is like a.zip
file of a bunch of classes, and Java knows how to work with them. - While you might think the
..
in the output belowJUnit
has something to do with a path, it’s actually printing a.
for each test that runs. So if you run hundreds of tests, you can kinda watch the progress by seeing how the dots count up.
Write down in notes: Who in your group has never seen -cp
before? Who in your group has never seen JUnit before? Has anyone written tests in a different way in Java? What about in a different language?
Symptoms and Failure-inducing Inputs
Array Methods
The two tests we wrote for you pass, but these two reverse implementations have bugs! Write more tests to demonstrate that the two implementations have bugs, and identify the bugs.
Write down in notes – For each, what was the failure-inducing input (the test)? What was the symptom (the output when the test failed)? What was the bug (the problem in the code)? Be as specific as possible to fill this in: copy the code for your tests, the output for the symptoms, and the code change you need to make for the bug.
Checkpoint – After fixing the reverse methods, make a commit and push to your repository. It’s really useful to checkpoint your work this way; you will be able to see in the commit history each of the elements above as well.
Go on and do the same thing for averageWithoutLowest
(the last array method), making sure to note symptoms, failure-inducing inputs, and bugs. Discuss with your group – did people find different ways to show the same bugs?
If you’re having trouble thinking of tests, try starting from the smallest possible inputs (an empty array), and then trying increasing sizes of arrays to structure your thinking.
List Methods
There are two methods in ListExamples
, each of which has a bug. For this program, create a new file called ListTests.java
with JUnit tests. Do the same exercise, carefully designing your tests to get failing inputs, symptoms, and eventually identify the bugs. Keep in mind that most of the time we can find relatively small inputs that trigger the buggy behavior!
Write down in notes – Symptoms, inputs, and bugs.
Checkpoint – Commit your changes, and don’t forget to add the new file! This is one of the most common mistakes I make with git
that is annoying for my collaborators: I add a new file locally and forget to put it on Github for them to see!
Linked List Methods
The file LinkedListExample.java
has an implementation of a linked list that is, in fact, buggy. We won’t tell you which method(s) have the bugs. Create a file called LinkedListTests.java
and write tests in that file.
Note that for this case, your failure-inducing input requires a little more work to construct: you have to build lists and try out the methods. All of that work is part of the “failure-inducing input”, and it’s useful to have it all written down in code so that we don’t have to remember it or re-type it each time we want to run the test.
Write down in notes – Symptoms, inputs, and bugs.
Reflect, write down in notes – You’ve now had to create two new test files (one for ListExamples
and one for LinkedListExample
). What actions did you take in your editor to do this? How long did it take you? Could you or did you use copy/paste effectively to avoid lots of typing? Could you or did you use the up arrow in the terminal to “get back” earlier commands rather than typing them out again? Any other tricks you could use to make this more painless in the future?
Discuss with your group! The long-term goal here is to learn tips and tricks to take tasks that might be annoying 5-minute tasks and turn them into 30-second tasks. It really changes how you think about writing tests if the process of getting started takes less time!
Checkpoint – Commit your changes, and don’t forget to add the new file! This is one of the most common mistakes I make with git
that is annoying for my collaborators: I add a new file locally and forget to put it on Github for them to see! (Yes, this is repeated from the last section. It’s a common mistake, so it’s worth repeating!)
File Methods
The file FileExample.java
has an implementation of a method that works with the filesystem and, fortunately for our learning, it’s buggy.
This one is interesting because the definition of a “failure-inducing input” is trickier – this program won’t run without us having some files and paths available to try! So the first thing you may want to do is create the example file structure in the comment in that file in your repository! Then you can write tests that use that file. You can create this just using VScode’s “new file” and “new folder” buttons/options.
To help you read and understand the program check out the File
documentation here:
https://docs.oracle.com/javase/8/docs/api/java/io/File.html
Write down in notes – Symptoms, inputs, and bugs. Remember that your input is not just the code, but also the test files you created.
Checkpoint – Commit your changes, and don’t forget to add the new files, including the files you created as test input! All these files need to be a part of the repository so that we can run the tests. (This is a particularly annoying one to realize you missed later – the test will fail because the input data doesn’t exist!)
Discuss – Out of all the bugs above, which was the most interesting bug you found? Have you ever made bugs like these yourself in your own programs? What about having JUnit tests written might be useful one or two weeks from now?
Extend Your Server
If you’re satisfied you’ve found each bug along with a failure-inducing input and a symptom for each one, try extending your server from last week (do this in pairs or as a group).
Instead of just tracking a List
of strings, instead have your server allow searching through a directory of files (searching the contents of the files for query words). Make a directory in the same directory as your code that has plain text files in it, and return all the filenames that have contents that match the query. Hint – use the fixed getFiles
method in your solution!
Week 3 Lab Report
As with the first lab report, you’ll write this as a Github Pages page, then print that page to PDF and upload to Gradescope. Include on your page two parts.
Part 1
Show the code for your Simplest Search Engine from week 2 (use a code block in Markdown). Then, show three screenshots of using it including at least one add and one query, showing the URL in the browser and the response on the page.
For each screenshot, describe:
- Which methods in your code are called
- What the values of the relevant arguments to those methods are, and the values of any relevant fields of the class
- If those values change, how they change by the time the request is done processing
Part 2
Choose two of the bugs from different files above. For each, show:
- The failure-inducing input (the code of the test)
- The symptom (the failing test output)
- The bug (the code fix needed)
- Then, explain the connection between the symptom and the bug. Why does the bug cause that particular symptom for that particular input?
Upload your post to the Lab Report 2 – assignment on Gradescope