LAB 4- Testing with JUNIT
Goal
Given Fruit.java and Bag4fruit.java, using JUnit- write a test for testing methods of Bag4fruit.java
- write a test suite for running automatically the tests you wrote previously
Testing Strategy
Design for test:- Seperate logic that can be automatically tested from logic that requires human judgement
- Seperate pure computation from database or file access
- make sure to include both valid and invalid values
- make sure to include both reasonable and unreasonable values
- It can also be useful to try to force the system to generate specific outputs: maximum, minumum, valid, invalid, empty, small, large
- Make sure that you know the corrected expected output. A "test oracle" is code that computes the expected result in a known-good way
- Look at the condition of each branch
- Decide what variable value would be needed to make it true or false
First step with JUnit: write Test Case
First, you'll write a test case to exercise a single software component, Bag4fruit.java1. Define a subclass of TestCase
2. Override the setUp() method to initialize object(s) under test.
3. Optionally override the tearDown() method to release object(s) under test.
4. Define one or more public testXXX() methods that exercise the object(s) under test and assert expected results.
Like this:
import junit.framework.TestCase;
public class Bag4fruitTest extends TestCase {
private Fruit apple1;
private Fruit apple2;
private Fruit orange;
protected void setUp() {
apple1 = new Fruit("apple", 1.0);
bag = new bag4fruit(); bag.addFruit(apple1); ...
}
protected void tearDown() {
// release objects under test here, if necessary
}
public void testEmpty() {
bag.empty();
assertEquals(0, bag.getFruitCount());
}
}
Second step with JUnit: write Test Suite
Next, you'll write a test suite that includes several test cases. The test suite will allow you to run all of its test cases in one fell swoop. To write a test suite, follow these steps:1. Write a Java class that defines a static suite() factory method that creates a TestSuite containing all the tests.
2. Optionally define a main() method that runs the TestSuite in batch mode.
Like this:
import junit.framework.Test;
import junit.framework.TestSuite;
public class FruitFruitSuite {
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(Bag4fruit.class);
// Add more tests here ...
return suite;
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
}
Third step: running the test
Now that you've written a test suite containing a collection of test cases and other test suites, we can run either the test suite or any of its test cases individually. Running a TestSuite will automatically run all of its subordinate TestCase instances and TestSuite instances. Running a TestCase will automatically invoke all of its public testXXX() methods. JUnit provides both a textual and a graphical user interface. Both user interfaces indicate how many tests were run, any errors or failures, and a simple completion status. The simplicity of the user interfaces is the key to running tests quickly. You should be able to run your tests and know the test status with a glance, much like you do with a compiler. To run our test case using the textual user interface, use:java junit.textui.TestRunner bag4fruitTest
The textual user interface displays "OK" if all the tests passed and failure messages if any of the tests failed. To run the test case using the graphical user interface, use:
java junit.swingui.TestRunner bag4fruitTest
The graphical user interface displays a Swing window with a green progress bar if all the tests passed or a red progress bar if any of the tests failed. The FruitFruitSuite can be run similarly:
java junit.swingui.TestRunner FruitFruiteSuite