Appendix C. Pax-Exam Testing Framework

Abstract

When it is time to start testing your application bundles in the OSGi container, it is recommended that you perform the testing using the Pax-Exam testing framework.

C.1. Introduction to Pax-Exam

Overview

Pax-Exam is an automated testing framework for running tests in an OSGi container. Consider the manual steps that would be needed to run tests in an OSGi container:
  1. Set up the environment and initial options for the OSGi container.
  2. Start the OSGi container.
  3. Install the prerequisite bundles into the OSGi container (provisioning).
  4. Install and run the test classes.
Using Pax-Exam you can automate and simplify this testing procedure. Initialization options and provisioning options are performed by a configuration method in the test class. The Pax-Exam framework takes care of starting the OSGi container and before running the test class bundle.
This section gives a brief introduction to the Pax-Exam testing framework and explains how to write a basic example using Apache Karaf.

JUnit 4 framework

JUnit 4 is the latest version of the JUnit Java testing suite. What distinguishes JUnit 4 from earlier versions is that JUnit 4 defines a test by applying Java annotations (in contrast to earlier versions of JUnit, which used inherited classes and naming conventions).
The simplest JUnit tests require just two steps:
  1. Specify which methods are the test methods by annotating them with the @org.junit.Test annotation.
  2. At any point in the test method, define an assertion by calling assertTrue() with a boolean argument (you also need to include a static import of org.junit.Assert.assertTrue() in the file). The test succeeds, if the specified assertions all evaluate to true.

Integration with Pax-Exam

To integrate JUnit 4 with Pax-Exam, perform the following steps:
  1. Customize JUnit to run the test in the Pax-Exam test runner class—JUnit allows you to delegate control over a test run to a custom runner class (by defining a runner class that inherits from org.junit.runner.Runner). In order to integrate JUnit with Pax-Exam, add a @RunWith annotation to the test class as follows:
    import org.junit.runner.RunWith;
    import org.ops4j.pax.exam.junit.JUnit4TestRunner;
    ...
    @RunWith(JUnit4TestRunner.class) 
    public class MyTest { 
        ...
    }
  2. Add a Pax-Exam configuration method to the test class—in order to run a test in an OSGi framework, you need to initialize the OSGi container properly and install any prerequisite bundles. These essential steps are performed by returning the appropriate options from the Pax-Exam configuration method. This method is identified by the @Configuration annotation as follows:
    import org.ops4j.pax.exam.junit.Configuration;
    ...
    @Configuration
    public static Option[] configuration() throws Exception {
        ...
    }
  3. Use the Pax-Exam fluent API to configure the OSGi framework—there are a fairly large number of settings and options that you can return from the Pax-Exam configuration method. In order to define these options efficiently, Pax-Exam provides a fluent API, which is defined mainly by the following classes:
    org.ops4j.pax.exam.CoreOptions
    Provides basic options for setting up the OSGi container. For example, this class provides options to set Java system properties (systemProperty()), define URLs (as a string, url(), or as an Mvn URL, maven()), and select OSGi frameworks (for example, felix() or equinox()).
    org.ops4j.pax.exam.OptionUtils
    Provides utilities for manipulating arrays of options and composite options.
    org.ops4j.pax.exam.container.def.PaxRunnerOptions
    Provides options for starting the OSGi container and for provisioning features and bundles. For example, the scanFeatures() and scanBundle() methods can be used to find and install features and bundles in the OSGi container before running the test.

Integration with Apache Karaf

Theoretically, Pax-Exam provides all of the features that are needed to run an OSGi framework embedded in Apache Karaf. In practice, however, there are a lot of Java system properties and configuration options that need to be set in order to initialize Apache Karaf. It would be a nuisance, if all of these properties and options needed to be specified explicitly in the Pax-Exam configuration method.
In order to simplify running Pax-Exam in Apache Karaf, helper classes are provided, which automatically take care of initializing the OSGi framework for you. The following classes are provided:
org.apache.karaf.testing.AbstractIntegrationTest
Provides some helper methods, particularly the getOsgiService() methods which make it easy to find an OSGi service, by specifying the Java type of the service or by specifying service properties.
org.apache.karaf.testing.Helper
Provides the Helper.getDefaultOptions() method, which configures all of the settings needed to start up Apache Karaf in a default configuration.

Maven dependencies

Example C.1, “Pax-Exam and Related Maven Dependencies” shows the Maven dependencies you need in order to run the Pax-Exam testing framework. You must specify dependencies on JUnit 4, Pax-Exam, and Apache Karaf tooling.

Example C.1. Pax-Exam and Related Maven Dependencies

<project ...>
  ...
  <properties>
    <junit-version>4.4</junit-version>
    <pax-exam-version>1.2.0</pax-exam-version>
    <felix.karaf.version>1.4.0-fuse-01-00</felix.karaf.version>
    ...
  </properties>

  <dependencies>
      <!-- Pax-Exam dependencies -->
      <dependency>
        <groupId>org.ops4j.pax.exam</groupId>
        <artifactId>pax-exam</artifactId>
        <version>${pax-exam-version}</version>
      </dependency>
      <dependency>
        <groupId>org.ops4j.pax.exam</groupId>
        <artifactId>pax-exam-junit</artifactId>
        <version>${pax-exam-version}</version>
      </dependency>
      <dependency>
        <groupId>org.ops4j.pax.exam</groupId>
        <artifactId>pax-exam-container-default</artifactId>
        <version>${pax-exam-version}</version>
      </dependency>
      <dependency>
        <groupId>org.ops4j.pax.exam</groupId>
        <artifactId>pax-exam-junit-extender-impl</artifactId>
        <version>${pax-exam-version}</version>
      </dependency>

      <!-- JUnit dependencies -->
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit-version}</version>
      </dependency>

      <!-- Apache Karaf integration --> 
      <dependency>
        <groupId>org.apache.karaf.tooling</groupId>
        <artifactId>org.apache.karaf.tooling.testing</artifactId>
        <version>${felix.karaf.version}</version>
        <scope>test</scope>
      </dependency>
  </dependencies>
  ...
</project>
This example uses custom properties to specify the versions of the various Maven artifacts.

References

To learn more about using the Pax-Exam testing framework, consult the following references: