Unit Testing and JUnit
Do this exercise by yourself,
but ask questions of other students, your instructor, and the student assistants.
Goals
The goals of this exercise are to:
- Learn what unit testing is.
- Learn why unit testing is a good thing.
- Learn how to write unit tests.
- Begin to use JUnit to automate the unit testing process.
Background
Unit testing is simply testing each class or method of a class in
isolation before combining it with the rest of a program. We will apply it to a toy example today, but we
will really see the benefits of unit testing when we have large projects that are
maintained over a long period of time. Whenever changes are made to the code, and
especially before a release of a new version, running the Unit tests increases our confidence that our
fixes and enhancements have not broken something that worked before.
Today, we are building a habit of mind
and thus we focus primarily on process, not code.
Instructions
- You will download a class whose purpose is to convert a String to Pig Latin. Pig Latin is translated
into "igPay atinLay".
Words starting with a vowel get "way" appended to them, as in "excellentway". If
these examples are not enough to make you understand how it works, ask someone!
- Think of some words that you would want to test in order to catch errors (see
the tips below). Discuss these with another
student or your instructor.
- Create a PigLatiner project and copy the PigLatiner.java file
into your project folder. Refresh the project if necessary.
- Write unit tests with JUnit. JUnit is built into Eclipse.
- First, note that you will not need to write main( ). Unit tests don't need main(),
because they are run under the JUnit test engine, which has its own main( ).
- Right-click the source file for which you want to write tests (in this case
PigLatiner.java). Then choose New →
JUnit Test Case. If it asks about adding JUnit to the path, do so.
Then
click the Next button,
select PigLatin's transform() method (the one you want to test), and
click Finish.
- Now you have the stubs of a method for a new PigLatinerTest class.
Take a look at its code.
- You can run the tests by right-clicking and choosing
Run as → JUnit Test.
- It should bring up a screen with a red bar, showing that it failed. (Why?)
- Fill in the body of your method as follows. The static assertEquals() method from the Assert class
(the TestCase class extends Assert) takes two arguments that you want to check for equality.
What should you pass to it? (ask if you need help).
- Answer to previous question: assertEquals("edfray",
PigLatiner.transform("fred")). The first argument is the expected result;
the second uses the method under test to try to obtain that result [Hint:
It's not an error to swap the order of the arguments, but JUnit's output
only makes sense if you give them in this order.]
- Note that the junit.framework.Assert class contains other methods that you may find
useful in later projects, such as assertFalse, assertTrue, assertNotNull, assertNull,
assertSame, assertNotSame,
- Run your test to see that it is doing what it's supposed to.
Then copy and paste to create as many new unit tests as you need.
- Try to use the output in the Failure Trace (bottom left-hand window) to determine the errors in the code.
- Keep fixing code and re-running tests until you get the code to pass all the tests.
The Goal:
- Ask someone near you if they have interesting tests that you should try (and see the tips below).
Tips on writing unit tests
- Test as many types of cases you can think of.
- Test boundary cases (such as when a String only contains a single character,
is the empty String, or is null)
- Test cases your program should reject or give special treatment (division by zero, empty strings, null pointers,
past the end of an array)
- Once your code is written, your tests should exercise all branches in the
code tested.
- Use cases for which you can compute the desired result by hand, or via a simple inverse method
(for example, to test a square root method, you can easily square the answer and compare it to the original).
Note, Weiss's Data Structures textbook doesn't focus on testing. These ideas were
mostly taken from Cay Horstmann’s Big Java and various other sources.
There is much more information in the JUnit FAQ
http://junit.sourceforge.net/doc/faq/faq.htm