Chapter 10. Running JUnit tests from Maven2

The conventional view serves to protect us from the painful job of thinking.

John Kenneth Galbraith

This chapter covers

  • Introduction to Maven
  • Dependency management the Maven way
  • Maven Surefire plug-in
  • Maven Surefire Report plug-in

In this chapter we discuss and reveal another common build system tool called Maven. We show you how Maven differs from Ant. We also present a brief introduction to this build system, which will be useful if you’re new to it or need a way to start your tests continuously.

People sometimes come to Maven thinking that it will be something like Ant. Once they discover that it’s totally different, they get frustrated. Don’t worry; you’re not alone. This is why we spend the first few pages of this chapter explaining what’s most essential in order to understand Maven: how it’s different from Ant. After that, we present some real-world examples of compiling your test cases and running them as well as producing fancy reports.

By the end of this chapter, you’ll know how to set up your environment on your machine to build Java projects with Maven, including managing their dependencies, executing JUnit tests, and generating JUnit reports.

10.1. Maven’s features

Once you’ve used Ant on several projects, you’ll notice that projects almost always need the same Ant scripts (or at least a good percentage of them). These scripts are easy enough to reuse through cutting and pasting, but each new project requires a bit of fussing to get the Ant buildfiles working just right. In addition, each project usually ends up having several subprojects, each of which requires you to create and maintain an Ant buildfile. Maven (http://maven.apache.org/) picks up where Ant leaves off, making it a natural fit for many teams. Like Ant, Maven is a tool for running other tools, but Maven is designed to take tool reuse to the next level. If Ant is a source-building framework, then Maven is a source-building environment.

In order to understand better how Maven works, you need to understand the key points (principles) behind Maven. Maven was designed to take the build systems to the next level, beyond Ant. You need to become familiar with the things that the Maven community didn’t like in Ant and how it tried to avoid them in designing Maven, that is, the core reason for starting Maven as a whole new project.

From the beginning of the Maven project, certain ground rules were in place for the entire software architecture of the project. These rules aim to simplify development with Maven and to make it easier for developers to implement the build system. One of the fundamental ideas of Maven is that the build system should be as simple as possible—software engineers should not spend a lot of time implementing the build system. It should be easy enough to start a new project from scratch and then rapidly begin developing the software, not spend valuable time designing and implementing a build system.

In this section we describe each of the core Maven principles in detail, and we explain what they mean to us, from a developer’s point of view.

10.1.1. Convention over configuration

This feature is a software design principle that aims to decrease the number of configurations a software engineer needs to make, in favor of introducing a number of conventional rules that the developers need to follow. This way you, as a developer, can skip the tedious configuration required for every single project, and you can focus on the more important parts of your work.

Convention over configuration is one of the strongest principles of the Maven project. As an example of its application, let’s look at the directory structure of the build process. When the Maven project was started, some of the initial Maven developers noticed that for every Ant buildfile, the person who writes the buildfile has to design the directory structure: declare the source directories, the build directories, and many other directories needed for the build itself. And although the Ant community tries to imply some directory names and directory structure, there’s still no official specification (convention) of how a directory should be named. For instance, many people declare the target.dir property to denote the directory that holds their compiled classes, whereas others may be accustomed to using the build.dir property and it seems unnatural to them to use target.dir. Also, many people place their source code in the src/ directory, but others put it in the src/java/ directory. The Maven team decided that instead of allowing the software engineers to choose the build structure every time themselves, they’d introduce a convention for this. This resulted in what’s now called the “Maven convention of directory structure.” With Maven, instead of defining all the directories you need, they’re defined for you. For example, the src/ main/java/ directory is the Maven convention for where the Java code for the project resides, src/main/test/ is where the unit tests for the project reside, target is the build directory, and so on. And it isn’t just the directory structure. Later on when we discuss the plug-ins themselves, you’ll see how every plug-in has a default state already defined, so you don’t need to define it again.

That sounds great, but aren’t we losing some of the flexibility of the project? What if we want to use Maven, and our source code resides in another directory? Maven is great at this. It provides the convention, but you still can, at any point, override the convention and use the configuration of your choice.

10.1.2. Strong dependency management

This is the second key point that Maven introduced. At the time the project was started, the de facto build system for Java projects was Ant. With Ant you have to distribute the dependencies of your project with the project itself. Maven introduced the notion of a central repository—a location on the internet where all kinds of artifacts (dependencies) are stored. The Maven build tool resolves them by reading your project’s build descriptor, downloading the necessary versions of the artifacts, and then including them in the classpath of your application. This way you only need to list your dependencies in the dependencies section of your build descriptor, as shown here:

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.5</version>
</dependency>
<dependency>
<groupId>jmock</groupId>
<artifactId>jmock</artifactId>
<version>1.0.1</version>
</dependency>
</dependencies>

Then you’re free to build the software on any other machine. There’s no need to bundle the dependencies with your project and so forth.

But Maven introduced also the concept of the local repository. This is a directory on your hard disk (~/.m2/repository/ on UNIX and C:Documents and Settings<UserName>.m2 epository on Windows) where Maven keeps the artifacts that it has just downloaded from the central repository. Also, after you’ve built your project, your artifacts are installed in the local repository for later use by some other projects—simple and neat.

10.1.3. Maven build lifecycles

Another strong principle in Maven is the build lifecycle. The Maven project is built around the idea of defining the process of building, testing, and distributing a particular artifact. Maven projects can produce only one artifact. This way we can use Maven for building the project’s artifact, or cleaning the project’s directory structure, or generating the project’s documentation. The activities we use Maven for define the three built-in lifecycles of Maven:

  • Default— For generating the project’s artifact
  • Clean— For cleaning the project
  • Site— For generating the project’s documentation

Each of these lifecycles comprises several phases, and in order to pass through a certain lifecycle, the build must follow its phases.

Here’s a list of all the phases of the default lifecycle:

  • Validate— Validate that the project is correct and all necessary information is available.
  • Compile— Compile the source code of the project.
  • Test— Test the compiled source code using a suitable unit-testing framework. These tests should not require the code to be packaged or deployed.
  • Package— Package the compiled code in its distributable format, such as a JAR.
  • Integration test— Process and deploy the package if necessary into an environment where integration tests can be run.
  • Verify— Run any checks to verify that the package is valid and meets quality criteria.
  • Install— Install the package into the local repository for use as a dependency in other projects locally.
  • Deploy— In an integration or release environment, copy the final package to the remote repository for sharing with other developers and projects.

If you remember, with Ant we had targets with almost the same names. And yes, the targets in Ant are the analogue of the phases in Maven, with one exception. In Ant you write the targets and you specify which target depends on which other target. With Maven, we see again the convention-over-configuration principle here. These phases are already defined for us in the order in which we listed them. And Maven invokes these phases in a strict order: they get executed sequentially in the order listed to complete the lifecycle. This means that if you invoke any of them, for example, if you type

mvn compile

on the command line in your project’s home directory, Maven will first validate the project and then try to compile the sources of your project.

One last thing—it’s useful to think of all these phases as extension points. At any moment you can attach additional Maven plug-ins to the phases and orchestrate the order and the way these plug-ins are executed.

10.1.4. Plug-in-based architecture

The last feature of Maven that we’ll mention is its plug-in-based architecture. At the beginning of this chapter, we said that Ant is a source-building framework and Maven is a source-building environment. More specifically, Maven is a plug-in, execution, source-building environment. The core of the project is small, but the architecture of the project allows multiple plug-ins to be attached to the core, and so Maven builds an environment where different plug-ins can get executed.

Each of the phases in a given lifecycle has a number of plug-ins attached to that phase, and Maven invokes them when passing through the given phase in the order in which the plug-ins are declared. Here are some of the core Maven plug-ins:

  • Clean plug-in— Cleans up after the build
  • Compiler plug-in— Compiles Java sources
  • Deploy plug-in— Deploys the built artifact to the remote repository
  • Install plug-in— Installs the built artifact into the local repository
  • Resources plug-in— Copies the resources to the output directory for inclusion in the JAR
  • Site plug-in— Generates a site for the current project
  • Surefire plug-in— Runs the JUnit tests in an isolated classloader
  • Verifier plug-in— Useful for integration tests; verifies the existence of certain conditions

Apart from these core Maven plug-ins, there are also dozens of other Maven plug-ins for every kind of situation you may need—WAR plug-in, Javadoc plug-in, AntRun plug-in—you name it.

Plug-ins are declared in the plugins section of your build configuration file, for instance:

<build>
<plugins>
<plugin>
<groupId>org.apache.cactus</groupId>
<artifactId>cactus.integration.maven2</artifactId>
<version>1.8.1-SNAPSHOT</version>
</plugin>
</plugins>
</build>

As you can see, every plug-in declaration specifies groupId, artifactId, and version. With this the plug-ins look like dependencies, don’t they? Yes, they do, and they’re handled the same way—they’re downloaded into your local repository the same way dependencies are. When specifying a plug-in, the groupId and version are optional parameters; if you don’t declare them, Maven will look for a plug-in with the specified artifactId and one of the following groupIds: org.apache.maven. plugins or org.codehaus.mojo. The version is optional. If you’re using a Maven version pre-2.0.9, Maven will try to download the latest version available. But as of Maven version 2.0.9, the versions of most plug-ins are locked down in the Super POM, so it won’t download the latest version anymore. Locking down plug-in versions is highly recommended to avoid autoupdating and nonreproducible builds.

Tons of additional plug-ins are available outside the Maven project but can be used with Maven. The reason for this is that it’s extremely easy to write plug-ins for Maven.

10.1.5. The Maven Project Object Model

If you remember, Ant has a buildfile, by default named build.xml, that holds all of the information for our build. In that buildfile we specify all the things that we want to accomplish in the form of tasks and targets.

What’s the analogue in Maven of Ant’s build.xml? Maven also has a build descriptor that’s by default called pom.xml, shortened from Project Object Model (POM). In contrast to Ant, in Maven’s project descriptor we don’t specify the things we want to do; we specify general information for the project itself, as in listing 10.1.

Listing 10.1. Simple pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.manning.junitbook</groupId>
<artifactId>example-pom</artifactId>
<packaging>jar</packaging>
<version>2.0-SNAPSHOT</version>
</project>

It looks simple, doesn’t it? But one big question arises at this moment: “How is even Maven capable of building our source code with so little information?”

The answer lies in the inheritance feature of the pom.xmls: every simple pom.xml inherits most of its functionality from a Super POM. As in Java, where every object inherits certain methods from the java.lang.Object object, the Super POM empowers each of our pom.xmls with the Maven features.

You see the similarity between Java and Maven. This analogue goes even further: Maven pom.xmls can inherit from each other, just as in Java some classes can act as parents for others. For instance, if we want to use the pom from listing 10.1 for our parent, all we have to do is change its packaging value to pom. Parent and aggregation (multimodule) projects can have only pom as a packaging value. We also need to define in our parent the child modules, as shown in listing 10.2.

Listing 10.2. Child modules for parent pom.xml

This listing is an extension of listing 10.1. We declare that this pom is an aggregation module by declaring the package to be of pom type and adding a modules section . The modules section lists all the child modules that our module has, by providing the relative path to the project directory (example-module).

Listing 10.3 shows the child pom.xml.

Listing 10.3. Pom.xml that inherits the parent pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.manning.junitbook</groupId>
<artifactId>example-pom</artifactId>
<version>2.0-SNAPSHOT</version>
</parent>
<artifactId>example-child</artifactId>
</project>

Remember that this pom.xml resides in the directory that the parent pom.xml has declared (example-module).

There are two things are worth noticing here. First, because we inherit from some other pom, there’s no need to specify groupId and version for the child pom; Maven expects they’re the same as the parent’s.

Going with the similarity to Java, it seems reasonable to ask, “What kind of objects can poms inherit from their parents?” Here’s a list of all the elements that a pom can inherit from its parent:

  • Dependencies
  • Developers and contributors
  • Plug-in lists
  • Reports lists
  • Plug-in executions with matching IDs
  • Plug-in configurations

And again, each of these elements specified in the parent pom get automatically specified in the child pom.

We discuss the poms further in the upcoming sections.

10.2. Setting up a Maven project

Now that you’ve seen the differences between Ant and Maven, it’s time to move on and start building our projects with Maven. But first, let’s examine the installation process.

 

Installing Maven

Installing Maven is a three-step process:

  1. Download the latest distribution from http://maven.apache.org/ and unzip/ untar it in the directory of your choice (for example, C:maven on Windows or /opt/maven on UNIX).
  2. Define an M2_HOME environment variable pointing to where you’ve installed Maven.
  3. Add M2_HOMEin (M2_HOME/bin on UNIX) to your PATH environment variable so that you can type mvn from any directory.

You’re now ready to use Maven. The first time you execute a plug-in, make sure your internet connection is on, because Maven will automatically download from the web all the third-party JARs the plug-in requires.

 

Let’s navigate to the c:junitbook2 directory. This is our work directory, and here we set up the Maven examples. Type the following on the command line:

mvn archetype:create -DgroupId=com.manning.junitbook
-DartifactId=maven-sampling -DarchetypeArtifactid=maven-artifact-mojo

After you press Enter and wait for appropriate artifacts to download, you should see a directory named maven-sampling being created. If you look inside that directory, you should see the directory structure being created, as shown in figure 10.1.

Figure 10.1. Directory structure after creating the project

What happened here? We invoked the maven-archetype-plugin from the command line and told it to create a new project from scratch with the given parameters. As a result, this Maven plug-in created a new project with a new directory structure, following the convention of the directory structure. Further, it created a sample App.java class with a main method and a corresponding AppTest.java file that’s a unit test for our application. Now, most likely, after looking at this directory structure, you’re quite familiar with which files stay in src/main/java and which files stay in src/ test/java.

But it gets even more automated. The Maven plug-in also generated a pom.xml file for us. Let’s open it and examine the different parts of the descriptor, shown in listing 10.4.

Listing 10.4. Pom.xml for the maven-sampling project
<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.manning.junitbook</groupId>
<artifactId>maven-sampling</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>maven-sampling</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

This is the build descriptor for our project. It starts with a global <project> tag with the appropriate namespaces, inside which we place all of our components:

  • modelVersion—The model version of the pom being used. Currently the only supported version is 4.0.0.
  • groupId—The group ID of our project. Notice that this is the value that we provided on the command line when invoking Maven. The groupId acts as the Java packaging in the filesystem; it groups together different projects from one organization, company, group of people, and so on.
  • artifactId—The artifact ID of our project. Again, the value here is the one we specified on the command line. The artifactId represents the name the project is known by.
  • packaging—What kind of artifact packaging will our project use? We specify here jar, but it also could be pom, ear, or war.
  • version—The current version of our project (or our project’s artifact). Notice the –SNAPSHOT ending. This ending denotes that this artifact is still in development mode; we haven’t released it yet.
  • dependencies—This section is used to list the dependencies.

Now that we have our project descriptor, let’s improve it a little, as shown in listing 10.5. First, we need to change the version of the JUnit dependency, because we’re using 4.6, and the one that the plug-in generated is 3.8.1. After that, we can make some additional information in the pom.xml more descriptive, like adding a developers section. This information not only makes the pom.xml more descriptive, but it will also be included later on when we build the website.

Listing 10.5. Additional metadata for the pom.xml
<developers>
<developer>
<name>Petar Tahchiev</name>
<id>ptahchiev</id>
<organization>Apache Software Foundation</organization>
<roles>
<role>Java Developer</role>
</roles>
</developer>
<developer>
<name>Gary Gregory</name>
<id>ggregory</id>
<organization>Apache Software Foundation</organization>
<roles>
<role>Java Developer</role>
</roles>
</developer>
<developer>
<name>Felipe Leme</name>
<id>felipeal</id>
<organization>Apache Software Foundation</organization>
<roles>
<role>Java Developer</role>
</roles>
</developer>
</developers>

Listing 10.6 continues the previous one, showing the organization, description, and inceptionYear elements.

Listing 10.6. Description elements for the pom.xml
<description>
"JUnit in Action II" book, the sample project for the "Running Junit
tests from Maven" chapter.
</description>
<organization>
<name>Manning Publications</name>
<url>http://manning.com/</url>
</organization>
<inceptionYear>2008</inceptionYear>

Now let’s move on and start developing our software. We want to use our favorite Java IDE: Eclipse or IntelliJ IDEA. No problem—Maven offers additional plug-ins to import the project into our favorite IDE. For instance, we use Eclipse to show you how this import happens. Again, open a terminal and navigate to the directory that contains your project descriptor (pom.xml). Once there, type the following and hit Enter:

mvn eclipse:eclipse -DdownloadSources=true

This will invoke the maven-eclipse-plugin, which, after downloading the necessary artifacts, will produce the two files (.project and .classpath) that Eclipse needs in order to recognize your project as an Eclipse project. The downloadSources parameter that we specify in the command line is optional. By using it we instruct the plug-in to also download source attachments. You can also download the Javadoc attachments by setting the optional downloadJavadocs parameter to true on the command line. Now you can import your project into Eclipse and examine it; you’ll notice that all of the dependencies that are listed in the pom.xml file are now added to your buildpath. Amazing, isn’t it?

To continue, let’s generate some documentation for the project. But wait a second, how are we supposed to do that? We don’t have any files to generate the documentation from. This is another one of Maven’s great features—with the little configuration and description that we have, we can produce a fully functional website skeleton. Type

mvn site

on the command line where your pom.xml is. Maven should start downloading its plug-ins, and after their successful installation, it will produce the nice website you see in figure 10.2.

Figure 10.2. Maven produces nice website documentation for the project.

This website is generated in Maven’s build directory—another convention. Maven uses the target/ directory for all the needs of the build itself. The convention continues even beneath this directory: source code is compiled in the target/classes/ directory, and the documentation is generated in target/site/.

After you examine the project, you’ll probably notice that this website is more like a skeleton of a website. That’s true, but remember that we entered only a small amount of data to begin with. We could enter more data and web pages in the src/site directory, and Maven will include it in the website, generating full documentation.

10.3. Introduction to Maven plug-ins

So far, so good. You’ve seen what Maven is and how to use it to start a project from scratch. You’ve also seen how to generate the project’s documentation and how to import our project in Eclipse.

To continue, we can get the source code from the first part of the book and place it in the src/main/java directory, where Maven expects it to be. Also, we can get the tests for the sampling project and place them in the src/test/java directory (again a convention). Now it’s time to invoke Maven and instruct it to compile the source code and tests and also to execute the tests.

But first we need to clean the project from our previous activities:

mvn clean

This will cause Maven to go through the clean phase and invoke all of the plug-ins that are attached to this phase, in particular the maven-clean-plugin, which will delete the target/ directory, where our generated site resides.

10.3.1. Maven Compiler plug-in

Like any other build system, Maven is supposed to build your projects—compile your software and package in an archive. As we mentioned at the beginning of the chapter, every task in Maven in done by an appropriate plug-in, the configuration of which happens in the <plugins> section of our project descriptor. To compile your source code, all you need to do is invoke the compile phase on the command line:

mvn compile

This will cause Maven to execute all of the plug-ins that are attached to the compile phase (in particular it will invoke the maven-compiler-plugin). But before invoking the compile phase, as already discussed, Maven will go through the validate phase and will download all of the dependencies that are listed in the pom.xml and include them in the classpath of the project. Once the compilation process is completed, you can go to the target/classes/ directory, and you should see the compiled classes there.

Let’s move on and try to configure the Compiler plug-in. Notice the italics in the previous sentence? Yeah, that’s right—we’ll escape from the convention-over-configuration principle and will try to configure the Compiler plug-in.

So far, we’ve used the conventional Compiler plug-in, and everything worked well. But what if we need to include the –source and –target attributes in the compiler invocation to generate class files for a specific version of the JVM? We should add the lines in listing 10.7 to the <build> section of our buildfile.

Listing 10.7. Configuring the maven-compiler-plugin
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.4</source>
<target>1.4</target>
</configuration>
</plugin>
</plugins>
</build>

This is a general way to configure each one of your Maven plug-ins; you enter a <plugins> section into your <build> section. There you list each of the plug-ins that you want to configure. In our case, it’s the maven-compiler-plugin. You need to enter the configuration parameters in the plug-in’s configuration section. You can get a list of parameters for every plug-in from the Maven website.

As you can see in the declaration of the maven-compiler-plugin in the previous listing, we haven’t set the groupId parameter. That’s because the maven-compiler-plugin is one of the core Maven plug-ins that has a org.apache.maven.plugins groupId, and as we mentioned at the beginning of the chapter, plug-ins with such a groupId can skip it.

10.3.2. Maven Surefire plug-in

Ant uses the javac task to compile the tests that we’ve selected, the same way Maven uses the maven-compiler-plugin to compile all of the source code that’s in src/main/java/. The same thing happens with the process of unit testing your project; Ant uses the junit task and executes the test cases that we’ve selected, whereas Maven uses—guess what?—a plug-in. The Maven plug-in that executes the unit tests is called maven-surefire-plugin. Notice the italics in the previous sentence; the Surefire plug-in is used to execute the unit tests for your code, but these unit tests aren’t necessarily JUnit tests. There are also other frameworks for unit testing, and the Surefire plug-in can execute their tests, too.

The conventional way to start the maven-surefire-plugin is simple. All you need to do is invoke the test phase of Maven. This way Maven will first invoke all of the phases that are supposed to come before the test phase (validate and compile phases) and then invoke all of the plug-ins that are attached to the test phase, thus invoking the maven-surefire-plugin. So by calling

mvn clean test

Maven first cleans the target/ directory, then compiles the source code and the tests, and finally executes all of the tests that are in the src/test/java directory (remember the convention). The output should be similar to that shown in figure 10.3.

Figure 10.3. Execution of JUnit tests with Maven2

That’s great, but what if we don’t want to execute all of our tests? What if we want to execute only a single test case? Well, this is something unconventional, so we need to configure the maven-surefire-plugin to do it. Hopefully there’s a parameter for the plug-in that allows us to specify a pattern of test cases that we want to be executed. The configuration of the Surefire plug-in is done in the same way as the configuration of the Compiler plug-in, and it’s shown in listing 10.8.

Listing 10.8. Configuration of the maven-surefire-plugin
<build>
<plugins>
[...]
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>**/Test*.java</includes>
</configuration>
</plugin>
[...]
</plugins>
</build>

As you can see, we’ve specified the includes parameter to denote that we want only the test cases matching the given pattern to be executed. Yes, but how do we know what parameters the maven-surefire-plugin accepts? No one knows all the parameters by heart, but you can always consult the maven-surefire-plugin documentation (and any other plug-in documentation) on the Maven website (http://maven.apache.org/).

10.3.3. HTML JUnit reports with Maven

As you saw in the previous chapter, Ant has a task for generating nice reports out of JUnit’s XML output. The same thing applies for Maven. And because Maven, by default, produces plain and XML-formatted output (by convention it goes into the target/surefire-reports directory), we don’t need any other configuration to produce HTML Surefire Reports for the JUnit tests.

As you’ve already guessed, the job for producing these reports is done by a Maven plug-in. The name of the plug-in is maven-surefire-report-plugin, and by default, it isn’t attached to any of the core phases that we already know (many people don’t need HTML reports every time they build their software). This means that we can’t invoke it by running a certain phase (as we did with both the Compiler plug-in and the Surefire plug-in), but instead we have to call it directly from the command line:

mvn surefire-report:report

When we do so, Maven will try to compile the source files and the test cases and then invoke the Surefire plug-in to produce the plain text and XML-formatted output of the tests. After that the Surefire Report plug-in will try to transform all of the XML reports from the target/surefire-reports/ directory into an HTML report that will be placed in the target/site directory (remember that the convention for the directory is to keep all of the generated documentation of the project, and the HTML reports are considered documentation).

If you try to open the generated HTML report, it should look something like the one shown in figure 10.4.

Figure 10.4. HTML report from the Maven Surefire Report plug-in

In the next section, we cover some of Maven’s weaker points.

10.4. The bad side of Maven

So far, we’ve discussed Maven as the tool that’s going to take the place of Ant. But as with all other things in life, it’s not all a bed of roses. Maven has its bad sides, too. Before you get too excited, just think about it. Maven has been out since 2002, and still Ant is the de facto standard for building software.

All of the people who’ve used Maven agree that it’s easy to start up with it. And the idea behind the project is amazing. But things seem to break when you need to do some of the unconventional things.

What’s great about Maven is that it will set up a frame for you and will constrain you to think inside that frame—to think the Maven way and do things the Maven way. When you work with Maven for a certain period of time, you’ll inevitably need to copy a file from one place to another. We think you’ll be surprised to see that there’s no copy plug-in in Maven, in contrast with Ant, which has the copy task. You have to deal with the situation, and if you investigate further and think “the Maven way,” it may turn out that you never needed to copy that file.

In most cases Maven won’t let you do any nonsense. It will restrict you and show you the way things need to be done. Ant works the other way: it’s a powerful tool, and you can do whatever you need to do. But it can be dangerous in inappropriate hands. And again, it’s up to you to decide which of these tools you want to use. Some companies hire build engineers, who are considered to have the appropriate knowledge, so for them Ant is no danger at all—it’s just a powerful tool.

To finish this chapter we’ll tell you a story. We have a friend who once had a job interview.

“Well, is it possible for Ant to do ...?” he was asked.

Without even letting the interviewer to finish his sentence, my friend replied, “Yes, it is.”

We’re not sure what his answer would have been if he’d been asked about Maven.

10.5. Summary

In this chapter we briefly introduced you to what Maven is and how to use it in a development environment to build your source code. We discussed in detail all of the features of Maven that make it unique compared to any other build system. We also looked at two of Maven’s plug-ins in detail: the Compiler plug-in and the Surefire plug-in. With this information you should be able not only to start and execute your tests but also to produce nice HTML reports of the test results.

In the next chapter we close the automation part of the book, by introducing different continuous integration build tools, such as CruiseControl and Hudson. We show you the benefits of using such tools and also how to install and configure these tools.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.46.69