ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

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:

  • Before writing any code fragment, an automated test must be written to check the functioning of this code. Since the code does not exist yet, it initially fails the test.
  • After the test begins to pass, duplicate code must be removed.

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:

  • Unit tests: These serve to check the correctness of several modules (i.e., classes). If the object needs access to some external data source, like a database, these are simulated with mock objects, but only in cases in which re-creating the actual data source would be difficult in a test environment.

  • Customer's tests: These are functional, system, and acceptance tests. All of them check the behavior of the system as a whole. In the XP methodology, these tests are written by the customer, given the program skeleton.

  • Integration tests: These are like a cross between the customer tests and unit tests. Integration tests help test the interaction of several levels of the application. Typically, mock objects are not used in integration testing, which may increase testing time. Also, integration tests often demand the presence of a special test environment, such as a database seeded with test data. Integration tests may also use special external libraries. An example of such a library for the integration of J2EE applications is Cactus. Explanation of these tests is going beyond of this article, and requires much detailed theory information, so you just take it as information that such kind of tests exists.

  • Developer's tests: These are just tests that developers use to verify whole code, new pieces of code, and/or new functions. For each developer, it is important to generate new tests to check code whenever possible. Organizing these tests can be as important as organizing the code base itself.

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 can take advantage of certain integrated development environments (IDEs) that allow us to search for places in which corrected classes and methods are used.
  • Create a known error situation and inspect what fragment of code is in error.
  • Last but not least, write the test and place it in one of the existing test classes. If you make a mistake arranging your test and duplicate test code, hopefully you or one of your colleagues will eventually notice the duplication and correct it.

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:

  • When using TDD, the class or method to be tested may not exist yet.
  • It's also possible that one test can cover several methods, or even several classes.

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.

Pages: 1, 2

Next Pagearrow