Skip Navigation

Unit Testing with Maven

Chapter 7

7.1 Introduction

Maven can run Unit Tests, this chapter shows you how.

7.2. Running JUnit Tests

7.2.1. Task

You need to run all JUnit tests in a given project.

7.2.2. Action

To execute all of the unit tests in a project, include JUnit as a test scoped dependency in your project's pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mcookbook</groupId>
<artifactId>junit-tests</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>junit-tests</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.5</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

Your project should then store unit classes in the default location of ${basedir}/src/test/java. The Maven Surefire plugin will scan these directory for JUnit tests. In this example, a component named SeriousComponent has a corresponding JUnit test named SeriousComponentTest.

web unit directory structure

Figure 7.1. Project Structure for Unit Tests

In this example, the simple component being tested is named SeriousComponent. SeriousComponent contains a single static method to be tested.

Example 7.1. SeriousComponent class

package org.sonatype.mcookbook;

public class SeriousComponent {

/**
* This function tests the seriousness of a String.
* Returns false if the string contains the word
* "FUNNY", returns true otherwise.
*/
public static boolean testSeriousness( String text ) {
return !text.toUpperCase().contains( "FUNNY" );
}
}

This class is tested by a simple JUnit test - SeriousComponentTest shown in the following exmple:

Example 7.2. JUnit test for SeriousComponent

package org.sonatype.mcookbook;

import junit.framework.TestCase;

public class SeriousComponentTest extends TestCase {

public SeriousComponentTest(String name) {
super( name );
}

public void testSeriousness() throws Exception {
assertTrue( SeriousComponent.testSeriousness( "SAD" ) );
assertTrue( SeriousComponent.testSeriousness( "SERIOUS" ) );
assertTrue( SeriousComponent.testSeriousness( "CRAZY" ) );
assertTrue( !SeriousComponent.testSeriousness( "FUNNY" ) );
}
}

To execute your unit test, you don't need to do anything. Maven's default settings are to scan ${basedir}/src/test/java for unit tests matching the pattern *Test.java. To run your unit test specify the test phase of the default Maven lifecycle and run mvn test.

$ mvn test
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building junit-tests
[INFO] task-segment: [test]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources {execution: default-resources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Compiling 1 source file to /Users/Tim/Library/Code/sonatype/ maven-cookbook/mcookbook-examples/unit/junit-tests/target/classes
[INFO] [resources:testResources {execution: default-testResources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Compiling 1 source file to /Users/Tim/Library/Code/sonatype/ maven-cookbook/mcookbook-examples/unit/junit-tests/target/test-classes
[INFO] [surefire:test {execution: default-test}]
[INFO] Surefire report directory: /Users/Tim/Library/Code/sonatype/ maven-cookbook/mcookbook-examples/unit/junit-tests/target/surefire-reports

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.sonatype.mcookbook.SeriousComponentTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.065 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5 seconds
[INFO] Finished at: Wed Nov 25 14:42:39 CST 2009
[INFO] Final Memory: 17M/80M
[INFO] ------------------------------------------------------------------------
7.2.3. Detail

The test results will be made available in ${basedir}/target/surefire-reports as both an XML file and a text file.

unit junit directory structure results

Figure 7.2. Project Structure for JUnit Test Results

The TEST-org.sonatype.mcookbook.SeriousComponentTest.xml contains an XML document describing the environment and state of the JVM in addition to data about the test cases which have been executed, and the org.sonatype.mcookbook.SeriousComponentTest.txt file a summary of a successful test or output that contains stack traces generated by a test failure.

If your unit test passes, the org.sonatypemcookbook.SeriousComponentTest.txt will contain the following output:

$ cd target/surefire-reports/ $ more org.sonatype.mcookbook.SeriousComponentTest.txt
-------------------------------------------------------------------------------
Test set: org.sonatype.mcookbook.SeriousComponentTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.065 sec

If the unit test fails the same file will contain a stack trace that points to a failed assertion on a specific line of the unit test as shown below:

-------------------------------------------------------------------------------
Test set: org.sonatype.mcookbook.SeriousComponentTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.062 sec
<<<FAILURE!
testSeriousness(org.sonatype.mcookbook.SeriousComponentTest) Time elapsed: 0.017 sec
<<< FAILURE!
junit.framework.AssertionFailedError: null
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.assertTrue(Assert.java:20)
at junit.framework.Assert.assertTrue(Assert.java:27)
at org.sonatype.mcookbook.SeriousComponentTest.testSeriousness(
SeriousComponentTest.java:15)
....

7.3. Running TestNG Tests

7.3.1. Task

You need to run all TestNG tests in a given project.

7.3.2. Action

To use TestNG, you will need to add TestNG as a dependency in your project's POM. Since the TestNG unit test shown in this section uses Java 5 annotation, you will also need to configure the Maven Compiler plugin to target Java 5. The following POM shows the minimum required configuration for running TestNG tests with Java 5 annotations.

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mcookbook</groupId>
<artifactId>testng-tests</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>testng-tests</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.10</version>
<classifier>jdk15</classifier>
<scope>test</scope>
</dependency>
</dependencies>
</project>

You would then put your TestNG unit test classses in the ${basedir}/src/test/java directory. The following TestNG test uses Java 5 annotations to mark a class and a method as a TestNG test. The following TestNG unit test duplicates the JUnit test shown in Section 7.2, “Running JUnit Tests”, and it tests the SeriousComponent class.

Example 7.3. TestNG Test for the SeriousComponent

package org.sonatype.mcookbook;

import org.testng.annotations.Test;

@Test
public class SeriousComponentTest {

@Test
public void testSeriousness() throws Exception {
assert SeriousComponent.testSeriousness("SAD");
assert SeriousComponent.testSeriousness("SERIOUS");
assert SeriousComponent.testSeriousness("CRAZY");
assert !SeriousComponent.testSeriousness("FUNNY");
}
}

There is no other configuration necessary to have Maven execute any TestNG tests it locates under ${basedir}/src/test/java which match the pattern *Test.java. Running mvn test will execute your TestNG unit tests.

$ mvn test
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building testng-tests
[INFO] task-segment: [test]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources {execution: default-resources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Compiling 1 source file to /Users/Tim/Library/Code/sonatype/ maven-cookbook/mcookbook-examples/unit/testng-tests/target/classes
[INFO] [resources:testResources {execution: default-testResources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Compiling 1 source file to /Users/Tim/Library/Code/sonatype/ maven-cookbook/mcookbook-examples/unit/testng-tests/target/test-classes
[INFO] [surefire:test {execution: default-test}]
[INFO] Surefire report directory: /Users/Tim/Library/Code/sonatype/ maven-cookbook/mcookbook-examples/unit/testng-tests/target/surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running TestSuite
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.292 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Thu Nov 26 08:24:02 CST 2009
[INFO] Final Memory: 17M/80M
[INFO] ------------------------------------------------------------------------
7.3.3. Detail

Once the TestNG unit tests have been executed, you will have a TestNG HTML report under ${basedir}/target/surfire-reports/index.html. To view a report which displays statistics about which tests failed and which tests passed, load this HTML page in a web browser.

unit testing directory structure results

Figure 7.3. Project Structure for TestNG Test Results

7.4. Running Specific TestNG Test Groups

7.4.1 Task

You want to configure the Maven Surefire plugin to run specific tests that are defined in a TestNG Test Suite XML descriptor.

7.4.2 Action

Consider a TestNG test class which contains five methods with the @Test annotation. Each method also configures the groups parameter. Four methods are in the "unit" group and one method is in the "integration" group. This might be a common situation for a project that contains different kinds of tests that are to be run during different times of the software development lifecycle. Very often, there is a set of tests that should be run every time a programmer makes a change to source code. There may also be a certain kind of test that can only be executed on a specific integration and testing machine, and there can be other tests which require too much time and resources to be associated with a developer's daily development cycle.

Here is the SeriousComponentTest with five annotated test methods:

package org.sonatype.mcookbook;

import org.testng.annotations.Test;

public class SeriousComponentTest {

@Test(groups={"unit"})
public void testSad() throws Exception {
assert SeriousComponent.testSeriousness("SAD");
}

@Test(groups={"unit"})
public void testSerious() throws Exception {
assert SeriousComponent.testSeriousness("SERIOUS");
}

@Test(groups={"unit"})
public void testCrazy() throws Exception {
assert SeriousComponent.testSeriousness("CRAZY");
}

@Test(groups={"unit"})
public void testFunny() throws Exception {
assert !SeriousComponent.testSeriousness("FUNNY");
}

@Test(groups={"integration"})
public void testLargeFile() throws Exception {
String text = "TEST";
// Imagine that this method contained some serious
// code that loaded a 100k line text file and
// tested each line.
assert SeriousComponent.testSeriousness(text);
}
}

The first four methods are executed quickly as unit tests, but the last method requires more time to execute, and if going to be run periodically by a continuous integration server like Hudson. To make the development cycle more efficient for your developers, you would add the following Maven Surefire plugin configuration to your project's POM. Specifying the groups parameter allows you to select one or more, comma-separate group names which will be executed by TestNG.

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mcookbook</groupId>
<artifactId>testng-groups<artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>testng-groups</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<groups>unit</groups>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.10</version>
<classifier>jdk15</classifier>
<scope>test</scope>
</dependency>
</dependencies>
</project>

When you execute mvn test, you will see that the Maven Surefire plugin will only execute four of the five tests in SeriousComponentTest.

7.4.3. Detail

If you wanted to run all tests in the SeriousComponentTest, you could configure your POM to have the following Maven Surefire configuration:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<groups>unit, integration</groups>
</configuration>
</plugin>

Alternatively, you could just define a dependency on the "unit" group withint the SeriousComponentTest class on the testLargeFile() method. Here's the annotation syntax you would use to do this:

@Test(groups={"integration"}, dependsOnGroups={"unit"})
public void testLargeFile() throws Exception {
String text = "TEST";
// Imagine that this method contained some serious
// code that loaded a 100k line text file and
// tested each line.
assert SeriousComponent.testSeriousness(text);
}

Then, in your project's POM, you would simply configure TestNG to run the "integration" group. TestNG would take note of the dependency defined in the test class and execute the "unit" group before the "integration" group.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<groups>integration</groups>
</configuration>
</plugin>

TestNG supports a very rich set of configuration possibilities for defining groups. You can have groups which depend on other groups, groups can be defined in Test Suite XML files, and you can match groups based on regular expressions to allow for platform specific customizations. Getting into the details of TestNG groups is well beyond the scope of this book, if you would like more information about TestNG, please see the TestNG project documentation here: https://testng.org/.

7.5. Configuring TestNG Tests

7.5.1 Task

You need to pass configuration parameters to TestNG unit tests.

7.5.2 Action

Consider the following TestNG unit test which declares the parameter "databaseHostname" using the @Parameters annotation.

package org.sonatype.mcookbook;

import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

@Test
public class SeriousComponentTest {

@Parameters({"databaseHostname"})
@Test
public void testSeriousness(String databaseHostname) throws Exception {
assert SeriousComponent.testSeriousness("SAD");
assert SeriousComponent.testSeriousness("SERIOUS");
assert SeriousComponent.testSeriousness("CRAZY");
assert !SeriousComponent.testSeriousness("FUNNY");
System.out.println( "Database Hostname: " + databaseHostname );
}
}

This "databaseHostname" parameter can be configured by using the systemProperties configuration parameter of the Maven Surefire plugin. The following POM passes in a value of "testDb01" for the "databaseHostname" test parameter.

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mcookbook</groupId>
<artifactId>testng-config</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>testng-config</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemProperties>
<property>
<name>databaseHostname</name>
<value>testDb01</value>
</property>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.10</version>
<classifier>jdk15</classifier>
<scope>test</scope>
</dependency>
</dependencies>
</project>

Running the test phase will execute the unit test passing the value from the POM to the unit test as a system property.

$ mvn test
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building testng-config
[INFO] task-segment: [test]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources {execution: default-resources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources {execution: default-testResources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Compiling 1 source file to /Users/Tim/Library/Code/sonatype/ maven-cookbook/mcookbook-examples/unit/testng-config/target/test-classes
[INFO] [surefire:test {execution: default-test}]
[INFO] Surefire report directory: /Users/Tim/Library/Code/sonatype/ maven-cookbook/mcookbook-examples/unit/testng-config/target/surefire-reports

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running TestSuite
Database Hostname: testDb01
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.358 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Thu Nov 26 13:32:44 CST 2009
[INFO] Final Memory: 17M/80M
[INFO] ------------------------------------------------------------------------
7.5.3. Detail

For more information about TestNG parameters, see the TestNG project documentation here: https://testng.org/.

7.6. Running TestNG Tests in Parallel

7.6.1. Task

You would like to run your unit tests in parallel to speed up your builds.

7.6.2. Action

To illustrate executing tests in parallel, we can create a component to be tests that sleeps for 5 seconds. The following listing is the SeriousComponent.java class which would be stored in ${basedir}/src/main/java under the org.sonatype.mcookbook package:

package org.sonatype.mcookbook;

public class SeriousComponent {

/**
* This function tests the seriousness of a String.
* Returns false if the string contains the word
* "FUNNY", returns truje otherwise.
*/
public static boolean testSeriousness( String text ) {
try {
Thread.sleep( 5000 );
} catch (InterruptedException e) {
}
return !text.toUpperCase().contains( "FUNNY" );
}
}

This class has a single static method which sleeps for five seconds and then tests a string for the presence of the word "funny". To test this class, there is a SeriousComponentTest.java class in ${basedir}/src/test/java under the org.sonatype.mcookbook package which contains the following four test methods:

package org.sonatype.mcookbook;

import org.testng.annotations.Test;

@Test
public class SeriousComponentTest {

@Test
public void testSad() throws Exception {
assert SeriousComponent.testSeriousness("SAD");
}

@Test
public void testSerious() throws Exception {
assert SeriousComponent.testSeriousness("SERIOUS");
}

@Test
public void testCrazy() throws Exception {
assert SeriousComponent.testSeriousness("CRAZY");
}

@Test
public void testFunny() throws Exception {
assert !SeriousComponent.testSeriousness("FUNNY");
}
}

If you ran this test in a single thread, it would take approximately 20 seconds to execute. To speed up your build, configure Maven to execute each test method in parallel and set the available thread count for parallel test execution to 4. To do this, add the following plugin configuration to your project's POM.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.sonatype.mcookbook</groupId> <artifactId>testng-parallel</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>testng-tests</name> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <parallel>methods</parallel> <threadCount>4</threadCount> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>5.10</version> <classifier>jdk15</classifier> <scope>test</scope> </dependency> </dependencies> </project>

Execute the TestNG test in parallel by running mvn test and take note of the time it takes to execute all four tests.

$ mvn test
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building testng-tests
[INFO] task-segment: [test]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources {execution: default-resources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources {execution: default-testResources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [surefire:test {execution: default-test}]
[INFO] Surefire report directory: /Users/Tim/Library/Code/sonatype/ maven-cookbook/mcookbook-examples/unit/testng-parallel/target/surefire-reports

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running TestSuite
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.342 sec

Results :

Tests run: 4, Failures: 0, Errors: 0, Skipped: 0

You can see that the execution of four tests took a total of 5.342 sec. This is a clear indication that the tests were being run in parallel given the fact that the function being tested has a 5 second sleep built-in. Now, change the parallel configuration parameter to "classes" and rerun the test. Find the Maven Surefire plugin configuration in the project's POM and change the configuration to this:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<parallel>classes</parallel>
<threadCount>4</threadCount>
</configuration>
</plugin>

Now, run mvn test and notice how long it takes to run the unit tests - 20 seconds. When you run the tests in parallel using classes, TestNG is going to create an independent test execution thread for each class. The four test methods in SeriousComponentTest are going to be executed in one, single thread instead of the four simultaneous threads that were used when the parallel configuration parameter was set to "methods".

$ mvn test
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building testng-tests
[INFO] task-segment: [test]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources {execution: default-resources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources {execution: default-testResources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [surefire:test {execution: default-test}]
[INFO] Surefire report directory: /Users/Tim/Library/Code/sonatype/ maven-cookbook/mcookbook-examples/unit/testng-parallel/target/surefire-reports

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running TestSuite
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 20.411 sec

Results :

Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
7.6.3. Detail

If waiting around for your unit tests is eating up too much of your time, this is a great way to make your builds a bit faster.

You use the following values in the parallel configuration parmeter:

classes

Each test class will be executed in an independent execution thread.

methods

Each test method will be run as an independent test in a separate thread. Note that if one method states and explicit dependency on another method, TestNG will note the dependency and execute both methods in the same Thread.

tests

If you use a TestNG Suite XML file and you list a test element that groups a number of related tests, listing test in the parallel configuration element will configure TestNG to use a separate thread for each <test> element. This option is only relevant if you have configured the Maven Surefire plugin to use a custom TestNG Suite XML file with one or more <test> elements.

7.7. Skipping Unit Tests

7.7.1. Task

You need to skip unit tests in a Maven build.

7.7.2. Action

To skip unit tests in a Maven build, pass a value of true to the parameter maven.test.skip to Maven on the command line.

$mvn install -Dmaven.test.skip=true
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building testng-groups
[INFO] task-segment: [install]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources {execution: default-resources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources {execution: default-testResources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Not compiling test sources
[INFO] [surefire:test {execution: default-test}]
[INFO] Tests are skipped.
[INFO] [jar:jar {execution: default-jar}]
[INFO] Building jar: /Users/Tim/Library/Code/sonatype/maven-cookbook/ mcookbook-examples/unit/testng-groups/target/testng-groups-1.0-SNAPSHOT.jar
[INFO] [install:install {execution: default-install}]
[INFO] Installing /Users/Tim/Library/Code/sonatype/maven-cookbook/ mcookbook-examples/unit/testng-groups/target/testng-groups-1.0-SNAPSHOT.jar to /Users/Tim/.m2/repository/org/sonatype/mcookbook/testng-groups/ 1.0-SNAPSHOT/testng-groups-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Thu Nov 26 12:32:14 CST 2009
[INFO] Final Memory: 15M/80M
[INFO] ------------------------------------------------------------------------
7.7.3. Detail

If you need to configure a Maven build to skip tests, you would add the following Maven Surefire configuration.

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skip>true</skip> </configuration> </plugin>

7.8. Running a Single Unit Test

7.8.1. Task

You want to run a single test class from a Maven project.

7.8.2. Action

To run a specific unit test in a Maven build, pass the name of the test class to the parameter test on the command line.

$ mvn test -Dtest=SeriousComponentTest
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building testng-groups
[INFO] task-segment: [test]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources {execution: default-resources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources {execution: default-testResources}]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [surefire:test {execution: default-test}]
[INFO] Surefire report directory: /Users/Tim/Library/Code/sonatype/ maven-cookbook/mcookbook-examples/unit/testng-groups/target/surefire-reports

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running TestSuite
Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.466 sec

Results :

Tests run: 5, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5 seconds
[INFO] Finished at: Thu Nov 26 13:01:58 CST 2009
[INFO] Final Memory: 11M/80M
[INFO] ------------------------------------------------------------------------