Arvind's Arena

I want to know God's thoughts… the rest are details. Albert Einstein

An integration testing framework for Java EE

leave a comment »

I am part of a team that is handling the migration of old code base to JEE6. The existing Architecture is monolith and complex one, the components are very tightly coupled because of which the project teams generally have great difficulty in managing and writing Test Cases. Unit tests alone aren’t sufficient to guarantee a component’s behavior. Though every project for long term success and maintainability would need a well defined, comprehensive Test Bed but it was not easy to find a Remote, Embedded and Managed container to test the components.

  Arquillian is an Integration Testing Framework for JEE6, it allows the developer to execute tests within the container, deployed alongside the code or by speaking with the container, acting as a client to the packaged code. Arquillian ensures the developer is not locked into a proprietary environment by making the model a pluggable one. With Arquillian we can actually test managed beans provided through dependency injection.

Well, it does sound very interesting doesn’t it? Sadly the documentation is not good enough. I have had terrible experiences in the past when I was working in JBPM.Things haven’t changed over the years as far as the documentation is concerned. Let me try to knit all the missing pieces which I had to hunt in various forums.

I always prefer to use Netbeans from the days of Maven 1.0. Once Maven(2 or 3 ) Web Project is created, the below dependencies are needed.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>org.jcc</groupId>
 <artifactId>ArqullianEJBDemo</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>jar</packaging>
 <name>Arqullian EJB Test Demo</name>
 <url>http://maven.apache.org</url>
 <properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 <arquillian.version>1.0.0.CR5</arquillian.version>
 <shrinkwrap.version>1.0.0-beta-5</shrinkwrap.version>
 <shrinkwrap_descriptor.version>1.1.0-beta-1</shrinkwrap_descriptor.version>
 </properties>
 <pluginRepositories>
 <pluginRepository>
 <id>jboss-public-repository-group</id>
 <name>JBoss Public Repository Group</name>
 <url>http://repository.jboss.org/nexus/content/groups/public/</url>
 <layout>default</layout>
 </pluginRepository>
 </pluginRepositories>

 <build>
 <plugins>
 <plugin>
 <artifactId>maven-compiler-plugin</artifactId>
 <configuration>
 <source>1.6</source>
 <target>1.6</target>
 </configuration>
 </plugin>
 </plugins>
 </build>

 <dependencies>
 <dependency>
 <groupId>javax.ejb</groupId>
 <artifactId>ejb-api</artifactId>
 <version>3.0</version>
 <optional>false</optional>
 </dependency>
 <dependency>
 <groupId>javax.enterprise</groupId>
 <artifactId>cdi-api</artifactId>
 <version>1.0-SP1</version>
 <optional>false</optional>
 </dependency>
 <dependency>
 <groupId>org.jboss.arquillian.junit</groupId>
 <artifactId>arquillian-junit-container</artifactId>
 <version>${arquillian.version}</version>
 <scope>test</scope>
 <optional>false</optional>
 </dependency>
 <dependency>
 <groupId>org.jboss.shrinkwrap.descriptors</groupId>
 <artifactId>shrinkwrap-descriptors-api</artifactId>
 <version>${shrinkwrap_descriptor.version}</version>
 <scope>test</scope>
 <optional>false</optional>
 </dependency>
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>4.8.1</version>
 <scope>test</scope>
 <optional>false</optional>
 </dependency>
 </dependencies>

 <profiles>
 <profile>
 <id>jbossas-remote-6</id>
 <dependencies>
 <dependency>
 <groupId>org.jboss.arquillian.container</groupId>
 <artifactId>arquillian-jbossas-remote-6</artifactId>
 <version>1.0.0.CR2</version>
 <scope>test</scope>
 </dependency>
 <dependency>
 <groupId>org.jboss.jbossas</groupId>
 <artifactId>jboss-as-client</artifactId>
 <version>6.0.0.Final</version>
 <type>pom</type>
 </dependency>
 </dependencies>
 </profile>
 </profiles>

 <repositories>
 <!-- other repos here -->
 <repository>
 <id>jboss-public-repository-group</id>
 <name>JBoss Public Repository Group</name>
 <url>http://repository.jboss.org/nexus/content/groups/public/</url>
 <layout>default</layout>
 </repository>
 <repository>
 <releases>
 <enabled>true</enabled>
 </releases>
 <snapshots>
 <enabled>false</enabled>
 </snapshots>
 <id>jboss-central</id>
 <name>JBoss Central</name>
 <url>https://repository.jboss.org/nexus/content/repositories/central/</url>
 <layout>default</layout>
 </repository>
 <repository>
 <releases>
 <enabled>true</enabled>
 </releases>
 <snapshots>
 <enabled>false</enabled>
 </snapshots>
 <id>jboss-deprecated</id>
 <name>JBoss Deprecated</name>
 <url>https://repository.jboss.org/nexus/content/repositories/deprecated/</url>
 <layout>default</layout>
 </repository>
 <repository>
 <releases>
 <enabled>true</enabled>
 </releases>
 <snapshots>
 <enabled>false</enabled>
 </snapshots>
 <id>jboss-public</id>
 <name>JBoss Public</name>
 <url>https://repository.jboss.org/nexus/content/repositories/public-jboss/</url>
 <layout>default</layout>
 </repository>

 </repositories>

</project>

The official documentation   uses Arqullian version 1.0.0.CR1 (also another doc uses 1.0.0Alpha5),  and there is no detail on shrinkwrap version and its dependencies.
I used the same TemperatureConverter Java Code and annotated it as a Stateless Session Bean.


@Stateless
public class TemperatureConverterBean implements TemperatureConverter {
	@Resource
	EJBContext ctx;

	public double convertToCelsius(double f) {
		return ((f - 32) * 5 / 9);
	}

	public double convertToFarenheit(double c) {
		return ((c * 9 / 5) + 32);
	}

}

Arquillian works with both JUnit and TestNG versions, in my demo I used JUnit4. When the Arquillian test runner processes a test class, the first thing it does is retrieve the definition of the Java archive from the @Deployment method, appends the test class to the archive and packages the archive using ShrinkWrap.

import javax.ejb.EJB;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(Arquillian.class)
public class TemperatureConverterTest {

	@Deployment
	public static JavaArchive createTestArchive() {
		return ShrinkWrap.create(JavaArchive.class, "test.jar").addClasses(TemperatureConverter.class, TemperatureConverterBean.class);
	}

	@EJB
	private TemperatureConverter converter;

	@Test
	public void testConvertToCelsius() {
		Assert.assertEquals(converter.convertToCelsius(212d), 100d, 0.9);
	}

}

Before executing, we need to define connection parameters for JBoss AS6,the documentation says that we need to use jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=jnp://127.0.0.1:1099

but it didnt work for me, I added Arquillian.xml in src/test/resources

<?xml version="1.0" encoding="UTF-8"?>
<arquillian xmlns="http://jboss.com/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">

   <container qualifier="jbossas-remote-6" default="true">
	 <configuration>
	 	<property name="providerUrl">jnp://127.0.0.1:1099</property>
	 </configuration>
	 <protocol type="Servlet 3.0">
	 	<property name="host">127.0.0.1</property>
	 	<property name="port">8080</property>
	 </protocol>
 </container>
 

   
    
</arquillian>

To run your code from command line, just use
mvn test -Pjbossas-remote-6

for netbeans select the jbossas-remote-6 profile in the main toolbar.

But once the setup was ready, testing EJB, CDI from  the command line or netbeans is very easy.

Advertisements

Written by Arvind A

December 7, 2011 at 6:04 pm

Posted in Rendezvous with Technology

Tagged with , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: