Build tests using Ant

Một phần của tài liệu Manning JUnit recipes practical methods for program (Trang 127 - 130)

3.9 Build tests using Ant

Problem

You need to build your tests in an environment where you cannot use your usual IDE. You can build the tests from the command line, but you would like to auto- mate this task in a portable way.

Background

In recipe 3.8, we describe the conditions under which it may be necessary to build your tests without your trusty IDE. We also describe the most serious limitation in using the Java compiler to build your tests: there is no direct support for building all the tests in your test source tree. If you need to work in this strange environ- ment for a prolonged period of time—that is, you need to build all your tests more than once or twice—you’ll want to automate the build so that you can con- centrate on higher-level thinking, such as solving the problem before you. We like to remind ourselves that the computer is supposed to do work for us and not the other way around. We should not waste our time satisfying some operating system or Java compiler.

Recipe

Ant to the rescue! If you’re unfamiliar with Ant, then run (don’t walk) to http://

ant.apache.org and read about this automated build tool that has become an industry standard among Java programmers. Ant is simple to install and integrates well with JUnit.

Building your tests with Ant is straightforward: use the <javac> task to build your test classes, specifying a source directory, a target directory, and a few ele- ments on the class path, notably JUnit itself. If you already know how to build your tests from the command line, then transcribing that command into an Ant target is easy. Start with the simplest example: the test source, production source, and all the classes are in the same directory on the file system. Just add junit.jar to the build-time class path and everything works. Listing 3.4 shows a simple Ant build- file that builds the tests.

97 Build tests using Ant

<project name="Simplified Project Structure" default="compile">

<property name="junit.home" value="d:/junit3.8.1" />

<target name="compile">

<javac fork="yes" srcdir="." includes="**/*.java">

<classpath>

<pathelement path="${junit.home}/junit.jar" />

</classpath>

</javac>

</target>

</project>

Here we have the simplest Ant buildfile we can think of that includes building JUnit tests. Because the test source code and production source code is all in one place—at the root of the project’s directory structure—it’s enough simply to build every Java class we find. The only item we need in the build-time class path is JUnit itself. It is a best practice in Ant not to hard code the location of tools such as JUnit into your Ant tasks, but rather to factor them out into properties. Although this book is not meant to be a primer on Ant, we have used a property to refer to junit.jar, as we would on a real project.19 This covers the simplest case.

If you follow our recommendations on separating the test source code and test classes from the production code, then your buildfile will look like the one in listing 3.5.

<project name="Simplified Project Structure" default="compileTest">

<property name="junit.home" value="d:/junit3.8.1" />

<target name="compileTest" depends="compileProduction">

<javac fork="yes"

srcdir="source/test" includes="**/*.java"

destdir="classes/test">

<classpath>

<pathelement path="${junit.home}/junit.jar" />

<pathelement path="classes/production" />

</classpath>

</javac>

</target>

Listing 3.4 A minimal Ant buildfile for JUnit tests

19Actually, we would move this property into a properties file because we expect the person using this buildfile to need to change that property to suit her environment. We decided that a separate properties file would be too much of a distraction for this example, so we left the property inside the buildfile.

Listing 3.5 A more useful Ant buildfile for JUnit tests

98 CHAPTER 3

Organizing and building JUnit tests

<target name="compileProduction">

<javac fork="yes"

srcdir="source/production" includes="**/*.java"

destdir="classes/production" />

</target>

</project>

The biggest difference between this buildfile and the one in listing 3.4 is that there are two targets: one to build the production code and one to build the tests.

Because we have placed the tests and production source in different source trees, we need a different target for each source tree: Ant does not support specifying multiple “source tree to destination tree” mappings in a single task.

Next, notice that the compileTest target depends on the compileProduction target. This ensures that the tests are always built with the most up-to-date produc- tion code. Failure to include this dependency can lead to difficult-to-diagnose class incompatibility problems when running your tests: the Java interpreter gen- erates ClassCastException, VerifyError, or one of a host of odd-sounding and confusing errors, when what you really need is the message “Your classes are out of date. Build again.”

Finally notice that we must add classes/production to the build-time class path of the test classes, as the tests depend on classes in the production code but not the other way around. If your production classes need your test classes in the build-time class path, then you have a serious dependency problem: specifically, you have test classes in your production code. If moving the class into the test source tree doesn’t work, then the situation is much worse: your class has some production features and some test-only features. You’ll have to split that class in two and put the corresponding part in the right place for your project to build. Although not ideal, doing so ensures that test-only features do not gum up the works of your production-quality system. The increased discipline is worth it.

Discussion

Using Ant to build your project, even if you always have access to your favorite IDE, can help point out dependency problems in your code. As you saw in the previous example, it is easy to create a class that is part production and part test utility but not realize that the class lives this double life, because the IDE manages class paths and the like, freeing you from having to figure it out for yourself. We all want our IDE to simplify our lives (at least as programmers), but you should be concerned when a feature of your IDE allows you to be too lazy. The IDE is a tool,

99 Build tests using Eclipse

and not a crutch; you should be able to build your system without the IDE, just in case you ever need to. This is the reason we recommend managing your build with Ant.

Related

■ 3.8—Build tests from the command line

Một phần của tài liệu Manning JUnit recipes practical methods for program (Trang 127 - 130)

Tải bản đầy đủ (PDF)

(753 trang)