Step 3: Provide a Mechanism to Pass Back Test Results.
When you execute
TestSuites and
TestCases, JUnit stores the results inside a special JUnit class called
TestResult. Unfortunately, this class isn't serializable and it is tailored for JUnit test runners to use. In order to pass the results outside the container, you have to define an analogous object or DTO (Sun BluePrints) for transferring the result data to the client.
Define a DTO class called TestResultCollection for storing test results. Provide a constructor to initialize a TestResultCollection from a JUnit TestResult instance:
public class TestResultCollection implements Serializable {
protected List failures;
protected List errors;
protected int runCount;
public TestResultCollection(TestResult result) {
failures = new ArrayList();
errors = new ArrayList();
copyResult(result);
}
protected void copyResult(TestResult result) {
runCount = result.runCount();
Enumeration enum = result.errors();
while(enum.hasMoreElements()) {
TestFailure tf = (TestFailure) enum.nextElement();
errors.add(tf.toString());
}
enum = result.failures();
while(enum.hasMoreElements()) {
TestFailure tf = (TestFailure) enum.nextElement();
failures.add(tf.toString());
}
}
}
Add the logic to your TestService to execute the JUnit TestSuite and return the results inside a TestResultCollection object:
public TestResultCollection executeTest(String testClass, Map params) {
try {
// initialise context
ApplicationContext.get().putAll(params);
// Create Test
TestSuite suite = loadTestSuite(testClass);
// Execute test
TestResult result = new TestResult();
suite.run(result);
// Copy results into serialisable collection
return new TestResultCollection(result);
} finally {
ApplicationContext.close();
}
}
Step 4: Wrap Your Test Service Inside an EJB.
You now have a working test service that can be embedded inside your server. The last step is to wrap and expose your test functionality using an EJB that the remote clients can access.
Create a stateless session bean called EjbTestRunnerBean. Define one public remote method called executeTest() for executing unit tests. This method is very similar to your existing TestService::executeTest() method with one difference: it has a parameter called teardown for controlling test data removal.
Inside your executeTest() method, instantiate and delegate test execution to your TestService:
public abstract class EjbTestRunnerBean implements javax.ejb.SessionBean {
public TestResultCollection executeTest(String testClass, Map params,
boolean tearDown) {
TestService service = new TestService();
TestResultCollection results = service.executeTest(testClass, params);
...
return results;
}