Over a million developers have joined DZone.

Faster Web Tests with Parallel Batches in Thucydides

DZone 's Guide to

Faster Web Tests with Parallel Batches in Thucydides

· Java Zone ·
Free Resource

Web tests are as a rule much slower than other types of tests, but they can be sped up significantly by running them in parallel. However, this is often harder to implement than it sounds. The latest version of Thucydides (version 0.6.0) comes with support for running parallel test batches, making this task much easier.

Web tests make good candidates for concurrent testing, in theory at least, but the implementation can be tricky. For example, although it is easy enough to configure both JUnit and easyb to run tests in parallel, running several webdriver instances of Firefox in parallel on the same display, for example, tends to become unreliable.

The natural solution in this case is to split the web tests into smaller batches, and to run each batch on a different machine and/or on a different virtual display. When each batch has finished, the results can be retrieved and aggregated into the final test reports.

However splitting tests into batches by hand tends to be tedious and unreliable – it is easy to forget to add a new test to a batch, for example, or have unevenly-distributed batches.

The latest version of Thucydides lets you do this automatically, by splitting your test cases evenly into batches of a given size. In practice, you run a build job for each batch. You need to specify two parameters when you run each build: the total number of batches being run (thucydides.batch.count), and the number of the batch being run in this build (thucydides.batch.number).

For example, the following will divide the test cases into 3 batches (“thucydides.batch.count”), and only run the first test in each batch (thucydides.batch.number):

mvn verify -Dthucydides.batch.count=3 -Dthucydides.batch.number=1

This will only work with the JUnit integration. However this feature is also now supported in easyb (as of easyb version 1.5), though using different parameters. When using the Thucydides easyb integration, you also need to provide the equivalent options for easyb:

mvn verify -Deasyb.batch.count=3 -Deasyb.batch.number=1

If you have both easyb and JUnit Thucydides tests, you will need to specify both options.

Parallel web tests on Jenkins

This approach is easy to set up on Jenkins using a multi-configuration build. In the following screenshot, we are running a multi-configuration build to run web tests across three batches. We use a single user-defined parameter (BATCH_NUMBER) to define the batch being run, passing this parameter into the Maven build job properties we discussed above.

The most robust way to aggregate the build results from the different batches is to set up a second build job that runs after the test executions, and retrieves the build results from the batch jobs. You can use the Jenkins Copy Artifacts plugin to do this. First, ensure that the multi-configuration build archives the Thucydides reports, as shown here:

This build will then trigger another, freestyle build job. This job needs to copy the Thucydides report artifacts from the matrix build jobs into the current workspace, and then run the mvn thucydides:aggregate command to generate the Thucydides aggregate reports. The matrix build job reports need to be copied one-by-one for each batch, as the current version of the Copy Artifacts plugin does not support copying from multiple projects in the same action.

Then make sure you publish the generated HTML reports (which will be in the target/site/thucydides directory) for easy access to the test results.

This simple example shows a parallel test running 3 batches – this brought the test execution time from 9 minutes to slightly over 1 minute. Results will vary, of course, but a typical real-world set of web tests would have a larger number of batches.


From http://weblogs.java.net/blog/johnsmart/archive/2011/12/26/faster-web-tests-parallel-batches-thucydides


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}