To use Maven for running your tests you should at least read the documentation for the Maven Surefire Plugin2, and in particular its section devoted to running JUnit tests with Maven. In addition, read the
1http://joda-time.sourceforge.net/
2http://maven.apache.org/plugins/maven-surefire-plugin/
Appendix B. Running Unit Tests
documentation for the Maven Surefire Report Plugin3 and the Maven Site Plugin4. Both can be used to generate nice HTML test reports. If you plan to use Maven for running more than unit tests you should take a look at the Maven Failsafe Plugin5. In any case, make sure you have an understanding of basic concepts of Maven - for example, its lifecycle. If you try using Maven without such knowledge, you will very quickly become frustrated.
This section provides basic information about running tests with Maven. There is much more to know about Maven (which is quite a complex tool, with all sorts of quirks of its own), but what is presented here should be enough to enable you to execute your unit tests with Maven.
As with Gradle, Maven will be happy with the default layout of your project. You need only inform Maven that it should use the JUnit dependency in the scope test (which makes Maven add JUnit JAR to the classpath during test execution).
Listing B.4. Basic Maven build script
<?xml version="1.0" encoding="UTF-8"?>
<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>com.practicalunittesting</groupId>
<artifactId>running-tests-with-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<url>http://practicalunittesting.com</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Now execute mvn test from the command line. Maven will automatically recognize JUnit test classes located in src/test/java and run them. You will see something similar to the following output (some lines omitted):
Appendix B. Running Unit Tests
Listing B.5. Output of "mvn test" command
>mvn clean test
[INFO] --- [INFO] Building running-tests-with-maven 1.0-SNAPSHOT
[INFO] --- ---
T E S T S
---
Running com.practicalunittesting.appendixb.SampleTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.058 sec Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- [INFO] BUILD SUCCESS
[INFO] ---
The last printed line assures us that all tests have passed successfully.
In the event of failed tests, Maven will print error messages to the console. Test results are kept in the
target/surefire-reports directory in text, and XML format. If you prefer something more readable, Maven makes it simple to generate an HTML report as well. As was mentioned previously, you could use the Maven Surefire Report Plugin or the Maven Site Plugin to achieve this.
B.4.1. Using JUnit Listeners and Reporters with Maven
Maven lets you specify which listeners (see Section 8.3) should be used when running tests. This is done by passing the fully qualified class name as a configuration parameter of the Maven Surefire Plugin. An example is shown in Listing B.6.
Listing B.6. Using a custom JUnit listener with Maven
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<properties>
<property>
<name>listener</name>
<value>com.practicalunittesting.TimeTestListener</value>
</property>
</properties>
</configuration>
</plugin>
B.4.2. Adding JARs to Maven’s Tests Classpath
To add other libraries to the test classpath (so that, for example, you can use Hamcrest in your test code), you will need to specify them in the same way that we specified the JUnit dependency. For example:
Appendix B. Running Unit Tests
Listing B.7. Maven - adding libraries required by tests classes
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.practicalunittesting</groupId>
<artifactId>listeners</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Make sure you use the test scope so Maven adds them to the test classpath.
Appendix C. Test Spy vs. Mock
As we mentioned in Section 5.2, test spies and mocks have a great deal in common. Their purpose is identical: they are there to verify the correctness of calls from the SUT to its DOCs (so-called "indirect outputs"). However, there are some subtle differences between the two, which are definitely worth discussing. As you will soon learn, some of the differences between the two are clear, and some are still being discussed by the community.
(DISCLAIMER) It is really hard to compare such theoretical entities as the mock and the test spy without comparing their specific implementations - like the ones provided by EasyMock and Mockito. I have put a lot of effort into making sure that this section abstracts out from specific and particular solutions, but I think that it (inevitably) reflects the current state of mocking and test-spying frameworks.