This
activity is a high-level introduction to Test Driven Design and the use of JUnit. Consult the on-line references listed on the course
site for more in-depth coverage of these topics. The following example was
taken from Test-Driven Development, A Practical Guide by David Astels.
This system will make it easy for a user to keep track of
movies they want to see. Additionally it will provide support for ratings,
recommendations, etc. to help in deciding what to watch.
Sample
User Stories:
( and so on….)
For the purpose of our exercise, lets
start with the implementation of the first user story – “Movie List”. The first
step is to break the story into tasks:
·
Task
1-1 Make a container for movies with a way to add to it. Doesn’t have to be
ordered or sorted.
·
Task
1-2 Make a GUI that shows a list of movies. List order represents the order of
the underlying collection. List should scroll as required.
·
Task
1-3 Provide a GUI interface for adding movies to the list.
Note that the tasks break the user story down into a set of
activities starting with the underlying data structure and associated behavior
and then adds a user interface.
Let’s implement Task 1-1. The first step using TDD is to
begin with a single test, implement (ONLY) the code needed to pass the test and
move on The rule is to test the simple stuff first and implement only what you
need to satisfy the test condition – and no more. Here are our tests for Task
1-1.
·
Test
1 – An empty list of movies should have a size of zero.
·
Test
2 – Adding a movie to an empty list should result in a list with a size of one.
·
Test
3 – Adding two movies to an empty list should result in a list with a size of
two.
·
Test
4 – If we add a movie to a list, we should be able to ask if it’s there.
Conversely, we should receive a negative response when we ask about a movie we
haven’t added.
We start our testing, using the
Eclipse support for JUnit:
public void testEmptyListSize(){
MovieList emptyList
= new MovieList();
assertEquals( "Size of empty list should be
0.", 0, emptyList.size());
}
public void testSizeAfterAddingOne(){
MovieList oneItemList
= new MovieList();
oneItemList.add( starWars);
assertEquals( "Size of one item list should
be 1.", 1, oneItemList.size());
}
Movie starWars
= new Movie();
public void add( Movie movieToAdd)
{
}
private int count
= 0
public void add( Movie movieToAdd)
{
count = 1;
}
Also change:
public int
size() {
return count;
}
It looks fishy to fix the count at one for the add method,
but we only need to satisfy the current test condition – and nothing more!
Don’t look ahead, that’s how defects creep in.
Run the tests – should be all green. Note that the first
test still passes, which indicates that we did not break anything that was
already working.
Test 3 – Adding two movies to an empty list should
result in a list with a size of two.
public void testSizeAfterAdddingTwo(){
Movie starWars
= new Movie();
Movie starTrek
= new Movie();
MovieList twoItemList = new MovieList();
twoItemList.add(starWars);
twoItemList.add(starTrek);
assertEquals("Size
of a two item list should be 2.", 2, twoItemList.size());
}
Of course this fails. Now is the time to
modify the add() method in MovieList:
public void add( Movie movieToAdd){
count ++;
}
2.
Run the tests again – all green, including previous two
tests.
3.
Before moving on, lets do some
“refactoring” – making the code easier to read and maintain. The variable name count is a little weak; lets make it more descriptive by renaming it numberOfMovies.
4.
Eclispe has a rename
feature that will go through and change all occurrences of a variable, class or
method without you having to manually hunt for all the changes.
a.
Highlight the variable count and right select Refactor->Rename.
b.
You can put in the new name and optionally see a preview of
what will be changed.
5.
After making the change, rerun the test to see the green
bar. Rerun the tests after ANY change you make
to your code – it’s easy once the test case are in place, and you’ll gain
confidence that your changes haven’t broken anything.
Test 4 – If we add a movie to a list, we should be able
to ask if it’s there. Conversely, we should receive a negative response when we
ask about a movie we haven’t added.
1.
Try this one on your own. You will need to use the JUnit methods assertTrue() and assertFalse() to test the
presence of movies you add.
2.
Hint: You will also need to think about a Collection of
some sort to hold movies (we can’t postpone doing real work forever!)..
To explore JUnit
a bit further, download the final solution is in MovieManager.zip, unpack this, and import the code into
Eclipse.
Note this version uses the setUp() method in MovieListTest which is executed
prior to the start of each individual test case. This is useful for
centralizing repeated work that needs to be done prior to each test execution.
Note the use of instance variables in MovieListTest to support the setUp() method.
JUnit also supports a tearDown() method that may be run at the
conclusion of each test to cleanup.