此内容没有您所选择的语言版本。
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:
- Set up the environment and initial options for the OSGi container.
- Start the OSGi container.
- Install the prerequisite bundles into the OSGi container (provisioning).
- Install and run the test classes.
Using Pax-Exam you can simplify this testing procedure by automating it. 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 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. It defines a test by applying Java annotations, rather than using inherited classes and naming conventions as earlier versions did.
The simplest JUnit tests require two steps:
- Specify which methods are the test methods by annotating them with the
@Test
annotation (you also need to include an import oforg.junit.Test
in the file) . - At any point in the test method, define an assertion by calling one of the methods
assertTrue()
,assertNotNull()
, orassertEquals()
with a boolean argument (you also need to include a static import oforg.junit.Assert.*
in the file). The test succeeds, if the specified assertions all evaluate totrue
.
Integration with Pax-Exam
To integrate JUnit 4 with Pax-Exam, perform the following steps:
- Import the requisite Pax Exam, JUnit, and other classes; for example:
import static org.ops4j.pax.exam.CoreOptions.*; import static org.junit.Assert.*; import javax.inject.Inject; import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.Configuration; import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.PaxExam; import org.ops4j.pax.exam.regression.pde.HelloService; import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; import org.ops4j.pax.exam.spi.reactors.PerMethod; ...
- Customize JUnit to run the test in the PaxExam class—Adding a
@RunWith(PaxExam.class)
annotation to the test class hooks Pax Exam into JUnit, enabling it to set up a test container with an OSGi framework, provision your bundles according to specifed configuration options, and build a probe bundle from the test classes and resources in your current project:... import org.junit.runner.RunWith; import org.ops4j.pax.exam.junit.PaxExam; ... @RunWith(PaxExam.class) public class MyTest { ... }
- Add a PaxExam configuration method to the test class or classes— 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 PaxExam configuration method. This method is identified by the
@Configuration
annotation this way:import org.ops4j.pax.exam.junit.Configuration; ... @Configuration public static Option[] configuration() throws Exception { ... }
The@Configuration
annotation returns an array of configuration options that define the set of bundles to be provisioned the OSGi framework in the test container. It also provides access to a large number of configuration options—both provisioning and properties options: - Use the PaxExam fluent API to configure the OSGi framework—the PaxExam configuration method supports a fairly large number of provisioning and property options. To define these options efficiently, PaxExam provides a fluent API, which is provided in the
org.ops4j.pax.exam.CoreOptions
class.- Provisioning optionsThese options are used to provision bundles to the OSGI framework under test. Two options provision a single bundle and one option can provision a group of related bundles.
bundle()
Usingbundle()
, you can provision a bundle from any kind of URL supported by Pax URL. This includes the standard http: and file: protocols and some specialized protocols for grouping bundles, scanning directories, and other useful things.mavenBundle()
UsingmavenBundle()
, you can specify a bundle by its Maven coordinates. The bundle will be provisioned to the test container from a local or remote maven repository using the standard Maven lookup and caching procedures.junitBundle()
UsingjunitBundle()
, you can provision JUnit and its dependencies as OSGI bundles to the test container.
- Property optionsProperty options are used to set system properties, OSGi framework properties, and VM properties for a forked Java Virtual Machine, as applicable. Some useful options are:
composite
Groups multiple options into a single option. This is useful for building your own option methods.public static Option baseBundles() { return combine( mavenBundle("com.example.foo", "common", "1.0.0"), mavenBundle("com.example.foo", "util", "1.0.0")); }
systemProperty
Sets a system property in the framework VM. For native containers, this amounts to invokingSystem.setProperty()
in the running VM, which may or may not produce the same effect as a-Dkey=value
argument for some properties defined in the JRE API.systemProperty("org.osgi.service.http.port").value("8080"), systemProperty("org.osgi.service.http.secure").value("8443")
NoteFor details, see Pax Exam Configuration Options.
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.11</junit-version> <pax-exam-version>3.5.0</pax-exam-version> <felix.karaf.version>2.4.0</felix.karaf.version> ... </properties> <dependencies> <!-- Pax-Exam dependencies --> <dependency> <groupId>org.ops4j.pax.exam</groupId> <artifactId>pax-exam-container-karaf</artifactId> <version>${pax.exam.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.ops4j.pax.exam</groupId> <artifactId>pax-exam-junit4</artifactId> <version>${pax.exam.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.ops4j.pax.exam</groupId> <artifactId>pax-exam</artifactId> <version>${pax.exam.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.ops4j.pax.url</groupId> <artifactId>pax-url-aether</artifactId> <version>1.6.0</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> <scope>test</scope> </dependency> <!-- JUnit dependencies --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${felix.karaf.version}</version> <scope>test</scope> </dependency> <!-- Apache Karaf integration --> <dependency> <groupId>org.ops4j.pax.exam.karaf</groupId> <artifactId>org.ops4j.pax.exam.karaf.testing</artifactId> <version>${felix.karaf.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.ops4j.pax.exam.karaf</groupId> <artifactId>org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features</artifactId> <version>${felix.karaf.version}</version> <scope>test</scope> </dependency> </dependencies> ... <build> <plugins> <plugin> <groupId>org.apache.servicemix.tooling</groupId> <artifactId>depends-maven-plugin</artifactId> <version>1.2</version> <executions> <execution> <id>generate-depends-fil<</id> <goals> <goal>generate-depends-file</goal> </goals> </execution> </executions> </plugin> </plugins> </build> ... </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:
- JUnit 4 testing framework on the JUnit Web site.
- The Pax-Exam reference guide on the Pax-Exam Web site.
- Source code for the sample FeatureTest class.