Discussion 2: Unit Test Coverage
The goal of today’s discussion is to practice reading documentation and using specifications to write unit test suites that provide good coverage. A good suite of unit tests for a class should have all of its tests pass when the class definition meets its specification. In addition, (and perhaps more importantly for the unit tests to serve their role), at least one unit test within the suite should fail if the class definition deviates from its specification (i.e., the class is buggy). Can you write tests to track down these bugs?
Learning Outcomes
- Write comprehensive unit tests for a method given only its specification and signature.
- Evaluate the coverage of a unit test suite on a method or a class.
Reminder: Discussion Guidelines
The work that you complete in discussion serves as a formative assessment tool; it offers the opportunity to assess your understanding of the material and for our course staff to get a “pulse” on how things are going, so we can make adjustments in future classes. Your grade in discussion is based on your attendance, active participation, and completion of that day’s activity. More information about the grading and expectations can be found in the syllabus.
Since discussion activities are not graded for correctness, we do not restrict what resources you may use to complete them, which include notes, books, unrestricted conversations with other students, internet searches, and the use of large language models or other generative AI. We advise you to be pragmatic about your use of these resources and think critically about whether they are enhancing your learning. Discussion activities are intended to serve as “strength training” for programming tasks we will expect on assignments and exams (and that you will encounter in future courses and careers), and their main benefit comes from thinking critically to “puzzle” them out.
Background: Bounding Boxes
The code for today’s discussion concerns bounding boxes. A bounding box is a rectangular area in a 2D coordinate plane. Bounding boxes are a foundational object in computer graphics since the array of pixels on a computer screen can serve as a (subset of a) coordinate plane. Calculations involving bounding boxes are used to take the coordinates of a user’s mouse click and obtain the element on the screen that they are clicking (possibly in the presence of multiple overlapping windows). They are also used to lay out graphical components of a user interface, including the HTML code that is used to render this webpage. As a final example, bounding boxes are used to model the positions of characters in a game to compute collisions or other actions.
In this discussion, we will restrict our attention to closed bounding boxes. Closed (a term from topology) boxes contain all the points on their boundaries (their outer edges and corners). For example, the closed bounding box in the following figure contains all of the points (3,2), (5,3), and (2,5).
These differ from open boxes, which do not contain their boundary points. Some edge (ha, pun!) cases of bounding boxes include those with width 0 (i.e., vertical line segments), height 0 (i.e., horizontal line segments), and both width and height 0 (i.e., single points).
These “line segment” and “point” boxes contain all of their points. We can also consider a special “empty” bounding box that does not contain any points. One final important concept is intersecting bounding boxes. The intersection of two bounding boxes is the set of all points that are contained in both of them. Convince yourself that these points also form a bounding box.
Writing a Test Suite
Imagine that you are on a team that is writing some graphics software that involves bounding box computations. Together with the other developers, you agree on the specification for two classes, Point and BoundingBox. The specifications are outlined in these Javadoc pages.
The Point class is fairly straightforward, but the BoundingBox class is a bit more involved. Your team decides to break up into two groups. One group will work on defining the BoundingBox methods according to their specifications, while the other group (your group) is in charge of developing the unit test suite for the BoundingBox class.
Take some time to write unit tests for each of the methods of the BoundingBox class. Your tests should go in the file tests/cs2110/BoundingBoxTest. These tests should involve:
- Constructing
BoundingBoxobjects (either directly through the constructors or using theintersectWith()method), - Using JUnit
assertEquals()on the return values of methods such asupperLeftCorner(),width(),height()andarea()to make sure these boxes have the expected properties, - Using JUnit
assertTrue()andassertFalse()to check the behavior of theisEmpty(),containsPoint(), andcontainsBox()methods.
We’ve provided a few tests to get you started. To achieve good coverage in your test suite, you should take care to address different possibilities that may arise when using these methods. Having comprehensive unit tests will give more confidence to the development team that their implementation is correct (before it is integrated into full graphics software).
Assessing Your Test Coverage
In the release code, we’ve included correct implementations of the Point and BoundingBox classes. We recommend that you not look at these when you are developing your tests. In black box testing, we design our tests using only the specifications.
When you run your tests in IntelliJ (against these correct reference implementations), they should all pass. However, this does not offer a sense of how good your test coverage is. For that, you should upload your BoundingBoxTest class to Gradescope. This will run your tests against some buggy BoundingBox implementations. If your test suites offer good coverage, some of your tests should fail in the presence of these bugs.
If you see green output from the autograder, this means that your tests found the bug(s) in one of our implementations. Look through the output to diagnose where this bug is (so you can report back to the development team). If you see red output from the autograder, this means that the buggy code evaded your tests. Think about what additional checks you can add to your test suite to increase its coverage.
Submission
The BoundingBoxTest.java that your group’s primary author uploads to the “Discussion 2” Gradescope assignment will serve as this week’s deliverable. Make sure all members of your group are tagged on the submission.