CompositeTest

When automating complex testscenarios (like end-to-end tests), you may need to execute a combination of batches, webservice calls, web application interactions, etc, maybe even on different points in time. In unitils, we have support for all those components, but you could not orchestrate them easy. That is where the compositeTest module comes in.  

Now you can define each step as if it was a standalone test : you can specify the time with unitils-jodatime, prepare the database via dbunit, call a batch/send a webservice message/do something in a webpage. In fact, any annotation based module that you use in a normal test also works for the testpart. And of course, you can do the necessary asserts for that part of your complicated scenario directly in the testpart. 

In the end, you simply specify the sequence in which the parts are executed. This also makes it easy to reuse certain blocks to in multiple scenario's.  

If you would like to get a report for a testpart, no problem : each step is in fact a standalone test, but not reported as such. In the default behaviour, you will only get a failed/passed for the test(s) that execute the parts. If you want a testpart to report its status as well in a standalone manner, you can specify this in the annotation.

Installation

If you are using maven, you can add following dependency to your project.

01
02
03
04
05
<dependency>
    <groupId>org.unitils.compositetest</groupId>
    <artifactId>unitils-compositeTest</artifactId>
    <version>1.0.1</version>
</dependency>

Config

Please create unitils-local.properties, and add testlink to unitils.modules. Code as following:

01
02
03
04
05
unitils.modules=[...other modules...], compositetest, [...other modules...]
 
unitils.module.compositetest.className = org.unitils.compositetest.CompositeTestModule
unitils.module.compositetest.runAfter=
unitils.module.compositetest.enabled=true

How to use it...

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class CompositeTestJUnit4Test_TestClass extends UnitilsJUnit4TestBase {
 
 
    @CompositeTestHandler
    private CompositeTestDriver mpTestDriver;
 
     
    @Test
    public void testMain() {
        System.out.println("JU4 MAIN");
        registerTestInvocation(TEST_METHOD, this.getClass(), "main");
    }
         
         
    @Test
    @TestPart(name="part2")   
    public void testPart2() {
        System.out.println("JU4 PART2");
        registerTestInvocation(TEST_METHOD, this.getClass(), "part2");
    }
     
    @Test
    @TestPart(name="part3", executeAsSingleTest=true)   
    public void testPart3() {
        System.out.println("JU4 PART3");
        registerTestInvocation(TEST_METHOD, this.getClass(), "part3");
    }
     
    @Test
    public void multi() {
        System.out.println("JU4 MULTI");       
        this.mpTestDriver.launchTestPart("testPart1"); // via method name
        this.mpTestDriver.launchTestPart("part2");       
        this.mpTestDriver.launchTestPart("part3");
        registerTestInvocation(TEST_METHOD, this.getClass(), "multi"); // has to be the last, otherwise the check on executed method freaks out.
    }
     
    @Test
    @TestPart
    // behind the multi() method, order is not important
    public void testPart1() {
        System.out.println("JU4 PART1");
        registerTestInvocation(TEST_METHOD, this.getClass(), "part1");
    }
 
}

In the previous example there are 5 tests, but only 3 tests are executed:

  • testPart3
  • testMain
  • multi

But the multi test executes testPart1, testPart2, testPart3 and the multi test itself.
There are 2 ways to execute a test:

  • @Test without @TestPart
  • @Test + @TestPart + executeAsSingleTest=true