Unitils SoapUI Module

This module integrates soapUI into a jUnit test. Because of this integration you can use the full stack of features of Unitils when you use its runner.

SoapUI Module load artifact (maven)

    <dependency>
        <groupId>org.unitils.soapui</groupId>
        <artifactId>unitils-soapui</artifactId>
        <version>1.0.0</version>
    </dependency>

This module uses SoapUI 4.5.1, but you can also use SoapUI 3.5.
If you want to use SoapUI 3.5, you have to change the dependencies. You have to exclude the soapui & httpclient dependency from the unitils-soapui module and add commons-httpclient:3.1 & soapui:3.5.1

<dependency>
  <groupId>org.unitils.soapui</groupId>
  <artifactId>unitils-soapui</artifactId>
  <version>1.0.0</version>
  <exclusions>
    <exclusion>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
    </exclusion>
    <exclusion>
      <groupId>eviware</groupId>
      <artifactId>soapui</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>commons-httpclient</groupId>
  <artifactId>commons-httpclient</artifactId>
  <version>3.1</version>
</dependency>
<dependency>
  <groupId>eviware</groupId>
  <artifactId>soapui</artifactId>
  <version>3.5.1</version>
</dependency>

SoapUI Module project config

unitils.modules = ...., soapui, ...

unitils.module.soapui.className = org.unitils.soapui.WebserviceModule  
unitils.module.soapui.runAfter=  
unitils.module.soapui.enabled=true

org.unitils.soapui.default.project.file = ???  
org.unitils.soapui.default.project.suite = ???  
org.unitils.soapui.default.project.endpoint = ???  
org.unitils.soapui.default.cleanup = ???

How does a test work?


Before we explain the lifecycle of the test maybe a good question: Is it the
responsiblity of the test to deploy the webservice? Well the answer is no, use
maven (or ant) to deploy the webservice.
So the webservice is deployed and ready to be tested.
When writing a test we can talk about 3 phases: setup, call System Under Test, verify

To be correct we should add a fourth phase: cleanup.

setup:
In the setup phase we set our SUT and the systems it uses in a known state. We
prepare them to be used afterwards. One of the most common things are database
setup and loading data in database.
call SUT:
In this phase we will use our client / tool to create and post a request to
the webservice.
verify:
After calling the webservice we could do some assertions on the response but we
could also check other things of our SUT, like the state of the database. This
is done in the verification phase.

Combining Unitils, SoapUI and jUnit.

@RunWith(UnitilsJUnit4TestClassRunner.class)
public class SimplePlatformIntegrationConsumerTest {

    @WebserviceTestSoapUi(testCase = "checkAccessControl TestCase")
    private WebserviceTest ws;

    @Test    
    public void checkAccessControl() {
        ws.triggerTestCase();
    }
}

First we define a WebserviceTest
property which will hold the configuration of the soapui testcases we want to
run. This property we have to annotate with @WebserviceTestSoapUi which has four values that you can set.

testCase:
the soapUi name of the testcase that you want to run. This has no default value
suite:
the soapUi name of the suite where the testcase resides. If no value is specified the one you defined in the property file will be taken.
endpoint:
the location for accessing the webservice. If no value is specified the one you defined in the property file will be taken.
projectFile:
the location of the soapUI project file. If no value is specified the one you defined in the property file will be taken. This is a file where SoapUI saves your soap project/testcases/testsuites.

If you want to run a lot of testcases in your testclass, than you will have to define a lot of WebserviceTest.

@WebserviceTestSoapUi(testCase = "checkAccessControl1 TestCase")
private WebserviceTest ws1;

@WebserviceTestSoapUi(testCase = "checkAccessControl2 TestCase")
private WebserviceTest ws2;

@WebserviceTestSoapUi(testCase = "checkAccessControl3 TestCase")
private WebserviceTest ws3;

//....

@Test    
public void checkAccessControl1() {
    ws1.triggerTestCase();
}
@Test    
public void checkAccessControl2() {
    ws2.triggerTestCase();
}
@Test    
public void checkAccessControl3() {
    ws3.triggerTestCase();
}

Although this approach works you'll remark a performance drawback. For every
test all WebserviceTest are recreated and this is a time consuming
process.

To solve this problem you can use the @WebserviceTestPlaceHolder on
the WebserviceTest and put your WebserviceTestSoapUi
configuration on the testmethod itself. This way only the webservicetest you need for
the test you want to run is configured, not the other ones.

@WebserviceTestPlaceHolder
private WebserviceTest ws;

//....

@Test  
@WebserviceTestSoapUi(testCase = "checkAccessControl1 TestCase")  
public void checkAccessControl1() {
    ws1.triggerTestCase();
}
@Test
@WebserviceTestSoapUi(testCase = "checkAccessControl2 TestCase")    
public void checkAccessControl2() {
    ws2.triggerTestCase();
}
@Test    
@WebserviceTestSoapUi(testCase = "checkAccessControl3 TestCase")
public void checkAccessControl3() {
    ws3.triggerTestCase();
}

Multiple endpoints:
Often you want to run the same test, or another test, against different endpoints on the same host.
This is done by stripping the last part of the endpoint (org.unitils.soapui.default.project.endpoint)
and adding it in the WebserviceTestSoapUi annotation. This will allow you to
test different versions or multiple endpoints on the same server.

@RunWith(UnitilsJUnit4TestClassRunner.class) 
public class PlatformIntegrationConsumerTest {

    @WebserviceTestPlaceHolder
    private WebserviceTest ws;

    @Test
@WebserviceTestSoapUi(testCase = "checkAccessControl TestCase",  endPointPostfix = "v1")
    public void checkAccessControlOtherEndpointV1() {
        ws.triggerTestCase();
    }

    @Test
    @WebserviceTestSoapUi(testCase = "checkAccessControl TestCase", endPointPostfix = "v2")
    public void checkAccessControlOtherEndpointV2() {
        ws.triggerTestCase();
    }
}
 

Last edit: Willemijn Wouters 2013-11-06