Tags

,

I’m using JUnit 4.0 in tandem with SoapUI4.0, not just for unit tests, but also for integration or conformance tests. Typically, we iterate over all test cases of a given test suite in a soapUI project and validate each test case.

parallel processing

parallel processing

One article that really inspired me to write this blog is located here: http://hwellmann.blogspot.com/2009/12/running-parameterized-junit-tests-in.html
As soapUI tests are not heavily relying on CPU power on the client machine the increase of performance is significant when running tests in parallel. If running hundreds of such test the performance can increase hundreds of times. This is just a rough estimate and nothing is set in stone.

So, enough with empty words and let’s see how things are working:

Parameterized tests
Structure of a parameterized test class
To mark a test class as a parameterized test, you must first annotate it with @RunWith(Parameterized.class). The class must then provide at least three entities:

1. A static method that generates and returns test data,
2. A single constructor that stores the test data, and
3. A test

In our case instead of using the @RunWith(Parameterized.class) we are going to use the @RunWith(Parallelized.class)without changing anything else in the actual parameterized class. Actually to test the performance is good to have both declarations in the header and comment them alternatively before running the test cases to measure the performance.
So, use the below class as is without making any changes and place the class into the same package as your JUnit test class. Eventually you can change the number of threads from 16 to another number.

public class Parallelized extends Parameterized
{
    
    private static class ThreadPoolScheduler implements RunnerScheduler
    {
        private ExecutorService executor; 
        
        public ThreadPoolScheduler()
        {
            String threads = System.getProperty("junit.parallel.threads", "16");
            int numThreads = Integer.parseInt(threads);
            executor = Executors.newFixedThreadPool(numThreads);
        }
        
        @Override
        public void finished()
        {
            executor.shutdown();
            try
            {
                executor.awaitTermination(10, TimeUnit.MINUTES);
            }
            catch (InterruptedException exc)
            {
                throw new RuntimeException(exc);
            }
        }

        @Override
        public void schedule(Runnable childStatement)
        {
            executor.submit(childStatement);
        }
    }

    public Parallelized(Class klass) throws Throwable
    {
        super(klass);
        setScheduler(new ThreadPoolScheduler());
    }
}

Now the JUnit test class will look something like this:

import static org.junit.Assert.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.xmlbeans.XmlException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.model.support.PropertiesMap;
import com.eviware.soapui.model.testsuite.TestCase;
import com.eviware.soapui.model.testsuite.TestRunner;
import com.eviware.soapui.model.testsuite.TestRunner.Status;
import com.eviware.soapui.model.testsuite.TestSuite;
import com.eviware.soapui.support.SoapUIException;

@RunWith(value = Parameterized.class)
//@RunWith(Parallelized.class)
public class soapUITest { // This is the parameter for each instance of the test.
    private TestSuite suite;

    public soapUITest(TestSuite suite) {
	this.suite = suite;
    }

    @Parameters
    public static Collection getParameters() throws XmlException, IOException, SoapUIException {
	WsdlProject project = new WsdlProject("c://Projects//QA//sometest.xml");
	Collection testSuites = project.getTestSuiteList();
	
	Collection parameters = new ArrayList(testSuites.size());
	for (TestSuite suite : testSuites) {
	    parameters.add(new Object[] {suite});
	 }
	 return parameters;
    }

    @Test
    public void testOneTestSuite() {
	List testCases = suite.getTestCaseList();
		for (TestCase testCase : testCases) {
		    System.out.println("Running SoapUI test [" + testCase.getName() + "]");
		    TestRunner runner2 = testCase.run(new PropertiesMap(), false);
		    assertEquals(Status.FINISHED, runner2.getStatus());
    }
}
Advertisements