2. JUnit Framework
2.1 Overview
2.2 Define a test in JUnit
2.3 Test Steps
2.4 API
JUnit (junit.org) in version 4.x is a test framework and open source software for the Java programming language. it uses annotations to identify methods to specify a test.
JUnit was designed by Kent Beck and Erich Gamma for writing and running test cases for Java programs and it includes core test framework class hierarchy. JUnit defines a common language for writing tests. For web applications JUnit offers the advantage to test the application without server.
The main websites for JUnit are the http://www.junit.org/ and the Github project page.
The framework creates the relationship between two processes: development and testing and automates the process of running tests.
It is one of a family of unit testing frameworks all known as xUnit and represents the Java version of the xUnit architecture for unit- and regression-testing frameworks.
JUnit is known as a standard for unit testing in Java and is included in many testing products which extend or are based on JUnit. The framework is not included in JDK, but many IDEs have built-in support for JUnit.
2.1 Overview
JUnit is simple to use and increases confidence in the correctness of the code. It can improve the design of the tested class because it makes more clear about how the objects are actually used.
Classes or methods are tested in isolation, although they do not function in isolation. They collaborate with other classes or methods which sometimes are not available during the unit tests. For example the request and response objects are created only by the servlet container and the servlet container isn’t running during the unit tests.
Classical testing (print statements for test output) and debugging are eliminated and first class objects are created. Tests become reusable and extendable.
2.2 Define a test in JUnit
A JUnit test is represented by a method contained in a class used only with the scope of testing.
Tested written with JUnit 4.x version should be annotated with @org.junit.Test annotation.
The annotated method uses the method from JUnit framework to check the expected result of the code versus the actual result.
Example:
Class to be tested:
package main.java.util; public class MyClass { public int addition(int x, int y){ return x+y; } }
Test class:
package test.java; import static org.junit.Assert.assertEquals; import main.java.util.MyClass; import org.junit.Test; public class MyClassTest { @Test public void testAddition() { // MyClass is tested MyClass tester = new MyClass(); // Tests AssertEquals (7, tester. addition (2, 5)); } }
In order to launch the test in Eclipse right – click on the test class MyClassTest.java and select Run As > JunitTest.
The result is obtained in the JUnit console:
The result is green if no error is present and red if the expected result is different than the obtained result.
It is recommended that the test class should have the “Test” suffix in their name because the Maven build system will automatically include such classes in its test scope.
The name of the test class should also explain what the test does in order to know the test scope without reading the implementation.
2.3 Test Steps
General test steps
A test can be run using a set of background resources or data commonly named as fixture. A fixture is created and destroyed by a TestCase through its methods setup() and teardown() which are executed during the running of the TestCase
The TestCase class calls setup() method before running each test for initialization and tearDown() when the test is complete for cleanup.
The test methods are put into the TestCase in order to share the fixture code. This is one of the design goals of JUnit: to reuse the fixture between the tests and to write more quickly and more tests.
The general test steps in Junit testing are:
1.Setup
2. Exercise
3. Verify
4. Teardown
TestCase lifecycle can be represented by the following diagram:
In JUnit 4.x the methods setup() and tearDown() have been replaced by annotations:
setup()-@Before
tearDown() - @After
testXYZ() - @Test
The extending of the TestCase class is no longer necessary beginning with this version.
In JUnit 3.x the example of testing used before (see 2.2) differs in not using annotations and extending the TestCase class:
package test.java; import main.java.util.MyClass; import junit.framework.TestCase; public class DummyTest extends TestCase { public void testAddition() { // MyClass is tested MyClass tester = new MyClass(); // Tests assertEquals(7,tester.addition(2, 5)); } }
It is recommendable that the versions 3.x of JUnit to not be used anymore because many other related frameworks have started to declare deprecated the JUnit 3.x support.
For example, from Spring 3.0 reference documentation:
[Warning] Legacy JUnit 3.8 class hierarchy is deprecated.
In general the latest stable release of a framework should be used when starting with a new project.
2.4 API
The unit contains more packages, but the most important is garnet.framework because it contains all the core classes.
Assert – this class defines a set of assert methods.
TestCase – this class defines the fixture to run multiple tests.
TestResult – this class collects the results after executing a test case.
TestSuite – this class is a composite of tests.
assertEquals(boolean expected, boolean actual) | Checks that two primitives/objects are equals |
assertNull(Object object) | Checks that an object is null. |
assertNotNull(Object object) | Checks that an object is not null. |
assertTrue(boolean condition) | Check if a condition is true |
assertFalse(boolean condition) | Asserts that a condition is false |
assertNotSame(String message,Object expected,Object actual) | Asserts that two objects refer to the same object. |
assertSame(Object expected,Object actual) | Asserts that tow objects refer to the same object |
void fail() | Fails a test with a given message. |
Assert
- assertXXX(“optional message”,expected,actual)
The declaration of this class is:
org.junit.Assert.*;
This class allows to reference assert methods without prefixing them with Assert
TestCase
@Test
Test classes are defined by annotate a method with @Test
To distinguish test classes from productive code they have a pre/postfix.
@Test(expected=Exception.class)
@Test(timeout=100)
The declaration of the class is:
org.junit.TestCase
The class defines the fixture to run multiple tests.
Methods of TestCase class:
getName() | Gets the name of the TestCase |
setName(String name) | Sets the name of the TestCase |
setup() | Set up the fixture (example opens a network connection) |
tearDown() | Tears down the fixture(example close a network connection) |
run(TestResult result) | Runs the test case and collects the results in TestResult |
runTest() | Override to run the test and assert its state. |
TestResult
The declaration of the TestResult class is:
org.junit.TestResult
TestResult collects the results after executing a test case.
Methods of Test Result:
void addError(Test test, Throwable t) | The method adds an error to the list of errors. |
void addFailure(Test test, AssertionFailedError t) | Adds a failure to the list of failures |
void endTest(Test test) | Informs the results that a test was completed. |
int errorCount() | Gets the number of the detected errors |
Enumeration<TestFailure> errors() | Returns an Enumeration for the errors |
int failureCount() | Gets the number of detected failures. |
void run (TestCase test) | Runs a testCase |
int runCount() | Gets the number of run tests. |
void startTest(Test test) | Informs the result that a test will be started |
void stop() | Marks that the test run should stop. |
TestSuite is used for the purpose of grouping and invocation. It groups test classes from the same package.
TestSuite is a container used to group tests to build test cycles:
- smoke tests
- integration tests
- separate fast/slow tests.
TestSuite can be nested.
Methods of the TestSuite
addTest(Test test) | the method adds a test to suite |
void addTestSuite(Class<? Extends TestCase> testClass) | adds tests of a class to the suite |
int countTestCases() | counts the number of test cases run by the suite |
String getName() | returns the name of the suite. |
void run(TestResult result) | runs the tests and gathers their results in TestResult. |
void setName(String name) | sets the name of the suite. |
Test testAt(int index) | returns the test at the given index |
int testCount() | returns the number of tests in this suite |
Static Test warning(String message) | returns a test which will fail and log a warning message. |