CustomWare Greenhouse Blog from March, 2009

Oeyvind Eliassen, Kelvin Yap, Adam Saint-Prix and 8 others like this. Please log in to like this.

Assumptions

This guide assumes that your project is already set up properly (pom, directory structure, maven 2, correct version of java).

If you are not familiar with the process of developing Confluence Plugins, here is a list of relevant documentation to get you started:

Setting Up

Parent pom

The first a foremost thing you have to do is to include the following at the very top of your pom.xml (within the project element) :

Please note that you can change the version of the plugin base, typically try to use the newest version as they get improved upon often.

This parent pom includes a lot of dependencies for the test harness including the JWebUnit libraries, the custom Confluence abstract test cases, sample data, the webapp, tomcat, etc.

Note: by default the parent pom uses Java 1.4, you should overwrite this so you use (at least) Java 1.5 by inserting:

Setting up the Properties

You can specify a few environment details for your testing environment in your pom.xml, to do this, simply append the variables to your properties, here is a list of the available ones:

Property Name

Description

atlassian.plugin.key

The plugin key for the plugin that you are developing.

confluence.version or atlassian.product.version

The version of Confluence you are developing for.

atlassian.product.data.version

The sample data for the version of Confluence you are developing for, typically this is the same as the confluence.version property.

atlassian.product.test-lib.version

The version of the testing library to use, as a general recommendation you should at least use version 2.0 or higher as it exposes more of the page's content and provides quite a few extra helper classes to aid in your testing.

atlassian.plugin.application.version.min

The minimum version of Confluence that your plugin is compatible with.

atlassian.plugin.application.version.max

The maximum version of Confluence that your plugin is compatible with.

confluence.plugin.bundled

Bundle your plugin as part of Confluence.

confluence.plugin.install

Installs your plugin into the test instance of Confluence once it starts up.

confluence.url

The url of the testing Confluence instance, note that you do not have to change this, it is set automatically based on your other settings.

tomcat.installer.url

The url of the Tomcat installer to use, typically it is a link to a release on a maven 2 repository, by default it uses version 5.5.20 of Tomcat.

http.port

The port to run the testing Confluence instance on.

rmi.port

The port to use for RMI.

cargo.wait

false by default (shuts down server as soon as the tests are completed), I recommend not turning this to true unless you really want to see what is inside the system after the testing is completed.

jdkLevel

Sets the version of the JDK to use for compiling the plugin

Sample properties

Sample Confluence Plugin pom.xml Files

Here is a list of some sample pom files used in Atlassian Supported plugins for reference.

Writing Your Test

Setting up your Test Class

All Confluence tests should extend the com.atlassian.confluence.plugin.functest.AbstractConfluencePluginWebTestCase class, it is an extension of the base net.sourceforge.jwebunit.junit.WebTestCase class but provides a lot of helper methods that aid in the writing of your tests. This class also has some predefined setUp and tearDown sequences that are useful in all test cases
Some features that the setUp provides include:

  • Creating the confluence web tester class
  • Setting the base URL
  • Logging into confluence as an administrator
  • Installing your plugin
  • Installing the license
  • Putting in sample data
    Some features that the tearDown provides are:
  • Logging out

Because of these features, it is HIGHLY recommended that you invoke these parent methods using super.xxx() if you decide to overwrite them to extend their functionality.

Writing the Test Cases

As the AbstractConfluencePluginWebTestCase class extends the WebTestCase class, you have full access to everything that a normal web test case has such as gotoPage, getting values by Xpath, etc. You may want to refer to the documentation for JWebUnit to get a grasp of the basic concepts of a web test case.

For the package structure, Atlassian's standard style is to include "it." at the front of the package to indicate that it is for integration testing. Please note that this naming standard is COMPULSARY as the testing frame work filters the tests by the package name, so integration tests must have "it." as the start of the package.
eg.
it.com.my.confluence.plugin

Helpers

A few extra things that the AbstractConfluencePluginWebTestCase provides includes helpers (as you do not have access to the managers directly), here is a list of helpers that you can access including:

Helper

AttachmentHelper

BandanaHelper

BlogPostHelper

CommentHelper

GroupHelper

IndexHelper

MailServerHelper

PageHelper

SpaceHelper

UserHelper

These helpers are basically beans for each of their relevant entities but typically provides some extra functionally such as create, delete and update.

The 3 special cases from this list are the more back-end helpers including:

  • BandanaHelper - providing access to a single value stored in Confluence's bandana
  • IndexHelper - provides access to a single indexed item
  • MailServerHelper - gives you access and ability to update the mail servers configured for the server, useful if you need to mail things out as part of your tests.

When you are doing any operation with the helpers, typically they return a boolean to say if the process completed successfully or not, so when you are calling these options it is a good idea to use an assertTrue() around the function to check that the process completed properly.

Creating/Fetching Entities in Confluence

The way that this is done is via the related Helper classes for each entity, you can get the helpers by using the getxxxHelper() and getxxxHelper(Params) methods, the Helpers basically uses the remote API in Confluence to fetch the entities, then once you have the entities, simply use the .read() method to grab all the data related to that entity.

Creating Entities

The way to create entities is to basically get an empty helper instance (by using the getxxxHelper() method), populating it with data and then using the .create() method in the helper, please note that it is recommended to create everything as part of the setUp and then remove them as part of the tearDown process, otherwise you will get issues when running multiple tests.

Sample Entity Creation

Space:

Page:

User:

Fetching Entities

The way to fetch entities is to basically use the getxxxHelper(Params) method and it will give you the helper object with the information about the requested entity.

Sample Entity Fetching

User:

Group:

Updating Entities

To update entities, all you have to do is to first fetch the entity (refer to #Sample Entity Fetching for more details) then change some of the values and then invoke the .update() method in the helper.

Sample Entity Updating

User:

Using Your Own Test Data

If your plugin requires a lot of setup to test (for example reporting will require quite a lot of content to test the functionality properly), you might want to have a pre-populated Confluence backup for use with testing. Take a site export of your entire Confluence instance and put it in the following directory structure:

Confluence will load up this site export as part of the testing.

Sample Integration Test Class Code

Constructor:

Single Test:

Sample Test Cases

Here is a list of some sample integration tests used in Atlassian Supported plugins to test out some core Confluence macros to help you get an idea on how these tests are used.

Running Your Tests

This is the simplest part, simply use the following command:

or

Note: you can specify build specific parameters by using -Dparameter=value (eg. -Dcargo.wait=true), for a list of relevant parameters please consult the Properties List

The results will be printed to command line and a summary will be outputted to the target/surefire-reports/ directory, the build will ONLY be successful if it passes ALL tests.

Configuring Your Bamboo Build Plan

To actually configure Bamboo to do your testing automatically as part of the build and produce meaningful output you will need to do the changes listed below.

If you have never set up a Bamboo build plan before, you may want to check the Atlassian documentation for Creating a Plan to get you started.

Modifying the Builder

Basically all you need to do is to add integration-test as part of the command to be executed, please note that this should be BEFORE the package phase.

It should look something like the following:

Adding to the Artifacts

It is useful to have access to the test results via the build server directly, to do this we will need to add another configuration to the list of artifacts, add the following:

Artifact Label

Artifact Copy Pattern

Source Directory

surefire-reports

surefire-reports/*.*

target

After each build, you will find a set of surefire-reports under Artifacts, which you can view to see how many tests were executed, how long it took to run, environment details and in cases where a test failed, details on where it failed.

Appendix

Confluence Plugin Parent pom.xml

The parent pom.xml being used for integration testing can be found on the Atlassian svn under
confluence-plugin-base.

The referenced version (version 19) is the latest version release as of the time this article was written.