CSE 331: Software Design and Implementation, Autumn 2026
Your job is to deliver code that you know works.
11/**
12 * Decides whether a number is prime.
13 *
14 * @param n the number to decide
15 * @requires 0 < n
16 * @return true if n is prime, and false if it is not
17 */
18static boolean isPrime(int n) {18static boolean isPrime(int n) {
19 if (n < 100) {
20 return SMALL[n];
21 }
22 for (int k = 2; k * k < n; k++) {
23 if (n % k == 0) {
24 return false;
25 }
26 }
27 return true;
28}Below 100, a table: all eleven tests were lookups
The loop never ran. Is the method right?
$ javac IsPrime.java $ java IsPrime 121 true $ echo '11 * 11' | bc 121
Line 22 stops one step early: k * k < n where it should be k * k <= n
Nothing in the specification says to look past 100. The code does.
The code gives a list: which test to write next, and when you may stop
isPrime, each needing its answerisPrime always returned truetrue, and passesfalse, and failsDefinition
A set of tests has statement coverage of a method if every statement that some allowed input reaches is run by some test.
14static int min(int a, int b) {
15 int r = a;
16 if (a <= b) {
17 r = a;
18 }
19 return r;
20}a and bfirstIsSmaller: assertEquals(1, Min.min(1, 2))Every statement ran, and the test passes
secondIsSmaller: assertEquals(1, Min.min(2, 1))$ java -jar junit.jar execute --class-path . --select-class MinTest ⋮ │ ├─ firstIsSmaller() ✔ │ └─ secondIsSmaller() ✘ expected: <1> but was: <2> ⋮
The first test never ran the if with its condition false
if has two branches: condition true, condition falseif with no else still has a false branch, and it is emptyDefinition
A set of tests has branch coverage of a method if every branch that some allowed input takes is run by some test.
min have it; the second found the mistake10* y
11* 2 | 1
12* --------+-------- x
13* 3 | 4
14*
15* @param x the point's x coordinate
16* @param y the point's y coordinate
17* @requires x != 0 and y != 0
18* @return 1 if x > 0 and y > 0,
19* 2 if x < 0 and y > 0,
20* 3 if x < 0 and y < 0, and
21* 4 if x > 0 and y < 023static int quadrant(int x, int y) {
24 int q = 1;
25 if (x < 0) {
26 q = 2;
27 }
28 if (y < 0) {
29 q = q + 1;
30 }
31 return q;
32}(1, 1) runs both false branches; (-1, -1) runs both true branches
Two tests, and both branches of both ifs have run
6@Test
7void upperRight() {
8 assertEquals(1, Quadrant.quadrant(1, 1));
9}
10
11@Test
12void lowerLeft() {
13 assertEquals(3, Quadrant.quadrant(-1, -1));
14}Both pass. Is the method right?
16@Test
17void lowerRight() {
18 assertEquals(4, Quadrant.quadrant(1, -1));
19}$ java -jar junit.jar execute --class-path . --select-class QuadrantTest ⋮ │ ├─ upperRight() ✔ │ ├─ lowerLeft() ✔ │ └─ lowerRight() ✘ expected: <4> but was: <2> ⋮
quadrant has four, and testing every path finds the mistakeifs in a row: \(2^{10}\) paths, over a thousandindexOf and its four tests18static int indexOf(int[] a, int lo, int hi, int x) {
19 for (int i = lo; i < hi; i++) {
20 if (a[i] == x) {
21 return i;
22 }
23 }
24 return -1;findsTheOnlyMatch: {3, 0, 7}, 0 to 3, x = 7, expects 2returnsMinusOneWhenAbsent: {3, 0, 7}, 0 to 3, x = 42, expects -1findsTheFirstMatch: {5, 1, 5, 2, 5}, 0 to 5, x = 5, expects 0findsSomeMatch: the same input, expects any index holding 5findsTheOnlyMatch: lo 0, hi 3, so i takes 0, 1, 2. Three timesreturnsMinusOneWhenAbsent: the same range, no 42. Three timesfindsTheFirstMatch, findsSomeMatch: 5 at index 0. OnceNever zero. The missing test: an empty range, lo == hi
Definition
A set of tests has loop coverage of a method if, for every loop in it, some test runs the loop's body zero times, some test runs it once, and some test runs it more than once.
16static int pow(int b, int n) {
17 int r = 1;
18 for (int i = 0; i < n; i++) {
19 r = b;
20 }
21 return r;
22}0 <= n, when it fits in an intpow(2, 0) expects 1, and pow(2, 1) expects 2Every statement, both branches, both pass. Is the method right?
Line 19 should read r = r * b;
pow(2, 3) expects 8: the loop runs three times$ java -jar junit.jar execute --class-path . --select-class PowLoopTest ⋮ │ ├─ loopOnce() ✔ │ ├─ loopZeroTimes() ✔ │ └─ loopManyTimes() ✘ expected: <8> but was: <2> ⋮
32static int powRec(int b, int n) {
33 if (n == 0) {
34 return 1;
35 }
36 powRec(b, n - 1);
37 return b;
38}powRec(2, 0) expects 1, and powRec(2, 1) expects 2Every statement, both branches, both pass. Is the method right?
Lines 36 and 37 should read return b * powRec(b, n - 1);
powRec(2, 3) expects 8: three calls$ java -jar junit.jar execute --class-path . --select-class PowRecTest ⋮ │ ├─ oneCall() ✔ │ ├─ zeroCalls() ✔ │ └─ manyCalls() ✘ expected: <8> but was: <2> ⋮
ifUntil then, the list says which test to write next. Then you may stop.
The second list of James Wilcox and Kevin Zatloukal's "Testing" (2025).
IndexOfTestmin, pow, and powRec: found by a test the list asked forquadrant: two tests completed the list and passedisPrime: add 100 and 10,007, a prime, to our elevenisPrime(100): returns false, loop runs 1 isPrime(10007): returns true, loop runs 99
Every measure met, every test passes, and 121 still passes as prime
k * k < n divides inputs at k * k == nThat least is the floor. The motto says whose job it is.
isPrime's tests meet the floor, and 121 still passes as primemin(1, 2) expects 1 and min(3, 3) expects 3, and both passif ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
...Pasted once too often: the second goto fail; sits under no if
Every run jumps to the exit with err still success. The check below never ran
Statement coverage would have shown it: no test ran those lines, and none could
Adam Langley, "Apple's SSL/TLS bug" (2014), from Apple's published source.
Tip 4 would have shown it: a length larger than the payload is a boundary
OpenSSL Security Advisory, April 7, 2014 (CVE-2014-0160).
assertEquals, checked by eyeSum into readList and sumListsumList: one call, one assertEquals, no keyboardYour job is to deliver code that you know works.