Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Maven Test Isolation

DZone's Guide to

Maven Test Isolation

How can you resolve memory errors while working in Maven? Take a look at a few tricks without changing your existing code.

· DevOps Zone
Free Resource

Learn more about how CareerBuilder was able to resolve customer issues 5x faster by using Scalyr, the fastest log management tool on the market. 

The other day I ran into a problem that made me quite puzzled. I was working on a project which build and ran without any problems. Then I enabled the use of a third-party library during the execution of the tests in the project and suddenly there were out of memory errors in PermGen during the build.

I had changed nothing in my own code and the application were working as expected when being run.

Allocating More PermGen Memory

The first obvious attempt was to allocate more PermGen memory when running the tests using the -XX:MaxPermSize=256m Maven option. In Linux or similar, this is set by executing the following line in a terminal window:

export MAVEN_OPTS="-XX:MaxPermSize=256m"

Unfortunately this only delayed the seemingly inevitable out of memory error.

Java 8 and PermGen

If you read this and have the option to build using Java 8 or later, then do try that option. I tried to run my build under Java 8, in which PermGen has been completely removed, and it worked without errors.
Unfortunately I didn’t have the option to use Java 8 so I had to soldier on.

Testing In Isolation

The Maven Surfire plug-in can be configured as to allow multiple tests to be run in parallel and whether a new JVM process is to be started for each new fork or not. In addition you can set memory allocation arguments to be used when running tests.
In the default configuration, tests will not run in parallel and the JVM process in which tests run will be reused. The latter is what may cause PermGen out of memory problems.
By adding the following plug-in configuration to the build section of your Maven pom file, each test will run in a new JVM process and only one single test at a time will be executed:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.18.1</version>
    <configuration>
        <argLine>-Xmx512m -XX:MaxPermSize=256m</argLine>
        <forkCount>1</forkCount>
        <reuseForks>false</reuseForks>
    </configuration>
</plugin>

With the above configuration in place, the entire build ran without memory problems.

I imagine running tests in parallel can be useful but it will also include additional complexity and problems. One problem that immediately comes to mind is mock servers; each mock server started in parallel would have to listen on a unique port. The Surefire plug-in does have a feature that makes it possible to accomplish but as of today, I am not sure it is worth the effort to parallelize my tests.

Find out more about how Scalyr built a proprietary database that does not use text indexing for their log management tool.

Topics:
devops ,test ,maven ,junit ,unit-testing ,surefire

Published at DZone with permission of Ivan K. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}