Unit Testing and JUnit

Work on this exercise by yourself, but ask questions of your instructor, student assistants and classmates as desired.

Goals

The goals of this exercise are to:

The Exercise

Background

Unit testing is simply testing each class or method of a class in isolation before combining it with the rest of a project. We will apply it to toy examples today, but recognize that we really see the benefits of unit testing when we have large projects that are maintained over a long period of time. Today, we are building a habit of mind and focus primarily on process, not code.

Instructions

  1. You will download some code that converts a String to Pig Latin (possibly with errors!). Pig Latin is translated "igPay atinLay". Words starting with a vowel get "way" appended to them, as in "excellentway".
  2. Brainstorm some words that you would want to test to catch errors (see the tips below). Discuss these with your instructor.
  3. Create a PigLatiner project and copy the PigLatiner.java file from here into your project.
  4. Write unit tests with JUnit. JUnit is built into Eclipse.
    1. First, note that you do not need to write main(). Unit tests don't need main().
    2. Select the class for which you want to write tests. Then choose New → JUnit Test Case. IN the next window, click on new JUnit4 test. Then select Next, select PigLatin's transform() method (the one you want to test), and select Finish. If it asks about adding JUnit to the path, do so.
    3. Now you have the stubs of a PigLatinTest class. You can run the test class by right-clicking, and choosing Run as → JUnit Test.
    4. It should bring up a screen with a red bar, showing that it failed. (Why?)
    5. Fill in the body of your testTransform method as follows. The static assertEquals() method from the Assert class takes two arguments that you want to check for equality. What should you pass to it? (ask if you need help)
    6. A potential 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.)
    7. Run it to ensure the test is doing what it's supposed to.
    8. Try to use the output in the Failure Trace (bottom left-hand window) to determine the error in the code.
    9. Keep writing and re-running new tests until you get the code to pass all the tests. (Hint: there's at least one other error in the program: a good set of tests will expose any error(s).

Tips on writing unit tests

  1. Test as many types of cases you can think of.
  2. Test boundary cases (such as when a string only contains a single character)
  3. Test cases your program should reject or give special treatment (division by zero, empty strings, null pointers)
  4. Once your code is written, your tests should exercise all branches in the code tested.
  5. 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).

Why are we learning unit testing?

Because following good habits (processes) are the difference between a programmer and a software developer!