Jim has posted 11 posts at DZone. View Full User Profile

Speed up your Unit Tests NOW!!!

02.29.2008
| 13601 views |
  • submit to reddit

Many Java developers know they *should* write and run unit tests, but often stop running, or even writing them, for several reasons. One reason I'm both seeing and hearing about more and more lately is the fact that running unit tests takes toooo looooooong. As a result, continuous builds get turned into nightly builds, which means that developers may be committing code that breaks the build without knowing it.

What's a development team to do???? Scale out your build process by setting up a build grid -- it's easier than you think! Ideally this would be transparent (such as having multiple instances of Maven's Surefire plugin running your tests at once, or simply replacing junit.jar), but things aren't quite there yet. However, a solution that requires minimal intervention is fortunately available: Add a single @GridifyTest annotation available in the GridGain API to your JUnit test suites, and that's all you have to do in your codebase.

 

Nikita Ivanov, the founder of the open source product GridGain,was kind enough to come down to Houston this week to show the Houston JUG just how to do that. He had two grid nodes running on his laptop, and showed how to run the unit tests right from Eclipse with the unit tests running in each of the other nodes. The JUnit bar even came back green, despite the fact that the unit tests weren't being run in Eclipse!!! He did have to add the GridGain jar and its dependent libraries to his project, and set up his JUnit runner to weave his JUnits with GridGain code, but it didn't take much effort. The JVM arguments and code from the Distributed JUnit Overview page are below, with the TestA & TestB classes added.

 

JVM Arguments:
-javaagent:[GRIDGAIN_HOME]/libs/aspectjweaver-1.5.3.jar
Note: Your Classpath should contain the [GRIDGAIN_HOME]/config/aop/aspectj folder

public class TestA extends TestCase {
public void testA(){
assert(true);
}
}

 

public class TestB extends TestCase {
public void testB(){
assert(true);
}
}

 

public class GridifyJunit3ExampleTestSuite {
// Standard JUnit3 suite method. Note we attach @GridifyTest
// annotation to it, so it will be grid-enabled.
@GridifyTest
public static TestSuite suite() {
TestSuite suite = new TestSuite("Example Test Suite");

// Nested test suite to run tests A and B sequentially.
TestSuite nested = new TestSuite("Example Nested Sequential Suite");

nested.addTestSuite(TestA.class);
nested.addTestSuite(TestB.class);

// Add tests A and B.
suite.addTest(nested);

return suite;
}
}

 

He mentioned that their unit tests were taking an hour to run, and decided to dogfood their own product to see if they could speed up their unit tests. The results were nothing short of staggering: They were able to cut their time down to only 11 minutes, which gets incredibly close to the 10 minutes that is ideal for achieving Continuous Integration. I forget how many grid nodes they used, but it wasn't very many (I think he mentioned it was only 5 or 6), and that they were able to get it working using Team City as their CI server really well.

 

OK -- you'll need to get GridGain set up and running on at least a few machines to make this possible, but the benefits far outweigh the short amount of time getting the infrastructure in place. Once the grid is in place, you can run the unit tests from any IDE, from your build process, or your CI server since they're all on the same network. You could get very creative about it too -- let's face it -- most of the time desktop CPUs are idle, so why not put them to good use?

 

You can find the full tutorial about how to distribute your JUnit tests at GridGain's Distributed JUnit Overview page, and instructions on how to install GridGain here. Their Javadocs for their GridifyTest class can be found here.

 

 

Published at DZone with permission of its author, Jim Bethancourt.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Jim Bethancourt replied on Fri, 2008/02/29 - 6:27pm

Correction -- Nikita gave me an update and let me know they're using Bamboo from Atlassian.

Nikita Ivanov replied on Fri, 2008/02/29 - 6:40pm

Jim,

It was great to be in Houston and organization was top notch! Great audience and great questions.

Thanks again,

Nikita Ivanov.

Dmitriy Setrakyan replied on Fri, 2008/02/29 - 8:15pm

You can also watch a screencast that shows how to grid-enable your JUnits here: http://www.gridgain.com/screencasts.html

There are some other interesting screencasts there as well, such as "Grid Application in 15 Minutes" for example.

Best,
Dmitriy Setrakyan
GridGain - Grid Computing Made Simple

Thomas Mueller replied on Sat, 2008/03/01 - 1:25am

Unit tests should be quick when developing, but thorough in continuous integration (CI).

To do that, you can use a scaling parameter. By default, the test performs only a few iterations (random operation tests, fuzz tests, concurrency tests). This is the quick/shallow setting (the default). When run in CI, the scaling parameter is higher, and more iterations are run. This is the slow/thorough setting.

Another flag is what database to use. When developing, use a quick database in in-memory mode (H2, HSQLDB). In CI, run the tests against the database your customer uses.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.