JUnit Driver

Overview

The JUnit driver lets you write Pax Exam tests much like plain old JUnit tests, with a couple of modifications and restrictions. JUnit provides a very powerful extension mechanism through its @RunWith annotation, which is leveraged by Pax Exam.

This is the skeleton of a Pax Exam JUnit test:

@RunWith(PaxExam.class)
@ExamReactorStrategy(...)
public class SampleTest {

    @Inject
    private BundleContext bc;

    @Inject @Filter("(sophistication=major)")
    private CoolService coolService;

    @Rule
    public MethodRule rule = new MyMethodRule();

    @Configuration
    public Option[] config1() {
       // ...
    }

    @Configuration
    public Option[] config2() {
       // ...
    }

    @Before
    public void setUp() {
       // ...
    }

    @After
    public void tearDown() {
       // ...
    }

    @Test
    public void test1() {
       // ...
    }

    @Test
    public void test2() {
       // ...
    }

    @Test
    public void test3() {
       // ...
    }
}

In your @Configuration methods include this option:

org.ops4j.pax.exam.CoreOptions.junitBundles(),

Example

Have a look at the BeforeAfterTest in the Pax Exam Regression Test Suite.

Points to note

  • The @RunWith(PaxExam.class) annotation is required to hook Pax Exam into JUnit.
  • The @ExamReactorStrategy(...) annotation lets you specify a reactor strategy. It is optional and defaults to PerMethod in OSGi mode or PerSuite in all other modes.
  • In OSGi mode, you need at least one no-args method with return type Option[] and annotated by @Configuration. The method name does not matter. If there is more than one configuration method, each test method will be run for each of the given configurations.
  • In other modes, a @Configuration is not required. You can use it to deploy additional modules.
  • Test methods are identified by the usual JUnit @Test annotation.
  • @Before and @After methods work as expected. They are executed in the container before or after the test method.
  • Method rules with @Rule annotations also work as in vanilla JUnit.
  • @BeforeClass and @AfterClass are not supported. (More precisely, methods with these annotations are run in the driver but not in the test container.) Class-level actions would require more significant changes in the internal design of Pax Exam, which is currently based on the assumption that one test corresponds to one method.
  • Pax Exam tests support Dependency Injection, using @Inject annotations (and an optional @Filter in OSGi mode).

Compatibility Note

Pax Exam test annotations @Configuration, @ExamFactory, @ExamReactorStrategy now come from package org.ops4j.pax.exam so they can be shared with the TestNG driver. The old 2.x annotations from org.ops4j.pax.exam.junit are deprecated but still functional.

The JUnit runner is now called PaxExam. The old name JUnit4TestRunner is still working but deprecated.

Parameterized Tests

Since 3.2.0.

In addition to PaxExam, the JUnit driver contains a PaxExamParameterized runner for executing parameterized tests.

This runner reuses the @Parameters and @Parameter annotations from JUnit. To turn a vanilla parameterized test into a Pax Exam test with an embedded container and service injection, simply replace Parameterized by PaxExamParameterized:

import org.ops4j.pax.exam.junit.PaxExamParameterized;

@RunWith(PaxExamParameterized.class)
public class CalculatorTest {
    
    @Inject
    private Calculator calculator;

    private int a;
    private int b;
    private int sum;
    
    @Parameters
    public static List<Object[]> getParameters() {
        return Arrays.asList(new Object[][] {
            {2, 3, 5},
            {6, 2, 8}
        });
    }


    
    public CalculatorTest(int a, int b, int sum) {
        this.a = a;
        this.b = b;
        this.sum = sum;
    }
    
    @Test
    public void add() {        
        assertThat(calculator.add(a,  b), is(sum));
    }
}