CS636 JUnit testing Tutorial Example, from the DevX tutorial (itself not that useful)

Code under test: (simplified)

package calc;
public class Calculator {
   private int result; // variable where the result is stored

   public void add(int n) { result = result + n; }
   public void subtract(int n)
   {
      result = result - 1; // Bug : should be result = result - n
   }
   public void divide(int n) { result = result / n; }
   public void clear() { // Cleans out the result
      result = 0;
   }
   public int getResult() { return result;
   }
}

JUnit4 test code: mark tests with annotation @Test, test setup with @Before:

package junit4;  // <--also can put the test in the same package (as in pizza1)
import calc.Calculator;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.*;

public class CalculatorTest {

  private static Calculator calculator = new Calculator(); // the "fixture"

  @Before
  public void clearCalculator() {  // set up the fixture for each test
    calculator.clear();
  }

  @Test
  public void add() {
    calculator.add(1);
    calculator.add(1);
    assertEquals(calculator.getResult(), 2);
  }

  @Test
  public void subtract() {
    calculator.add(10);
    calculator.subtract(2);
    assertEquals(calculator.getResult(), 8);
  }

  @Test
  public void divide() {
    calculator.add(8);
    calculator.divide(2);
    assertEquals(calculator.getResult(), 5);
  }

  @Test(expected = ArithmeticException.class)
  public void divideByZero() {
    calculator.divide(0);
  }

  @Ignore("not ready yet")
  @Test
  public void multiply() {
    calculator.add(10);
    //    calculator.multiply(10);
    assertEquals(calculator.getResult(), 100);
  }
}

Important idea: tests are independent, and all start from a known program state.

That's why above @Before clears the calculator, so nothing is left over from the last test.

Running from the command line:  not easy, so seldom done, but shows what’s happening. The junit.jar has the main, and takes our test as an arg. Need flag -ea to enable assertions:

topcat$ java -ea -cp lib/junit-4.11.jar:src org.junit.runner.JUnitCore junit4.CalculatorTest
JUnit version 4.11
.E.E.I.
Time: 0.009
There were 2 failures:
1) subtract(junit4.CalculatorTest)
java.lang.AssertionError: expected:<9> but was:<8>
        at org.junit.Assert.fail(Assert.java:88)
        at org.junit.Assert.failNotEquals(Assert.java:743)
... 2) divide(junit4.CalculatorTest) java.lang.AssertionError: expected:<4> but was:<5> at org.junit.Assert.fail(Assert.java:88) at org.junit.Assert.failNotEquals(Assert.java:743) at org.junit.Assert.assertEquals(Assert.java:118) ... FAILURES!!! Tests run: 4, Failures: 2

Ant Task: from build.xml in $cs636/junit

     <target name="test">
         <junit fork="yes">
              <formatter type="brief" usefile="false">
              <test name="junit4.CalculatorTest">
              <classpath refid="project.classpath">
         </classpath></test></formatter></junit>
     </target>

Eclipse integration Eclipse helps you create new unit tests. To execute them, all you need to do is right-click on the project and select Run as JUnit test, and all tests of the project will be run, showing green bar for success and red bar for failure.

@BeforeClass, @AfterClass: To save time, parts of the setup that need to be done only once for the whole run can be put in the @BeforeClass.  For us, the original database connection and setup could be done here.
Note that the @BeforeClass and @AfterClass methods must be public and static, unlike @Before and @After methods, which must be public and non-static.