Most hip JUnit extension frameworks integrate easily with Groovy. For example, one can easily employ XMLUnit, DbUnit, and jWebUnit via JUnit tests written in Groovy as these frameworks expose an API that facilitates delegation. Decorator based frameworks, however, are slightly more challenging to utilize within Groovy.
JUnitPerf is an extension framework for JUnit that offers the neat-o ability to ascertain fine grained performance and scalability (i.e. at a method level). For instance, JUnitPerf enables scenarios such as “the findUsers
method must return a collection
of User
objects within one second or the test fails (even if the test did return a valid collection
of User
objects).” The framework also adds scalability via threading. Using the above scenario, one can add the trippin? requirement that under a load of 100 invocations, the findUsers
method must return a collection
of User
objects within one second.
Understandably, there are scenarios within Groovy where this type of framework could come in quite handy:
- testing the performance and scalability of Groovy applications
- testing the performance and scalability of normal Java code in tests written in Groovy
But, because JUnitPerf is a decorator based framework that requires test cases define a suite
method, integration with Groovy can cause some misleading results. Groovy’s available test runners, GroovyTestSuite
and AllTestSuite
create suite
methods themselves, which appears to override individually defined suite
methods within Groovy test cases. Therefore, when running a test case, written in Groovy, that contains a suite
method it appears the method is ignored. This means that test cases themselves are run; however, they are not decorated.
To solve this issue and successfully run a test case written in Groovy, which contains a suite
method, there are two steps that must be followed:
- define a constructor which takes a
String
and have that constructor callsuper(yourString)
- compile the Groovy test case into normal Java byte code and run it via JUnit?s normal runners.
For example, the following smokin? test case, written in Groovy, utilizes JUnitPerf via a suite
method to verify that invoking testOr
20 times (each thread staggered by 100 milliseconds) returns within 2300 milliseconds.
package test.com.acme.seda.impl.perf
import junit.framework.TestCase
import com.acme.seda.impl.RegexPackageFilter
import junit.framework.Test
import junit.textui.TestRunner
import com.clarkware.junitperf.ConstantTimer
import com.clarkware.junitperf.LoadTest
import com.clarkware.junitperf.TimedTest
import com.clarkware.junitperf.Timer
class RegexFilterPerfGTest extends TestCase {
RegexFilterPerfGTest(test){
super(test)
}
void testOr() {
def filr = new RegexPackageFilter("java|org")
assertTrue("value should be true",
filr.applyFilter("org.sf.String"))
}
static void main(String[] args) {
TestRunner.run(RegexFilterPerfGTest.suite())
}
static Test suite() {
def testCase = new RegexFilterPerfGTest("testOr")
//20 users for load staggered at 100 ms
def loadTest = new LoadTest(testCase, 20,
new ConstantTimer(100))
//each thread must return within 2300 ms
return new TimedTest(loadTest, 2300)
}
}
Running this test requires it first be complied into Java byte code and invoked via JUnit, which can be done quite easily with the Maven Groovy Test plug-in. By typing the groovytest:test
command, the plug-in will compile any Groovy tests into byte code and then invoke the test:test
command, which internally invokes the venerable junit
Ant task.
For instance, below is the output from running the groovytest:test
command in Maven.
test:test:
[junit] Running test.com.acme.seda.frmwrk.
filter.impl.ClassInclusionFilterTest
[junit] Tests run: 3, Failures: 0, Errors: 0,
Time elapsed: 0 sec
[junit] Running test.com.acme.seda.frmwrk.
filter.impl.misc.ConcurrentFilteringTest
[junit] Tests run: 10, Failures: 0, Errors: 0,
Time elapsed: 0.031 sec
[junit] Running test.com.acme.seda.frmwrk.
filter.impl.perf.RegexFilterPerfGTest
TimedTest (WAITING): LoadTest (NON-ATOMIC):
ThreadedTest: testOr(test.com.acme.seda.
frmwrk.filter.impl.perf.RegexFilterPerfGTest):
2015 ms
[junit] Tests run: 20, Failures: 0, Errors: 0,
Time elapsed: 2.031 sec
[junit] Running test.com.acme.seda.frmwrk.
filter.impl.SimpleFilterTest
[junit] Tests run: 1, Failures: 0, Errors: 0, Time
elapsed: 0.016 sec
The next time it?s your bag to figure out the performance of some Groovy code or you want to test the performance and scalability of your hip Java application with Groovy, give JUnitPerf a try! It?s a trip!