- Forward


JUnit v4
An Introduction


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu

Print

Background
Back SMYC Forward
  • Purpose:
    • A way to write, organize, and run repeatable unit tests (i.e., a test harness or testing framework)
  • Why It's Popular:
    • Open source
    • Easy to use
    • Flexible
    • Can be integrated with other tools
Creating Test Classes
Back SMYC Forward
  • Steps:
    • Create a file (usually named ClassNameTest.java)
    • Add the necessary import statements
    • Add a class declaration
    • Add one or more tests (i.e., methods preceded by the annotation @Test)
  • Contents of Tests:
    • Setup code
    • One or more calls to assert___() methods
Some assert___() Methods
Back SMYC Forward
  • Equals Checks:
    • Assert.assertEquals([description,] expected, actual)
    • Assert.assertEquals([description,] expected, actual, tolerance)
    • Assert.assertEqualsArray([description,] expected, actual[, tolerance])
  • True/False Checks:
    • Assert.assertTrue([description,] actual)
    • Assert.assertFalse([description,] actual)
  • Null Checks:
    • Assert.assertNull([description,] actual)
An Example
Back SMYC Forward
  • The Class to Tested:
    • Atom
  • The Methods to Test:
    • public int getAtomicNumber()
    • public boolean equals(Atom other)
An Example (cont.)
Back SMYC Forward
import static org.junit.Assert.*; import org.junit.Test; public class AtomTest { @Test public void testGetAtomicNumber() { // Setup - Declare and construct an Atom for oxygen Atom o; o = new Atom("O", 8, 16); // This is a call to Assert.assertEquals() but the class name // isn't needed because of the static import. // // It checks that the value returned by getAtomicNumber() is // equal to 8 (as it should be) assertEquals("Oxygen", 8, o.getAtomicNumber()); } @Test public void testEquals() { // Setup - Declare and construct an Atom for oxygen and two // for hydrogen Atom h, hh, o; h = new Atom("H", 1, 1); hh = new Atom("H", 1, 1); o = new Atom("O", 8, 16); // Compare two Atom objects that should be the same assertTrue("Two H atoms", h.equals(hh)); // Compare two Atom objects that should be different assertFalse("H and O", h.equals(o)); assertFalse("O and H", o.equals(h)); } }
Testing Methods that Throw Exceptions
Back SMYC Forward
  • The Easiest Approach:
    • Use the optional expected element of the @Test annotation
  • How It Works:
    • It tells the method that calls the test method to catch the exception that is thrown
An Example (cont.)
Back SMYC Forward
  • The Method to Test:
    • The Atom constructor
  • The Expected Result:
    • It should throw an IllegalArgumentException if either of the parameters are negative
  • Implications for the Test Method:
    • It should not have any assert___() invokations after the exception will be thrown
An Example (cont.)
Back SMYC Forward
@Test(expected = IllegalArgumentException.class) public void testConstructor_IllegalArguments() { Atom o; o = new Atom("O", -8, -16); }
Common Setup/Cleanup
Back SMYC Forward
  • The Situation:
    • All of the test methods use the same setup code and/or the same cleanup code
  • One Approach:
    • Move the code to private methods and invoke them at the top and/or bottom of each test method
  • A More Elegant Approach:
    • Use the @Before annotation to indicate that the method should be invoked before every test method and the @After annotation to indicate that the method should be invoked after every test method
Common Setup/Cleanup (cont.)
Back SMYC Forward
  • Remember:
    • You must import org.junit.Before and/or org.junit.After
    • Methods annotated with @Before or @After will be invoked before/after every test method
  • Note:
    • In general, you should not count on the test methods being executed in a particular order
Some Notes About Terminology
Back SMYC Forward
  • "Assertions":
    • The assert___() methods are often called assertions, but they should not be confused with assert statements in Java
  • Test (and "Test Case"):
    • JUnit calls each test method an individual test but each invokation of an assert___() method can be thought of as an individual test
Executing JUnit Tests
Back SMYC Forward
  • The Basics:
    • You must execute a "test runner" that executes all of the appropriately annotated methods in a test class
  • From the Command Line:
    • You have to include the appropriate .jar files in the CLASSPATH and execute a "test runner" (commonly org.junit.runner.JUnitCore) passing it the name of the test class
  • From an IDE:
    • You have to let the IDE know that the test class is a JUnit test (usually when you create it) and then, when you run it, the IDE knows to actually start a "test runner"
There's Always More to Learn
Back -