Pages

Tuesday, February 21, 2012

Integration tests made easy with Arquillian


Wikipedia defines Integration testing as follows

"Integration testing (sometimes called Integration and Testing, abbreviated "I&T") is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing"

It should be clear by now the purpose of integration testing is way different from Unit testing.

Arquillian makes it really easy to write integration tests by handling the following
  • Manages the lifecycle of the container (start/stop),
  • Bundles the test class with dependent classes and resources into a deployable archive,
  • Enriches the test class (e.g., resolving @Inject, @EJB and @Resource injections),
  • Deploys the archive to test (deploy/undeploy) and
  • Captures results and failures.
The above said points were something that developers should handle so far with mock objects and embedded containers so far. With Arquillian the integration tests are as simple as writing straight forward unit tests. It also provides good integration with maven.

How it works?

1) Import arquillian dependencies

2) Configure arquillian using arquillian.xml - You will configure the containers and container properties like location, port and protocol of the jboss server for example

3) Annotate test as arquillian tests if using Junit or Extend org.jboss.arquillian.testng.Arquillian if using testng.

4) Prepare the archive containing the classes you are writing tests for - You should include all the referred classes and libraries also. You can prepare a JAR, WAR or EAR based on your needs. Remember you are building this archive on the fly using Shrinkwrap. You should annotate the method preparing the archive using  @Deployment

5) Execute tests- Arquillian will build the archive  in the beforesuite phase of test execution , deploy it based on the configuration in arquillian.xml , execute the tests in the container (because of this your eclipse debugging will have to setup differently to debug test case execution, will see that in a different post) and send you back the results.


Quick Startup guide:

I am using Maven, Jboss 7.0.2 (Arc) , JEE6 and TestNG for this example


Maven Integration

Add the following dependencies
<dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>6.1.1</version>
  <scope>test</scope>
 </dependency>
 <dependency>
  <groupId>org.jboss.arquillian.testng</groupId>
  <artifactId>arquillian-testng-container</artifactId>
  <version>1.0.0.CR7</version>
 </dependency>
 <dependency>
  <groupId>org.jboss.arquillian.protocol</groupId>
  <artifactId>arquillian-protocol-servlet</artifactId>
  <version>1.0.0.CR7</version>
  <scope>provided</scope>
 </dependency>
The following will start and stop the container of its own
 <dependency>
  <groupId>org.jboss.as</groupId>
  <artifactId>jboss-as-arquillian-container-managed</artifactId>
  <version>7.0.2.Final</version>
 </dependency>
or
The following will deploy and undeploy the testabke archive to the container that is already running
 <dependency>
  <groupId>org.jboss.as</groupId>
  <artifactId>jboss-as-arquillian-container-remote</artifactId>
  <version>7.0.2.Final</version>
 </dependency>


Arquillian.xml (Have this 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://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<defaultProtocol />
<container qualifier="jboss7" default="true">
    <configuration>
        <property>C:\DevTools\jboss-as-web-7.0.2.Final\jboss-as-web-7.0.2.Final</property>
    </configuration>
      <protocol>
            <property>REMOTE</property>
        </protocol>
   </container>
</arquillian>


Code snippets showing archive preparation

public abstract class AbstractTestServices extends Arquillian {
...
....
@Deployment(testable = true)
public static WebArchive createTestArchive() {
test = ShrinkWrap.create(WebArchive.class,"test.war").addClass(AbstractTestServices.class).addAsLibraries(servicesJar, entitiesJar);
return test;
}


Code Snippets of Integration test cases


public class PersonServiceTestIT extends AbstractTestServices {
@Inject private personService personService;
@Test
 public void shouldBeAbleToInjectEJB() throws Exception AssertJUnit.assertEquals(personService.dummyTestMethod(), true);  }

Maven will look for integration tests in the Integration-test phase, you should end your integration tests with the name IT for that to be identified as Integration test. Also remember to use Maven failsafe plug-in.

That’s it!!!

Further reading:
http://www.jboss.org/arquillian
http://maven.apache.org/plugins/maven-failsafe-plugin/
https://docs.jboss.org/author/display/ARQ/Complete+Container+Reference
https://docs.jboss.org/author/display/ARQ/Supported+containers
https://docs.jboss.org/author/display/ARQ/Introduction
http://www.jboss.org/shrinkwrap

3 comments:

  1. Testing our code with the real server instead of mock-up. This is what we called as integration testing?If so this will do the testing with the JBoss or any application server. Is that right?

    Is it possible to attach or provide the link of any working sample? So that we get to know more about it.

    ReplyDelete
  2. Yes you are right, you can use this to do testing with Jboss. The 3rd link in the further reading section will give you the list of containers you can use with Arquillian.

    I belive i have pretty much given everything you will need to write a sample in the Quick start up guide.

    ReplyDelete
  3. quite bit of lazy :)

    OK let me try on it...

    ReplyDelete