Skip to end of metadata
Go to start of metadata

Level of experience: Intermediate

Icon

Our tutorials are classified as 'beginner', 'intermediate' and 'advanced'. This one is at 'intermediate' level. If you have never developed a plugin before, you may find this one a bit difficult.

On this page:

Overview

This tutorial shows you how to write integration tests for a plugin. This tutorial demonstrates how to write such tests for both UI elements provided by the plugin itself, as well as the host application.

In order to do this, you will create a JIRA plugin. As with all plugins, your plugin will consist of the following components:

  • Java classes encapsulating the plugin logic
  • Resources for display of the plugin UI
  • Plugin descriptor to enable the plugin module in JIRA.

All these components will be contained within a single JAR file. Each component is discussed further in the examples below.

There are various definitions available for what integration testing actually means. For the purposes of this tutorial, integration testing is defined as running a set of automated tests against the web-UI of your plugin, using HTTP requests and responses to assert that the web-UI is exhibiting the correct behaviour.

Plugin Source

We encourage you to work through this tutorial. If you want to skip ahead or check your work when you are done, you can find the plugin source code on Atlassian Bitbucket. Bitbucket serves a public Git repository containing the tutorial's code. To clone the repository, issue the following command:

$ git clone https://atlassian_tutorial@bitbucket.org/atlassian_tutorial/jira-integration-tests-plugin.git

Alternatively, you can download the source using the Downloads page here: https://bitbucket.org/atlassian_tutorial/jira-integration-tests-plugin

Step 1. Create the Plugin Project

Use the appropriate atlas-create-application-plugin command to create your plugin. For example, atlas-create-jira-plugin or atlas-create-confluence-plugin.

When you create the plugin using the above SDK, you will be prompted for some information to identify your plugin. Enter the following information:

  • group-id: com.atlassian.plugins.tutorial
  • artifact-id: jira-integration-tests-tutorial
  • version: 1.0
  • package: com.atlassian.plugins.tutorial

Step 2. Add Plugin Metadata to the POM

Now you need to edit your POM (Project Object Model definition file) to add some metadata about your plugin and your company or organisation.

  1. Edit the pom.xml file in the root folder of your plugin.
  2. Add your company or organisation name and your website to the <organization>element:

  3. Update the <description>element:

  4. Save the file.

Step 3. Register the Plugin Module in the Plugin Descriptor

Now you will add the required plugin modules to your plugin descriptor at src/main/resources/atlassian-plugin.xml. The plugin descriptor is an XML file that identifies the plugin to JIRA and defines the functionality that the plugin requires.

Here's a basic plugin descriptor:

Note that some of the information from the POM is transferred to the plugin descriptor using variable names such as ${project.artifactId}.

You will need the following plugin module:

atlassian-plugin.xml

The above code snippet introduces a webwork action into this plugin. This is not strictly necessary to write integration tests, but it adds a good example to write integration tests for.

Now you are ready to move onto writing some code to make your plugin do something.

Step 4. Write Java Classes

In this plugin, you want to write integration tests for some plugin points defined by your plugin.

To do this, you will write a webwork action that simply displays the projects in which the currently logged in user has the permission provided as a parameter. So for example, a user will be able to show all the projects that he/she has the Create Issue permission in. The webwork action will also perform some error checks to ensure that only logged in users can query this information and that the permission submitted as a parameter to the action is a valid JIRA permission.

First we need to construct the webwork action with a JIRA PermissionManager which will be used to check what projects a user has a given permission in:

ShowUsersProjectPermissionAction.java

When a user submits a request to this action, we'll have to do some validation:

ShowUsersProjectPermissionAction.java

If validation passed, the doExecute() method is called to retrieve the information we're after:

ShowUsersProjectPermissionAction.java

Finally, all webwork actions need a corresponding view:

showprojects.vm

Step 5. Build, Install and Run the Plugin

Follow these steps to build and install your plugin, so that you can test your code. If you have not already started the application, start it now:

  • Open a command window and go to the plugin root folder (where the pom.xml is located).
  • Run atlas-run (or atlas-debug if you might want to launch the debugger in your IDE).

From this point onwards, you can use FastDev to reinstall your plugin behind the scenes as you work.

To trigger the reinstallation of your plugin:
  1. Make the changes to your plugin module.
  2. Open the Developer Toolbar.
  3. Press the FastDev icon.

    The system rebuilds and reloads your plugin:

Use live reload to view real-time updates to templates and other resources:

  1. Open the Developer Toolbar.
  2. Press the live reload icon.
    The  icon starts to revolve indicating it is on.
  3. Edit your project resources.
  4. Save your changes:
    Back in the host application, your plugin displays any user visible changes you make. 

Go back to the browser. The updated plugin has been installed into the application, and you can test your changes.

The full instructions are in the SDK guide.

You should be able to visit http://localhost:2990/jira/secure/ShowUsersProjectPermissionAction.jspa?permission=create to see a list of all the projects that you have the Create Issue permission in. This may require you to create some projects first.

Step 6. Write Unit and Integration Tests

Icon

There's now available a newer, object oriented way of writing integration tests. This section is for reference and legacy integration tests. We advise you to write integration tests using Page Objects.

Congratulations! You've made it to the meaty part of this tutorial. We'll only focus on integration tests since there's nothing to unit test here, really.

Before we jump into writing an integration test, here's a bit of background about how integration tests work in JIRA. JIRA's integration tests are driven by jWebUnit (albeit a fairly ancient version: 1.2). jWebUnit's purpose is essentially to simulate a browser, making HTTP requests to your web application and making assertions about the state returned in responses by your application. It provides a number of built-in methods to make this easy such as clickLink("linkid") and assertTextPresent("Sample Text").

JIRA built an integration testing framework on top of this to make certain actions in JIRA easier. Historically, integration tests would be written by extending JiraWebTest which would provide all of these utility methods to your integration test. This has now been superseded by a new integration testing framework for JIRA which provides much better documentation and is more flexible and extensible. Please have a read of the framework's API docs for more details about what's possible (make sure to checkout all the interfaces in the main package as they contain all the useful utility methods available to you).

Before we start writing an integration test, you'll have to create a localtest.properties file in your src/test/resources folder:

localtest.properties

JIRA's integration test framework uses this file to figure out which URL your JIRA instance is running under and where to find XML backup files your tests can import to set up the test data. At some stage in the near future, this file will be generated automatically.

Once you have your localtest.properties file in place, you can begin writing your actual integration test case in src/test/java/it:

ShowUsersProjectPermissionTest.java

To write an integration test using JIRA's integration test framework, your test class has to extend FuncTestCase. This class provides a number of helpers such as administration, text and navigation to make integration testing easier. Note that tests not in the it directory are treated as unit tests by the atlas-integration-test command later on, which means that JIRA won't be automatically started and all the "unit tests" will fail.

Before you can start testing, we need to set up JIRA with some data that we can use to test. This is best done by importing an XML backup before a test runs:

ShowUsersProjectPermissionTest.java

This method uses the administration helper to restore the TestShowUsersProjectPermission.xml backup in JIRA.

Icon

While you can use the helper classes provided by FuncTestCase to create test data, this is generally not recommended. For example, creating a large number of issues this way can be very slow. It's better to manually create your test data first, which can then be backed up to XML and imported in your test.

Now we have JIRA setup with some data and we can start writing our first test. Let's test the webwork action we wrote earlier:

ShowUsersProjectPermissionTest.java

This particular test navigates to our webwork action by going to a specific URL and asserts that the correct text has been returned. This test does not use jWebUnit directly, but instead uses helpers provided by JIRA's integration testing framework. One particular pattern that is very useful is the text.assertTextPresent(SomeLocator) pattern. Quite often a web-page will contain the same text in several different places on a web page (for example the name of the logged in user may appear in the page header as well as in the reporter field of an issue) and it's necessary to only run an assertion in a particular part of a page. Locators are a way of limiting what part of the page an assertion is being run over. This is one of the most powerful parts of the integration testing framework and it is highly recommended to have a look at the different kinds of locators available to you.

Finally, lets demonstrate some more advanced ways one can write an integration test:

ShowUsersProjectPermissionTest.java

This test demonstrates some more advanced things that are possible with JIRA's integration testing framework. Line 82 also demonstrates how to use jWebUnit directly via the tester variable, should this ever be necessary.

To run this test you can simply run atlas-integration-test from the command line. This will build your plugin, start up JIRA and run all tests. To run individual tests, you should also be able to start up JIRA with atlas-run and execute your test from your IDE. In Intellij, you can simply right click on a method and click on Run '<TESTNAME>':

If there's any test failures, the build will fail:

Tests run: 2, Failures: 1, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Unable to execute mojo

Embedded error: There are test failures.

Please refer to /Users/andreask/projects/atlassian/jira-integration-tests-tutorial/target/jira/tomcat6x/surefire-reports for the individual test results.

The directory mentioned in the build log will contain a text file for each test class in your integration test suite with more details about what went wrong:

-------------------------------------------------------------------------------
Test set: it.ShowUsersProjectPermissionTest
-------------------------------------------------------------------------------
Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 72.129 sec <<< FAILURE!
testUsersProjectPermissions(it.ShowUsersProjectPermissionTest)  Time elapsed: 40.25 sec  <<< FAILURE!
junit.framework.AssertionFailedError: The text 'The user admin h the 'create' permission in the following projects' could not be found via locator WebPageLocator : 1 node(s) - 'Welcome - Your Company JIRA var conte...'
        at junit.framework.Assert.fail(Assert.java:47)
        at com.atlassian.jira.functest.framework.assertions.TextAssertionsImpl.assertTextPresentImpl(TextAssertionsImpl.java:71)
        at com.atlassian.jira.functest.framework.assertions.TextAssertionsImpl.assertTextPresent(TextAssertionsImpl.java:39)
        at it.ShowUsersProjectPermissionTest.testUsersProjectPermissions(ShowUsersProjectPermissionTest.java:39)
...

In this case I misspelled the text "The user admin h the 'create' permission in the following projects" on line 39 of the ShowUsersProjectPermissionTest.

Congratulations, that's it

Icon

You should now be able to write integration tests for JIRA. Oh and don't forget to have a chocolate!

RELATED TOPICS

Plugin Testing Resources and Discussion

Writing integration tests using Page Objects

Smarter integration testing with TestKit

3 Comments

  1. The example plugin seems broken. "doValidation()" references a variable "permission" which isn't declared, or in scope.

    I'd have reported this as an issue but hitting "Report a Bug" just takes me to a vanilla looking dashboard.

  2. Anonymous

    There are errors in the mark up that are preventing one from seeing the example code.

    Starting with the code for localtest.properties and several others.

    Error formatting macro: snippet: java.lang.IllegalArgumentException: Invalid url: must begin with a configured prefix.

    Erik Husby
    Broad Institute