Skip to main content

Setting properties for JUnit testing and NetBeans

Posted by fabriziogiudici on January 31, 2007 at 4:48 PM PST

Keeping an old habit since the old times of C/C++ development and Makefile, mostly under Unix, I usually set environment variables to specify some properties that should be available during compiling or testing. But environment variables can create troubles sometimes.

For instance, Mistral automated tests need to deal with a number of images that are used as a test case. Unfortunately, most of these images are quite large (several megabytes) since they are digital photos (the main target of Mistral), often stored in a camera raw format (which Mistral can handle thank to jrawio). In the first distribution of Mistral just a couple of images were included, and this made the source zip 20mb large. Putting more images in the distribution is not a viable option - a best approach is to ask developers to download them optionally (after all many people who download sources could be not interested in running tests) - indeed the new JUnit tests are smart enough to automatically download the required images from the internet the first time they run.But the basic point is that test images are stored outside the project directory structure, and different people would choose a different path on their hard disk. Until yesterday, an environment variable TEST_PHOTOS was required to point to that path in order for the tests to run properly (the value was read by Java code with System.getenv("TEST_PHOTOS")).

While this approach worked in a portable fashion (Mac OS X, Linux, Windows) when tests were run by invoking ant by command line, it never worked when launching JUnit from inside NetBeans on Mac OS X. The problem is that NetBeans on Mac OS X is started by a sh script that doesn't get initialized with my enviroment (among other reasons, also because my favourite shell is tcsh).

Of course there are many ways to fix this if you're skilled with U*ix administration, but on the NetBeans developers' mailing list (a good place for precious hints) I was suggested to use a property file instead: something easier and more portable. After some minutes of work and a pair of good suggestions, I came out with a good solution.

The main problem was to have JUnit be aware of my required properties and pass them to the Java code under testing. I first looked at nbproject/build-impl.xml which is an ant script automatically generated by NetBeans and found the macro definition for invoking JUnit:

    <target name="-init-macrodef-junit">
        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute name="includes" default="**/*Test.java"/>
            <sequential>
                <junit showoutput="true" fork="true" dir="${basedir}" failureproperty="tests.failed" errorproperty="tests.failed">
                    <batchtest todir="${build.test.results.dir}">
                        <fileset dir="${test.src.dir}" includes="@{includes}"/>
                    </batchtest>
                    <classpath>
                        <path path="${run.test.classpath}"/>
                    </classpath>
                    <syspropertyset>
                        <propertyref prefix="test-sys-prop."/>
                        <mapper type="glob" from="test-sys-prop.*" to="*"/>
                    </syspropertyset>
                    <formatter type="brief" usefile="false"/>
                    <formatter type="xml"/>
                    <jvmarg line="${run.jvmargs}"/>
                </junit>
            </sequential>
        </macrodef>
    </target>

I'm not a big expert of ant scripting, but the code looks quite easy to understand. The focal point is the syspropertyset element: it takes all the properties whose name starts with test-sys-prop and makes them available to the tested code, with the prefix stripped; that is test-sys-prop.FOO becomes available as FOO.

So I just had to define this:

test-sys-prop.test.photos.dir=/Users/fritz/Business/Tidalwave/Projects/TestPhotos

in nbproject/private/private.properties (which is a special NetBeans property file which is not committed into the project repository and contains per-user project settings); Java code retrieves the property value with System.getProperty("test.photos.dir").

Neat and simple.


PS You'll see me blogging more about NetBeans in the following weeks - time allowing - because I'm working more and more with it, and also because I'm now member of the NetBeans Dream Team (NBDT for friends). I've just integrated into NetBeans ant scripts a tool for producing reports about test coverage (but there are still a couple of quirks to fix); I'll blog about it as soon as possible.

Technorati tags: , , , .

Related Topics >>