Steve Chambers Steve Chambers - 26 days ago 17
Java Question

How to write automated acceptance tests for a Maven project packaged as a WAR file?

I've been given the source code for an existing Java application (let's call it "WebApp") that needs to be tested . It's deployed into Glassfish as a WAR file. This is customer code so would like to avoid modifying the WebApp POM if I can help it.

So I'm creating a separate project (in Eclipse) to do the testing. The new project needs to call methods directly on various WebApp classes. I tried referencing the WAR file as a Maven Dependency but after doing this it doesn't show up in Maven Dependencies in Eclipse - see below:

WebApp
src/main/java
...
pom.xml

WebAppTest
src/main/test
test.package.name
webAppAcceptanceTestIT.java
Maven Dependencies
junit-4.6.jar
mockito-all-1.9.5.jar
<<< No WebApp war/jars here >>>


The dependency in WebAppTest's pom looks like:

<dependency>
<groupId>...</groupId>
<artifactId>webapp</artifactid>
<version>...</version>
<type>war</type>
<scope>compile</scope>
</dependency>


Have tried
type=jar
and
scope=test
instead but neither of these is hitting the mark. Not sure if I'm missing something or going about this the wrong way? Should I maybe be using Maven Modules instead? Don't want to over-complicate things. Of course I can cheat and add WebApp to WebAppTest's build path but I want to get this right so it works when it deploys.

One other q - should WebAppTest be packaged as a WAR or JAR? It will only contain tests that execute WebApp code and check results. Am I right in thinking it would still need to be deployed into Glassfish as a WAR file?

Answer

You have several options, in decreasing order of preference:

Use HTTP (only) for acceptance testing

Deploy the war, fire HTTP requests at it, check the database separately. No access needed to the webapp's classes. This is the cleanest option and most maintainable.

In-container testing

Use Arquillian to deploy the application along with your tests and run them. You would need to add attachClasses to maven-war-plugin's config in the POM of the original war. Your Test project needs to depend on [artifactid]-classes instead of artifactid. Your tests run within Glassfish (Arquillian deals with starting up Glassfish and deploying the war).

Arquillian has a bit of learning curve.

Expose the WebApp classes remotely

Use something like Spring's HTTPInvoker to expose the classes you want to test to your test code. Your tests run in a separate JVM to Glassfish, and connect to the classes under test using HTTP. You still need to change the POM like in the in-container case. This might be tricky if your WAR isn't Spring-based, and is quite invasive to the original application. You may also run into problems with serialization.