📜 ⬆️ ⬇️

Automate Java EE Testing Web Services with SoapUI and Arquillian

One of the advantages of web services is the relative ease of testing. Indeed, in the simplest case, all we need to check the operation of the web service is to send a well-formed HTTP request in any convenient way and check what came back. With the help of SoapUI - a tool for all kinds of web services testing (more details about the features can be found on the official website ) - this process can be made even more convenient by automating it: we can create a test suite, specifying which requests should be sent, and specifying a set of rules that must be answered by the responses from the service. But, nevertheless, we still have to run these tests with our hands, and the soul craves for complete automation. Indeed, why not run these tests automatically when building the application (on the CI server or directly on the developer’s machine)?

Disclaimer
If you are a guru of web services and Java EE development, then surely a lot of things in this article will seem obvious to you, but I couldn’t find in the public time complete instructions on how to do this, and the information (often outdated) had to be collected in parts from different articles and manuals. Therefore, I decided to combine everything within this article.

Possible alternatives


Before attempting to automate the launch of SoapUI tests, let's see what alternatives we have. And there are at least two of them (perhaps, some of them will be more suitable for you than what will be described later in the article):
  1. If your service is part-time EJB-bin, which is quite reasonable, then you can test the method call of the bin corresponding to the operation of the web service. The advantages of this approach are relative simplicity (working with familiar java-objects, the absence of an extra entity in the form of SoapUI) and the fact that we have access to transaction management (we can open a transaction at the beginning of the test and roll back upon completion and thus always have “Clean” test database). The disadvantages include the fact that in this case such stages of the service operation are not covered, such as mapping data from XML to DTO and back, where errors may also occur.
  2. You can generate client classes for a web service and implement sending requests and validating results directly in java-code. In principle, for functional tests this is a good alternative to SoapUI, perhaps somewhat less declarative.

Closer to the point


We will use Maven as a build and project management system and JUnit as a testing framework, and our application will run on the WildFly server. Although this is not so important: the same could be done using TestNG and some other more or less common application server.

Experimental


So, first we will write a simple service, which, in fact, we will test:

@WebService(name = "Greeter", serviceName = "Greeter", portName = "Greeter", targetNamespace = "my/namespace") public class Greeter { @WebMethod public String hello(String name) { return "Hello, " + name; } } 

SoapUI


Next, we will create a project in SoapUI and add a test there that will check that if we transfer the hello operations of our web service to “world”, it will return “Hello, world” to us. We will not go into the details of this process, since information on this topic is easily found on the network, for example, on the official website of SoapUI ( here and here ).
')
image

After that, let's not forget to save the SoapUI project with the name Greeter-soapui-project.xml to the folder with the test resources of our main project.

Arquillian and JUnit


Now the most interesting thing: you need to make sure that during the assembly, at the testing stage, our service is deployed to the application server, and after that the SoapUI tests we created earlier were launched. With this, Arquillian will help us - a great framework designed to make testing Java EE applications a bit more pleasant (you can get acquainted with the Getting Started Guide on the official website).

Add dependencies for this whole zoo to our pom-file:

  <repositories> <repository> <id>soapui</id> <url>http://www.soapui.org/repository/maven2</url> </repository> </repositories> <dependencyManagement> <dependencies> <!-- BOM      Arquillian --> <dependency> <groupId>org.jboss.arquillian</groupId> <artifactId>arquillian-bom</artifactId> <version>1.1.8.Final</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement> <dependencies> ... <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!--    Arquillian  JUnit.          TestNG --> <dependency> <groupId>org.jboss.arquillian.junit</groupId> <artifactId>arquillian-junit-container</artifactId> <scope>test</scope> </dependency> <!-- Arquillian-    WildFly-9.0.1.Final.      , ,    ,       --> <dependency> <groupId>org.wildfly.arquillian</groupId> <artifactId>wildfly-arquillian-container-managed</artifactId> <version>1.0.1.Final</version> <scope>test</scope> </dependency> <!--   SoapUI     SoapUI- --> <dependency> <groupId>com.smartbear.soapui</groupId> <artifactId>soapui</artifactId> <version>5.1.3</version> <scope>test</scope> </dependency> </dependencies> 

We should also mention adapters for containers / application servers. A more or less complete list of adapters is available on the project wiki , where you can also see what configuration parameters there are for each individual adapter. However, this list does not seem to be supported (the last change was in August 2014), so information about adapters for more recent versions of containers should be searched for separately. In general, all adapters can be divided into three classes:

Managed containers are most useful in CI environments, because

Therefore we will stop the choice on managed option of the adapter. But, in addition to the CI environment, we want to run tests on the developers' machines, where the server can be started even before the tests start. By default, Arquillian will swear that the container is already running, and to calm it down, we need to set the parameter to allowConnectingToRunningServer to true, to do this, create the configuration file arquillian.xml with the following content in the folder with test resources:

 <?xml version="1.0" encoding="UTF-8"?> <arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.org/schema/arquillian http://www.jboss.org/schema/arquillian/arquillian_1_0.xsd"> <container qualifier="jbossas" default="true"> <configuration> <property name="allowConnectingToRunningServer">true</property> </configuration> </container> </arquillian> 

To start the server, Arquillian needs to know the path to the WildFly installation. By default, it is taken from the JBOSS_HOME environment variable (but it can be overridden in arquillian.xml), so let's not forget to give it the desired value.

Now that we have specified all the dependencies and configured Arquillian, we can finally move on to writing a test class that will do all the work:

 //  Arquillian   JUnit  @RunWith(Arquillian.class) public class GreeterIT { /* ,   Deployment,  ,  Arquillian       .      ,      .       ,      ,   testable  false. */ @Deployment(testable = false) public static Archive<?> createDeployment() { /* ShrinkWrap    ,   ,    ,    . ,  ,  (      )     ,       ,   Maven-. */ return ShrinkWrap.createFromZipFile(WebArchive.class, new File("target/ws-autotesting.war")); } @Test public void testGreeter() throws Exception { SoapUITestCaseRunner runner = new SoapUITestCaseRunner(); //  SoapUI     runner.setProjectFile("src/test/resources/Greeter-soapui-project.xml"); //       JUnit runner.setJUnitReport(true); //       runner.setPrintReport(true); //         failsafe  runner.setOutputFolder("target/failsafe-reports"); runner.run(); } } 

It should be noted that in the SoapUI project we have specified localhost as a host, and the web service will be transferred to the local managed server during the tests, so everything will work correctly. But if we deployed to a remote server, we would need to redefine the address to which SoapUI should send requests. In this case, the testGreeter method would look like this:

 @Test public void testGreeter(@ArquillianResource URL serverUrl) throws Exception { ... runner.setHost(serverUrl.getHost() + ":" + serverUrl.getPort()); ... } 

Failsafe


All that's left is to set up Maven so that it can run the tests during the build process. With this, the Failsafe plugin will help us. The name of our test class ends with “IT”, which corresponds to the convention of naming integration tests launched by Failsafe, so it only remains to configure the plugin in our pom-file:

 <properties> <skipITs>true</skipITs> </properties> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>2.18.1</version> <configuration> <!--   ,     VM --> <forkCount>1</forkCount> <reuseForks>false</reuseForks> <redirectTestOutputToFile>false</redirectTestOutputToFile> <!--    ,      it (..      )--> <skipITs>${skipITs}</skipITs> </configuration> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin> ... </plugins> </build> <profiles> <profile> <id>it</id> <properties> <skipITs>false</skipITs> </properties> </profile> </profiles> 

That's all!


Now Maven will automatically run tests in the CI environment when building with the it profile, and developers can enjoy the green bar view in their favorite IDE.



All source codes from article can be found on github .

Source: https://habr.com/ru/post/267301/


All Articles