Black Pepper Blog

The thoughts and musings of our team


I've written in an earlier blog entry about writing acceptance tests in Java for a Flex front ended web app, using Selenium RC. Here I'll describe how we added those tests to our continuous integration build, using a Hudson job as part of our build-and-deploy pipeline.

Our web app comprises two components, a Java server-side component and a Flex client-side component. The Java component is built by a Hudson job as a war file. The Flex component is built by another Hudson job as a zip file. These two Hudson jobs are independent, fairly standard projects built by Ant, each with its own set of unit tests. To run acceptance tests, we need both components to be deployed into the target environment. We created a third Hudson job which aims to deploy the latest artifacts from the Java and Flex jobs, start up Tomcat and Selenium, run the acceptance test suite, and shut down Tomcat and Selenium. This Hudson job depends on the other two jobs and its build is activated when either of those two completes.

As we are already using Ant to control the two component builds, and our acceptance tests are written in Java, we decided to use the Ant build for the Java component as the home for the acceptance test build. Here's the target to run the acceptance tests in the Hudson CI environment:

 
<target name="acc-test-ci"
   depends="compile-acctests, create-acctest-schema, load-ref-data, deploy-ci, selenium-start, run-acc-tests"
   description="Run acceptance tests against the most recent good build from Hudson">
</target>
 

The task depends on targets to compile the acceptance tests, create the test database schema, load reference data, download and deploy the CI builds of the Java and Flex artifacts, start up Selenium RC, and finally run the acceptance test suite. Here's the deploy-ci task:

 
<target name="deploy-ci" 
   description="Download latest builds from Hudson, deploy into Tomcat and start Tomcat" 
   depends="get-latest-build, deploy, tomcat-start">
</target>
 

The run-acc-tests task runs the acceptance test suite of Selenium/JUnit tests against the deployed artifacts and finishes by shutting down tomcat and Selenium-RC.

There were one or two wrinkles which we had to iron out before our Hudson dashboard showed a happy sun.

  1. Selenium needs a display, but Hudson is running on a headless server.
  2. Other builds or processes run Selenium servers; there was port contention.
  3. Similarly, other builds or processes run Tomcat; there was port contention.
  4. Acceptance tests ran but failed with diagnostics like "window.document.MyFlexApp has no properties".

Solutions we used were:

  1. We configured the Hudson job with "Run Xvnc during build".
  2. We chose a port for the Selenium server that doesn't clash with any other server. We did this in the ant task that starts Selenium:
     
    <target name="selenium-start">
       <java jar="${dir.lib.acceptance}/selenium-server.jar" spawn="true" fork="true">
          <arg line="-port ${selenium.port}"/>
     
  3. Similarly, we chose a non-clashing port for Tomcat.
  4. We realized that our app has a Flex front-end but the browser installed on the Hudson box and used for the Selenium tests did not have a Flash plug-in installed. So the Flex application object was never initialized. Once we'd installed the plug-in, the acceptance tests started passing. Doh!

Comments (2)Add Comment
Sanjeev
April 16, 2009
216.113.168.141
Votes: +0
...

Hi,

Could you please elaborate more on issue #1 (Selenium needs a display, but Hudson is running on a headless server.)?

We have a hudson instance running on a Windows box. Is it possible to do headless build on windows using Selenium?

Thanks,
Sanjeev

Julia Dain
May 12, 2009
78.86.232.161
Votes: +0
...

I'm sorry I can't help on Windows. Maybe someone over at the Hudson wiki http://wiki.hudson-ci.org/display/HUDSON/Home could help.

Write comment
 
  smaller | bigger
 

security image
Write the displayed characters


busy