ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


Using JUnit With Eclipse IDE

by Alexander Prohorenko and Olexiy Prokhorenko
02/04/2004

This article is going to introduce you to JUnit, a tool for project testing and debugging. After introducing the theory of test-driven development, we'll move on to a step-by-step explanation of how you can create your JUnit tests with the help of the popular Eclipse IDE. We'll show how something as simple as a Hello World program can be exposed to a JUnit test.

Many books have already been written about automated testing, but very few of them pay attention to the question of how to organize such tests. As more tests are written, it becomes harder to know where to put a test or even what to call it. This has become a significant issue with the rise of test-driven development (TDD), which has been popularized by Extreme Programming (XP). You can think of TDD as "development through testing."

The major provisions of TDD are:

Such an approach can be used by any programmer and does not require the use of a specific methodology. But before we get into writing tests, it would be desirable to first look at how to organize the automated tests.

There several different kinds of tests we should consider:

For the rest of this article, when I say "test," I will mean developer's test.

During development, a programmer sometimes asks himself or herself: is there a test for the given behavior of the system and if it exists, where it can be found? A classic example is basic bug fixing, in which the mistake is found, but not by automated tests. The sequence of events that results from this situation might be:

  1. Look for a test for the given functionality (it's probable that the test is already written, but contains a mistake).
  2. If such test is not present, or it does not cover a situation in which there is a mistake, we will need to write a new test that reveals it.
  3. Now we need to be convinced that the new test does not pass.
  4. Fix the bug.
  5. Run the test.
  6. Confirm that it passes.

Certainly, variations of this process are possible, but the idea should be clear: you only correct a mistake when you have a test that reveals the mistake.

Now, let's consider how a developer would solve this situation. To search through existing functionality tests:

We are almost ready to create our test, so now we have to choose a name for our test. You could say, "It's not even a problem: just put the word "Test" before your class name, and that's it!" But not so fast! Let me just show how this approach can run into trouble:

These are just the most common problems; there are many more.

Let me offer one recommendation on naming your tests: the name of a test class should convey that this class is a test class, and indicate what exactly it checks, whether or not it repeats the name of a tested class. That's easy. Don't worry if such a name turns out too long or ugly. It describes itself, and that is the idea.

We will create our first test with the help of the JUnit tool in the Eclipse IDE. I assume that you have already downloaded a recent version of this product, but if not, you can always get it from the official site. We need JUnit, which you can download from its official site, too. Download it and unzip somewhere on your disk, where you are keeping your Java libraries.

Run Eclipse IDE. We will create a new workplace project, so click File -> New -> Project, then choose Java and click Next. Type in a project name -- for example, ProjectWithJUnit. Click Finish. The new project will be generated in your IDE. Let's configure our Eclipse IDE, so it will add the JUnit library to the build path. Click on Project -> Properties, select Java Build Path, Libraries, click Add External JARs and browse to directory where your JUnit is stored. Pick junit.jar and click Open. You will see that JUnit will appear on your screen in the list of libraries. By clicking Okay you will force Eclipse to rebuild all build paths.

We are ready to start developing our "Hello World" example. Let's follow TDD rules and create the test even before we have any kind of code. For the sake of having somewhere to start, we will assume that our future code class will be named HelloWorld and that it will have the method say(), which will return some String value ("Hello World," for example).

To create such a test, right-click on the ProjectWithJUnit title, select New -> Other, expand the "Java" selection, and choose JUnit. On the right column of the dialog, choose Test Case, then click Next. This is illustrated by Figure 1.

Figure 1
Figure 1. Creating a JUnit test in the Eclipse IDE

Type in the name of our yet-to-be written class HelloWorld into the Test class field, and choose a name for our Test case -- for example, TestThatWeGetHelloWorldPrompt (yes, it looks too long, but it clearly indicates what it does.) Click on Finish.

The code for TestThatWeGetHelloWorldPrompt.java is as follows:

import junit.framework.TestCase;

public class TestThatWeGetHelloWorldPrompt
    extends TestCase {
    public TestThatWeGetHelloWorldPrompt(
        String name) {
        super(name);
    }
    public void testSay() {
        HelloWorld hi = new HelloWorld();
        assertEquals("Hello World!", hi.say());
    }
    public static void main(String[] args) {
        junit.textui.TestRunner.run(
            TestThatWeGetHelloWorldPrompt.class);
    }
}

This code is not complex; it's just a bit unusual. However, let's examine it in detail. We extend JUnit's TestCase class, which is defined in JUnit's javadocs as "a fixture to run multiple tests." JUnit also has TestSuite, which is a set of related test cases, but we will not work with in this article.

To create our own simple test case, we need to follow these steps:
  1. Create an instance of junit.framework.TestCase.
  2. Define tests that return void and whose name begins with the string "test" (such as testWasTransactionSuccessful(), testShow(), etc.).

TestThatWeGetHelloWorldPrompt.java meets both of these criteria: it subclasses TestCase and has a method called testSay(). This method uses an assertEquals() call, which compares the value which we expect to receive against the value returned by say().

The main() method is used to run the tests and present their output. JUnit's TestRunner executes our tests, and provides both graphical and textual output. We use the textual version because that's what Eclipse IDE supports and it's absolutely suitable for us. Once executed, the textual version of the test shows the result as text output and Eclipse IDE uses that to create its own graphic presentation.

So, according TDD provisions, once we run our test we should see that it failed. Let's try. Click Run -> Run as -> JUnit Test (remember that TestThatWeGetHelloWorldPrompt.java should be highlighted in Package Explorer). In the left window, instead of Package Explorer, you will see the JUnit window, which shows a red bar, the failed tests, and details of those failures, as seen in Figure 2. If you do not automatically see it, just click on JUnit label (on the bottom left), which is one of the layers of this screen.

Figure 2
Figure 2. Failed test in JUnit

Perfect! It really fails. Now we can create working code in our project: right-click the ProjectWithJUnit title in the left Package Explorer window, then choose New -> Class. Choose a name for the class — we've assumed it to be HelloWorld. Do not check off any of checkboxes on the bottom of the dialog window, just click Finish. Below is the code for HelloWorld.java:

public class HelloWorld {
    public String say() {
        return("Hello World!");
    }
}

It's very simple and merits no commentary. So let's test it and see the results. Run our test the same way as described above, and in the left JUnit window you will see a green bar, as seen in Figure 3. The green bar means that our test was successful.

Figure 3
Figure 3. Successful test in JUnit

Now we want to try to make it fail once again, but for a different reason. This will help show how JUnit test covers and reports different errors. Edit the assertEquals() to change the expected return value from "Hello World!" to, for example, "Hello Me!". When you run this JUnit test again, the bar will be red, and at the bottom of the left JUnit window you will see an explanation of what failed, as illustrated by Figure 4.

Figure 4
Figure 4. ComparisonError running JUnit

In conclusion, I would like to mention a few thoughts about testing as a necessary part of the development process. Testing code was always an integral part of any development. But it has been advanced over the last few years, thanks to powerful methodologies (such as "expectations-based development," etc.), accelerated testing toolkits, and the development of better testing processes. If you have found this article interesting, take some time to study formal testing methodology, and use it in your work.

Alexander Prohorenko is a certified professional, who holds Sun Certified System Administrator and Sun Certified Java Programmer certifications.

Olexiy Prokhorenko is a Sun Certified Enterprise Architect whose areas of interests include Web software architecture and development of software with frequently changing requirements.


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.