Tests and implementation

Figure 306. Step 1 + 2: Specify method, write skeleton Slide presentation
/**
 * Identifying prime numbers.
 */
public class Prime {
  /**
   * Check whether a given integer candidate is prime or not 
   * @param candidate A positive integer value
   * @return true if and only if candidate is a prime number.
   */
  public static boolean isPrime(int candidate) {
    return true ; //TODO: Dummy value to be implemented correctly 
  }
}

An informal specification of the method's expected behaviour. This comprises the descriptions of all method parameters among with the expected outcome.

Note that boolean isPrime(int value) is being specified as a partial method: The value parameter must not contain negative values. Thus negative values likely lead to unexpected results.

Since our current implementation is just a skeleton we simply return a constant value. Other choices:

  • return false;

  • return 231 < value;

  • ...

In fact every syntactically correct expression will do since we defer our implementation to a later step. Thus the only requirement with respect to our code is its ability to get compiled. Returning a single value obviously is the most simple way to comply.


Figure 307. Execution yet being flawed Slide presentation
for (int i = 1; i < 20;i++) {
  System.out.println(i + " is " + (Prime.isPrime(i) ? " a " : " not a ")
    + " prime number");
}
1 is a prime number
2 is a prime number
3 is a prime number
4 is a prime number
5 is a prime number
...

Figure 308. Sample test data Slide presentation
Input Expected output Input Expected output
1 false 7 true
2 true 8 false
3 true 9 false
4 false 10 false
5 true 11 true
6 false 12 false

Figure 309. Step 3: Junit based specification test Slide presentation
public class PrimeTest {

  @Test  public void test_1_isNotPrime() {
    Assert.assertFalse(Prime.isPrime(1));
  }
  @Test  public void test_2_isPrime() {
    Assert.assertTrue(Prime.isPrime(2));
  }

  void someOrdinaryMethod()  {...}
...

A @Test annotation triggers automatic method execution by the Junit framework.

Any methods not being annotated by @Test will not be called by the Junit framework. They may however be called indirectly by test methods e.g. test_1_isNotPrime() thus acting as helper methods.


Figure 310. Junit skeleton test result (Maven CLI) Slide presentation
goik@goiki Prime_v01> mvn test
...
Running de.hdm_stuttgart.mi.sd1.PrimeTest
Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, 
         Time elapsed: 0.065 sec <<< FAILURE!
...
test_1_isNotPrime(de.hdm_stuttgart.mi.sd1.PrimeTest)
         Time elapsed: 0.001 sec  <<< FAILURE!
java.lang.AssertionError
	at org.junit.Assert.fail(Assert.java:86)
	at org.junit.Assert.assertTrue(Assert.java:41)
	at org.junit.Assert.assertFalse(Assert.java:64)
	at org.junit.Assert.assertFalse(Assert.java:74)
...

Similar to a main(...) method execution we may execute Junit Tests using our IDE:

Figure 311. Junit skeleton test result (IDE) Slide presentation
Junit skeleton test result (IDE)

Test test_1_isNotPrime() accidentally failing due to dummy implementation Figure 306, “Step 1 + 2: Specify method, write skeleton ”.

Test test_2_isPrime() accidentally succeeding due to dummy implementation Figure 306, “Step 1 + 2: Specify method, write skeleton ”.


Before replacing the skeleton implementation Figure 306, “Step 1 + 2: Specify method, write skeleton ” we supply additional tests:

Figure 312. Step 3: Providing more prime tests Slide presentation
@Test public void test_Primes() {
  Assert.assertTrue(Prime.isPrime(3));
  Assert.assertTrue(Prime.isPrime(5));
  Assert.assertTrue(Prime.isPrime(7));
  Assert.assertTrue(Prime.isPrime(11));
    ...  }
@Test public void testOddNonPrimes() {
  Assert.assertFalse(Prime.isPrime(9));
  Assert.assertFalse(Prime.isPrime(15));
  Assert.assertFalse(Prime.isPrime(21));...}

Since all even numbers greater than two are non-prime we add:

Figure 313. Step 3: Prime mass testing Slide presentation
@Test public void testEvenNonPrimes() {
  for (int i = 2; i < 100; i++) {
    Assert.assertFalse(Prime.isPrime(2 * i));
  }
}

Now its time actually implementation isPrime():

Figure 314. Step 4: Implement skeleton Slide presentation
public static boolean isPrime(int candidate) {
  for (int i = 2; i < candidate; i++) {
    if (0 == candidate % i) { // i divides value
      return false;
    }
  }
  return candidate != 1;
}

Figure 315. Step 5: Testing our first implementation Slide presentation
goik@goiki Prime_v01> mvn test
...
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running de.hdm_stuttgart.mi.sd1.PrimeTest
Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.055 sec

Results :

Tests run: 5, Failures: 0, Errors: 0, Skipped: 0