1.4. Procesos Adjetivos 1. Nivel de Asesoría
1.4.2. Nivel de Apoyo
1.4.2.1. Dirección Administrativa Financiera Misión: Administrar, gestionar y controlar los
3.4 The JUnit Test Framework
A test harness is a driver program written to test a method or class. It does this by providing known inputs for a series of tests, called a test suite, and then compares the expected and actual results of each test and an indication of pass or fail.
A test framework is a software product that facilitates writing test cases, organizing the test cases into test suites, running the test suites, and reporting the results. One test framework often used for Java projects is JUnit, an open-source product that can be used in a stand-alone mode and is available from junit.org. It is also bundled with at least two popular IDEs (NetBeans and Eclipse). In the next section, we show a test suite for the ArraySearch
class constructed using the JUnit framework.
JUnit uses the term test suite to represent the collection of tests to be run at one time. A test suite may consist of one or more classes that contain the individual tests. These classes are called test harnesses. A test harness may also contain common code to be executed before/
after each test so that the class being tested is in a known state.
Each test harness in a test suite that will be run by the JUnit main method (called a test run-ner) begins with the two import statements:
import org.junit.Test;
import static org.junit.Assert.*;
The first import makes the Test interface visible, which allows us to use the @Test attribute to identify test cases. Annotations such as @Test are directions to the compiler and other
3.4 The JUnit Test Framework 129
language-processing tools; they do not affect the execution of the program. The JUnit main method (test runner) searches the classes that are listed in the args parameter for methods with the @Test annotation. When it executes them, it keeps track of the pass/fail results.
The second import statement makes the methods in the Assert class visible. The assert meth-ods are used to determine pass/fail for a test. Table 3.2 describes the various assert methods that are defined in org.junit.Assert. If an assert method fails, then an exception is thrown causing an error to be reported as specified in the description for method assert ArrayEquals. If one of the assertions fail, then the test fails; if none fails, then the test passes.
TA B L E 3 . 2
Methods Defined in org.junit.Assert
Method Parameters Description
assertArrayEquals [message,] expected, actual
Tests to see whether the contents of the two array parameters expected and actual are equal. This method is overloaded for arrays of the primitive types and Object. Arrays of Objects are tested with the .equals method applied to the corresponding elements. The test fails if an unequal pair is found, and an AssertionError is thrown. If the optional message is included, the AssertionError is thrown with this message followed by the default message; otherwise it is thrown with a default message
assertEquals [message,] expected, actual
Tests to see whether expected and actual are equal. This method is overloaded for the primitive types and Object. To test Objects, the .equals method is used
assertFalse [message,] condition Tests to see whether the boolean expression condition is false assertNotNull [message,] object Tests to see if the object is not null
assertNotSame [message,] expected, actual
Tests to see if expected and actual are not the same object. (Applies the !=
operator.)
assertNull [message,] object Tests to see whether the object is null assertSame [message,] expected,
actual
Tests to see whether expected and actual are the same object. (Applies the ==
operator.)
assertTrue [message,] condition Tests to see whether the boolean expression condition is true
fail [message] Always throws AssertionError
E X A M P L E 3 . 3 Listing 3.1 shows a JUnit test harness for an array search method (ArraySearch.search) that returns the location of the first occurrence of a target value (the second parameter) in an array (the first parameter) or −1 if the target is not found. The test harness contains methods that implement the tests first described in Section 3.2 and repeated below.
r The target element is the first element in the array.
r The target element is the last element in the array.
r The target is somewhere in the middle.
r The target element is not in the array.
r There is more than one occurrence of the target element and we find the first occurrence.
r The array has only one element and it is not the target.
r The array has only one element and it is the target.
r The array has no elements.
Method firstElementTest in Listing 3.1 implements the first test case. It tests to see whether the target is the first element in the 7-element array {5, 12, 15, 4, 8, 12, 7}. In the statement
assertEquals("5 is not found at position 0", 0, ArraySearch.search(x, 5));
the call to method ArraySearch.search returns the location of the target (5) in array x. The test passes (ArraySearch.search returns 0), and JUnit remembers the result. After all tests are run, JUnit displays a message such as
Testsuite: KW.CH03New.ArraySearchTest
Tests run: 9, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.111 sec
where 0.111 is the execution time in seconds. The Netbeans IDE also shows a Test Results window as shown in Figure 3.1. (The gray box at the end of Section 3.5 shows how to access JUnit in Netbeans.)
If instead we used the following statement that incorrectly searches for target 4 as the first element
assertEquals("4 is not found at position 0", 0, ArraySearch.search(x, 4));
the test would fail and AssertionErrorException would display the messages
Testcase: firstElementTest: FAILED
4 not found a position 0 expected:<0> but was:<3>
If we omitted the first argument in the call to assertEquals, the default message
Testcase: firstElementTest: FAILED expected:<0> but was:<3>
would be displayed instead where 3 is the position of the target 4.
F I G U R E 3 . 1 Test Results
L I S T I N G 3 . 1
JUnit test of ArraySearch.search import org.junit.Test;
import static org.junit.Assert.*;
/**
* JUnit test of ArraySearch.search * @author Koffman and Wolfgang */
public class ArraySearchTest {
// Common array to search for most of the tests private final int[] x = {5, 12, 15, 4, 8, 12, 7};
3.4 The JUnit Test Framework 131
@Test
public void firstElementTest() {
// Test for target as first element.
assertEquals("5 not at position 0", 0, ArraySearch.search(x, 5));
} @Test
public void lastElementTest() {
// Test for target as last element.
public void notInArrayTest() { // Test for target not in array.
assertEquals(‐1, ArraySearch.search(x, ‐5));
} @Test
public void multipleOccurencesTest() {
// Test for multiple occurrences of target.
assertEquals(1, ArraySearch.search(x, 12));
} @Test
public void oneElementArrayTestItemPresent() { // Test for 1‐element array
int[] y = {10};
assertEquals(0, ArraySearch.search(y, 10));
} @Test
public void oneElementArrayTestItemAbsent() { // Test for 1‐element array
int[] y = {10};
assertEquals(‐1, ArraySearch.search(y, ‐10));
} @Test
public void emptyArrayTest() { // Test for an empty array int[] y = new int[0];
assertEquals(‐1, ArraySearch.search(y, 10));
}
@Test(expected = NullPointerException.class) public void nullArrayTest() {
int[] y = null;
int i = ArraySearch.search(y, 10);
} }
3.5 Test‐Driven Development
Rather than writing a complete method and then testing it, test-driven development involves writing the tests and the method in parallel. The sequence is as follows:
Write a test case for a feature.
Run the test and observe that it fails, but other tests still pass.
Make the minimum change necessary to make the test pass.
Revise the method to remove any duplication between the code and the test.
Rerun the test to see that it still passes.
We then repeat these steps adding a new feature until all of the requirements for the method have been implemented.
We will use this approach to develop a method to find the first occurrence of a target in an array.
Case Study: Test‐Driven Development of ArraySearch.search
Write a program to search an array that performs the same way as Java method ArraySearch.
search. This method should return the index of the first occurrence of a target in an array, or 1 if the target is not present.
E X E R C I S E S F O R S E C T I O N 3 . 4
S E L F ‐ C H E C K
1. Modify the test(s) in the list for Example 3.3 to verify a method that finds the last