The Maven Cookbook

7.2. Running JUnit Tests

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.

Project Structure for Unit Tests

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.

Project Structure for JUnit Test 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)
....