CodeGear JBuilder 2007 Testing Using JUnit: A Simple Example

By: Doug Thiele

Abstract: JUnit testing article with simple example

Software Required:
JBuilder 2007 Professional R2 or JBuilder 2007 Enterprise R2 http://www.codegear.com/jbuilder

Before we step into the project, it probably bears discussing why we would want to use an automated testing tool like JUnit. If you’re reading this article, you may already be a proponent of unit testing, but let’s make sure everyone reading this article has the same foundation before we begin.

In a relatively unstructured development process, at a very high level, we get requirements from the users, design a piece of code (maybe), sit down and write the code, do some basic testing to ensure that the code works correctly, and then deploy the code to production. This approach has a lot of problems, such as:

  • The person writing the code usually tests only successful values
  • There probably is no structured testing approach, which means that tests are relatively random, and are not recorded (i.e. if you find a value that causes a problem and fix it during one development cycle, do you remember to test with that value in successive development cycles to keep this problem from reappearing?).
  • The testing is probably done manually, which puts users in the position of performing repetitive tasks on code. As a sweeping generalization, that provides an uneven testing experience, as the person’s fatigue may cause concentration lapses, or they decide to skip tests that they “know” will pass.

Although the problems above can occur in a work situation where there isn’t a formal development process in place, it can also occur in larger organizations with formal software development processes as well. Computers were meant to perform the dull, repetitive chores that humans, by nature, would perform less efficiently. By allowing the computer to focus on core, repetitive tests, it frees the developer to perform special testing that a computer couldn’t perform. It also gives the developer and customer more confidence in the code that was written, since there is tangible evidence that the code works as expected.

Unit testing can help provide an automated series of tests that exercise base functionality of your classes so that you can focus on higher-level activities, like tests that don’t pass, or test scenarios that are more aptly performed by humans. You can run the tests after every build and use the reports to provide hard data on software build quality.

Let’s also talk about what unit testing is not. Unit testing is not a replacement for manual testing by users. Unit testing is also not easy. Even if you use JBuilder 2007’s support for JUnit, where it actually writes some of the code for the test case for you, you still have to modify the code to correctly test your application.

Java has had a unit testing framework available to it for some time. It’s called JUnit (www.junit.org), and it’s fantastic. It’s currently on release 4 (4.3.1 as of this writing, to be exact). The major change in Version 4 is that JUnit now uses annotations (text prefixed by a @ symbol, which gives it special meaning to the compiler). We aren’t going to talk much about previous versions of JUnit, since JBuilder 2007 ships with JUnit 4.x included, but if you are curious about the differences, then Antonio Goncalves has a fantastic article comparing the previous release to the 4.x release (see the References section for the article URL).

In this article, we’re going to build a simple class in JBuilder 2007 and create some unit tests to give you an opportunity to see how JBuilder helps integrate JUnit and simplify the creation of test classes.

As is always the first step in working with JBuilder, I created a new project to hold my classes. In this case, I just created a simple Java Project by choosing “New” >> “Project” from the “File” menu (Figure 1).

Figure 1: The Project Creation Menu

Hide image
Click to see full-sized image

This displays the “New Java Project” Dialog Box (Figure 2). I’ve updated the default Java runtime to point to a Java 5 installation I downloaded separately. I like to keep a Java 5 and Java 6 JDK and Java runtime on my machine so that I can switch back and forth if necessary. Enter a project name (as you can see, I chose “TestProject”).

Figure 2: New Java Project Dialog Box

Hide image
Click to see full-sized image

Click “Finish”, since the rest of the wizard steps aren’t necessary.

The “Java” perspective is opened. Perspectives in JBuilder 2007 are a set of windows and associated shortcut menu choices that are tailored to your current needs. For example, if you were debugging, the IDE would shift to the “Debug” perspective with windows for call stacks, breakpoints, and the values of current variables. The “Java” perspective, by contrast, shows you things like the outline of the current class, the project’s file hierarchy, tasks and problems.

Now that we’ve got a project, we need to add a Java class for our simple calculator class. To do so, click on the “File” menu, and choose the “New” >> “Class” menu item (see Figure 3).

Figure 3: Add A New Class Menu Hide image
Click to see full-sized image

This will show the “New Java Class” Dialog box (Figure 4). It’s important to note that you should choose your package name here, although you can change this later, if necessary. I also like the “Generate Comments” option, which puts in Javadoc comments for each method to get you started.

Figure 4: New Java Class Dialog Box

Hide image
Click to see full-sized image

Click “Finish”

In the code listing for this article, I’ve included the class definition for Calculator.java, which is a simple calculator class. You can copy and paste the code from this article’s code listing right into the IDE if necessary. Once you’ve created the methods for our Calculator class, you can right click on one of the method names and choose “Generate Tests” from the shortcut menu (Figure 5).

Figure 5: Generate Test Menu

Hide image
Click to see full-sized image

JBuilder then displays the “JUnit Test Case” Wizard Dialog Box (Figures 6 and 7).

Figure 6: JUnit Test Case Wizard – Page 1

Hide image
Click to see full-sized image

There are a number of things to note here:

  1. Choose the “New JUnit 4 test” radio button in order to create the tests using the latest version of JUnit which includes annotations
  2. Choose the name of the class to be tested (in this case, the Calculator class in the “test” package).
  3. setUp and tearDown are special methods that are provided in case the tests need pre-work before beginning, or clean-up after the tests are finished. The classic example is one where you need to create a connection to a database, for which you’d use the setUp method. Then in the tearDown method, you’d close the connection. It’s a place for shared initialization and destruction.
  4. Make sure to click on the “Click here” link to add JUnit 4 to the build path. This is a big one. If you forget to do this, then your JUnit code that gets generated has a whole bunch of errors because the JUnit JAR file hasn’t been imported. While I know that you could find it and add it as a library, it’s just a whole lot easier to let the IDE do this for you. Incidentally, the JUnit JAR is kept in {JBuilder Home}\plugins\org.junit4_4.1.0.1, so if your JBuilder 2007 home directory is like mine, then you could find the file in c:\JBuilder2007R2\plugins\org.junit4_4.1.0.1. Again, just make sure to click the “Click here” link and avoid the hassle.

Then click the “Next” button.

Figure 7: JUnit Test Case Wizard – Part II

Hide image
Click to see full-sized image

This is where you get to choose for which methods you’d like to generate test stubs. I chose all of the Calculator class’s methods, and ignored the default constructor and inherited methods (for obvious reasons). Click the “Finish” button to generate the test class.

The thing to note in the source code that is generated is that each test method that is generated is marked with a @Test annotation. This lets the compiler know that the method is a test method.

I wish that the test code would already be complete and wouldn’t need any changes, but that’s simply not the case. For each method, we have to go through and create the code that we need in order to test the method. As with the previous class, the code listing below contains the full (if not very complex) test class.

My one piece of advice here is that you should take a lot of care in coding your tests, at least as much as for the code you wrote that is being tested. I’ve found that unit testing sounds easy, but it’s got a lot of subtle complexity to it. On more than one occasion, I’ve looked at tests that I’ve written and discovered that it wasn’t testing what I thought it was, and I’ve had to re-write the tests. Writing good tests is an art, and practice makes perfect.

Once the test class is complete, it’s time to run the tests to see some results. Click on the “Run” menu item, and choose “Run As” >> “JUnit Test” from the shortcut menu (Figure 8).

Figure 8: Run As JUnit Test Menu

Hide image
Click to see full-sized image

As you can see from the output in Figure 9, the results are displayed in a JUnit test window that appears in the IDE. I won’t belabor the obvious here, but you can imagine a test suite of these tests that can be built up to help you create better quality software. Another typical use for unit testing is that each time a bug is found, one or more unit tests are created to help test whether the bug was fixed. This helps make sure the bug is fixed, as well as stays fixed in future releases of the software.

Figure 9: JUnit Test Results Window

Hide image
Click to see full-sized image

In this article, we’ve looked at how JBuilder2007 integrates JUnit 4 unit testing into the IDE and makes it easy to test your code. JBuilder automates a lot of the manual work associated with unit testing, and integrating JUnit gives developers another tool to help improve the quality of the software that they write.

Code Listing:

// Calculator.java

package test;

public class Calculator {
    public Calculator() {
         // default constructor
    }
    
    /**
     * Please realize that this isn't a production quality class.
     * It doesn't have error handling or robust code to handle overflow checks.
     * This example is meant to show how to set up unit testing, rather than 
     * how to set up a class.
     */
    public int add(int x, int y) {
         return x+y;
    }
    
    public int subtract(int x, int y) {
         return x-y;
    }
    
    public int multiply(int x, int y) {
         return x*y;
    }
    
    public int divide(int x, int y) {
         return x/y;
    }

}

//CalculatorTest.java
package test;
import static org.junit.Assert.*;
import org.junit.Test;

public class CalculatorTest {
    private Calculator calc = new Calculator();
    private int x = 10;
    private int y = 5;

    @Test
    public void testAdd() {
         assertSame(15, calc.add(this.x, this.y));
    }
    @Test
    public void testSubtract() {
         assertSame(5, calc.subtract(this.x, this.y));
    }
    @Test
    public void testMultiply() {
         assertSame(50, calc.multiply(this.x, this.y));
    }
    @Test
    public void testDivide() {
assertSame(2, calc.divide(this.x, this.y));
}
}

References:

  1. Get Acquainted With the New Advanced Features of JUnit 4, Goncalves, Antonio, http://www.devx.com/Java/Article/31983, July 24, 2006


Server Response from: ETNASC03