Skip Tests with PAX-Exam

First, let me explain what I had and what I wanted to do.
I had integration tests for an OSGi application I work on. These tests involved Apache Karaf, PAX-Exam and an external messaging server. On my continuous integration server, the messaging server is installed and can thus run these tests. However, when new developers try to compile locally, these tests may fail because the messaging server is not installed or not running. And what I wanted to do was PAX to skip these tests. Not just skip the methods, but also skip the test classes. Indeed, the errors were not in my test methods, but when PAX installed my bundles in the OSGi framework. Some of these bundles tried to connect to the messaging server, and it resulted in errors.

I tried to use the JUnit method Assume.assume… but depending where it was used, it was either useless (in the test methods, the environment was already set up) or it was resulting in an error in the tests. I also searched for some kind of PAX specific methods to handle this use case, but I did not find any.

Anyway, I finally found a solution by implementing my own test runner. Or, more exactly, I extended PAX’s runner (the PaxExam class) and performed my environment checks in it. Here is the code…

import org.junit.runner.Description;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.model.InitializationError;
import org.ops4j.pax.exam.junit.PaxExam;

public class RoboconfPaxRunner extends PaxExam {

	private final Class<?> testClass;

	public RoboconfPaxRunner( Class<?> klass ) throws InitializationError {
		super( klass );
		this.testClass = klass;
	}


	@Override
	public void run( RunNotifier notifier ) {

		if( ! IntegrationTestsUtils.rabbitMqIsRunning()) {
			Description description = Description.createSuiteDescription( this.testClass );
			notifier.fireTestAssumptionFailed( new Failure( description, new Exception( "RabbitMQ is not running." )));

		} else {
			super.run( notifier );
		}
	}
}

For the classes that needs the messaging server, I only have one annotation to add.

@RunWith( RoboconfPaxRunner.class )
@ExamReactorStrategy( PerClass.class )
public class AgentTerminationTest extends DmWithAgentInMemoryTest {
	// ...
}

It works very well, in both Eclipse and Maven.
And it remains quite simple to manage.


About this entry