Saturday, March 10, 2012

Running TestNG & JUnit 4 tests in the same Maven project without duplication

Update on 16 Mar '12:  Cedric has informed me that the TestNG master branch now supports JUnit 4.  Try it out!

As of this writing, TestNG still doesn't support JUnit4.  Problem is, Spring Roo uses JUnit 4 and I happen to be developing a liking for TestNG lately.

Many folks out there have suggested defining two Surefire executions, one for JUnit 4 & one for TestNG.  I did that, but every time I do, it looks like the default configuration of Surefire runs first, then whatever other test executions that you've defined next, often resulting in duplicate tests being run.

I noticed that the default Surefire execution id is default-test.  By simply defining an execution with id default-test and setting skipTests to true, I was able to avoid the unwanted default run.  You could either redefine the default-test execution or defeat it and define whatever other test executions you want to.

Here's the POM snippet that defeats the default-test execution and defines one for JUnit 4 & TestNG:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.11</version>
        <executions>
            <execution>
                <id>default-test</id>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
                <goals>
                    <goal>test</goal>
                </goals>
            </execution>
            <execution>
                <id>junit-tests</id>
                <goals>
                    <goal>test</goal>
                </goals>
                <configuration>
                    <testNGArtifactName>none:none</testNGArtifactName>
                    ...
                </configuration>
            </execution>
            <execution>
                <id>testng-tests</id>
                <goals>
                    <goal>test</goal>
                </goals>
                <configuration>
                    <junitArtifactName>none:none</junitArtifactName>
                    ...
                </configuration>
            </execution>
        </executions>
    </plugin>

I hope this helps you some time.

2 comments:

Cedric said...

Actually, TestNG supports JUnit 4 as of last week :-)

Check out the version in master if you want to try it, feel free to email me if you encounter issues.

Matthew Adams said...

Sweet, @Cedric! I'll have a look when I get a chance.