Writing System Tests for Joomla! - Part 1

From Joomla! Documentation

Introduction[edit]

As documented at Running Automated Tests for Version 1.6, Joomla! 1.6 now includes a library of system tests. This document details the steps necessary to create system tests using Selenium IDE. This article is split into two parts. The first part covers recording tests using the Selenium IDE. The second part covers more advanced topics, including converting recorded tests into PHP system tests that can be run automatically.

For background information about System Testing, please see the System Testing article.

NOTE: To use Selenium IDE you just need to have Firefox installed. To run system tests in PHP, you need to have PHPUnit and Selenium RC set up and working properly, as documented in Running Automated Tests for Version 1.6.

Overview[edit]

This is the first in a series of documents that show you how to write automated system tests for Joomla! using the Selenium IDE add-on for Firefox and the Selenium RC program. This document covers creating recorded tests using the Selenium IDE. The second document, Writing System Tests for Joomla! - Part 2, covers more advanced topics.

Creating a system test is not difficult once you are familiar with the steps. It is also important to remember that, unlike a manual test, once you have created an automated test it can be run hundreds or thousands of times with no effort.

The major steps to create a system test are as follows:

  1. Plan the test. This involves the following:
    1. Figure out the purpose of the test. Each test ideally will test one area of the CMS.
    2. Plan what screens you will visit and what data you will enter.
    3. Plan what checks you will perform to ensure that you have gotten the expected results.
  2. Record the test using the Selenium IDE. This creates most of the PHP code for the test automatically.
  3. Create the file for the test in your Joomla! project (for example, in Eclipse) and paste in the PHP code from step (2) above.
  4. Debug the test and revise as needed.
  5. Add the test to the TestSuite.php file if desired.

Planning the Test[edit]

For a simple test, this step can be very quick. Just figure out what you want to test and decide how you would test this manually. Here are some important tips when planning a test.

  • Always start with the base sample data and always end the test with the sample data in the same state you started with. This way you can run a series of tests knowing that the data will be in a known state.
  • Keep tests small and focused on one area. Generally it is easier to maintain a series of small tests than one large test.

An example of a plan for a test could be as follows:

  • Log in to back end.
  • Navigate to Article Manager.
  • Add a new article called Test Article.
  • Publish the article to the front page.
  • Navigate to the front end.
  • Test that new article is shown.
  • Navigate to the back end.
  • Delete the new article.
  • Navigate to the front end.
  • Test that the new article is not shown.
  • Log out of back end.

Writing System Tests with Selenium IDE[edit]

Selenium IDE makes it fairly easy to write system tests. It is a Firefox add-on that operates as an Integrated Development Environment (IDE) for creating system tests. In essence, it records your clicks as you navigate in your browser and encodes them into a series of commands that can control the browser. Tests recorded with Selenium IDE can be converted to PHP code. This code can then be used to create PHP system tests for the Joomla repository and integrated into the test suite.

Getting Selenium IDE[edit]

At of May 27, 2010, the latest version of Selenium IDE is 1.0.7. You can get it at http://seleniumhq.org/download/. Click on the download link and Firefox will install it automatically and then re-start.

Preparing your Environment[edit]

To get started, create a clean install of Joomla! with the standard sample data or update your local copy to the latest build and perform a re-installation. It is important to start and end each test with the unaltered sample data. That way, tests can be performed in any sequence.

Writing a Basic Test with Selenium IDE[edit]

For our first test, we are going to load the home page of our local test site and check to make sure that some of the menu items are functioning and verify the presence of text on their corresponding pages. The commands that we use to check that items are present are called assertions. Basically, you perform your actions and make assertions about the results. In this example, we are going to use the command assertText. This command will read the text of a specified element and ensure it matches a particular value.

  1. To start, open Firefox and browse to the home page of your Joomla! installation. For example, I set up my installation on my localhost, and so the URL is http://127.0.0.1/selsampledata.
  2. Click on Tools -> Selenium IDE. You will notice that a window will pop-up, and on the top right corner of that window, there is a red circle that is highlighted. This is the start/stop recording button. When you start Selenium IDE, recording starts automatically.
  3. Ensure that the Base URL displayed in the Selenium IDE window is that of the home page of your Joomla! installation.
  4. Switch to the browser window that has your Joomla! installation open.
  5. Left click on the Home menu item to load / re-load the home page, then right-click and select 'Assert Text' on the title of the leading article. You will notice the addition of each of those actions to Selenium IDE as you make them.
  6. Repeat the above step for the remaining menu items and leading article on each page, or in the case of a form, you can right-click on the submit button and select "Assert Text".
  7. Switch to your Selenium IDE window and click the Red Button to stop recording.

You should see two tabs in your Selenium IDE window - one labeled Table, and one labeled Source. At this point you don't really need to look at the Source window.

Selenium-screen.png


Our first test is done.

To run your test, use the icons on the bar between the Base URL address bar and the Table and Source tabs. The two important buttons is the button with the Green Triangle, with Three Solid rectangles, and the one with the Green Triangle and One Solid Rectangle. The first one will execute the entire test suite and the second one will run the currently selected test case. Since we currently have only one test case, both of these currently do the same thing.

To run your test, press one of these buttons.

As you watch the Selenium IDE, you will see a yellow bar move down your list of steps. Once a step is completed, a successfully executed action (i.e. a button was successfully located and clicked) should show up in light green and a successful assertion should show up in darker green. Failed actions show up in light red and failed assertions show up in darker red.

Click on the Window Expander on the left to unhide the Test Case browser.

If your test completed successfully, you should see Runs: 1, Failures: 0 at the bottom of the Test Case browser.

Writing an Intermediate Test with Selenium IDE[edit]

This example is based on the sample data included with Joomla 1.6 Beta2. In this example, we will:

  • Log in to the back-end of our test site
  • Create a test article and publish it to the front page
  • Navigate to the front page and verify that the article is published
  • Navigate to the back end and unpublish the article
  • Navigate to the front end and verify that the article is unpublished.

This example will also help us illustrate working with a few quirks of Selenium IDE.

  1. Start by opening Firefox and browsing to the back end of your Joomla installation.
  2. Click on Tools -> Selenium IDE to start recording.
  3. Enter your administrative username in the username input.
  4. Due some quirks with Selenium, it will not record your password and we will need to create that step manually.
    1. Press the start/stop button to stop recording.
      • Since entering a password is very similar to entering a username, we are going to copy and modify the username step.
    2. Right-click on the username step and select copy. Right-click directly below the username step and select paste. You will now see the same step repeated twice.
    3. Left-click on the second username entry. Using Firebug I can see that the target needs to changed to mod-login-password and the value needs to be changed to reflect my password.
    4. Left-click directly below the password step that we just created and click the start/stop button to resume recording.
  5. Click on the Log in button.
    • Since Selenium IDE has difficulty with correctly interfacing with WYSIWYG editors, we are going to disable the editor for this test.
  6. Click on the User Manager
  7. Click on the admin account that you just logged in with, in this case Super User.
  8. In the Basic Settings area, select Editor - None next to Editor.
  9. Click Save & Close
  10. Under the Content menu, click on Add New Article.
    1. Enter a name for the test article.
    2. Enter an article alias.
    3. Select a category.
    4. Select the Published State.
    5. Select Yes next to Featured.
    6. Enter the following in the article textarea:
      <p id="body-text">Test paragraph</p>
    7. Click Save & Close.
  11. To make it easier to navigate to the front end of our site, we will go ahead and logout of the back end and click the Go to site home page link next to the login form.
  12. You should now see the test article on the home page. Right-click on the title and select the Assert Text command.
  13. Left-click on the article title.
  14. Once the test article has loaded, right click on the test paragraph and click the Assert Text command.
  15. Click on the Home link to go back to the home page.
    • Since our site is configured to open the Site Administrator menu item in a new browser, we will need to manually create the step to go to the back end.
  16. Click the start/stop button to stop recording.
    1. Right click on the first step of our test: open/127.0.0.1/selsampledata/administrator/ and then select copy.
    2. Right click below the last step of our test and select paste.
    3. Do the same with the username and passwords steps: typemod-login-usernameadmin typemod-login-passwordpassword
  17. Click the start/stop button to start recording.
  18. Click on the Log in button.
  19. Click the article manager button.
  20. Left-click in the filter input and enter "test article".
  21. Click on the Search button.
  22. Click the check all checkbook to select all articles.
  23. Click the Unpublish toolbar button.
  24. Log out of the back end and click the Go to site home page link.
  25. To include verification in our test that the article does not appear on the front end, we will copy the following step, paste it at the end of our test and then modify it.assertTextlink=Test ArticleTest Article
  26. Once pasted at the end of our test, click the drop down arrow next to command, scroll down to assertTextNotPresent and click it.
  27. Click the start/stop button to stop recording.
  28. Select File -> Export Test Case As -> HTML to save your test locally.

Exporting / Saving Selenium IDE Tests[edit]

Once recorded, you can export a Selenium IDE test for later use or to share with someone else to run. In this example, we choose HTML so that we can easily share it with others. This is the recommended format to use for saving a Selenium Test.

Selenium-export.png

For example, the resulting HTML of our basic test is:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="http://servebrain/workspace/joomla-1-6-source/index.php/" />
<title>basic-selenium-ide-test</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">basic-selenium-ide-test</td></tr>
</thead><tbody>
<tr>
	<td>open</td>
	<td>http://127.0.0.1/selsampledata</td>
	<td></td>
</tr>
<tr>
	<td>clickAndWait</td>
	<td>link=Home</td>
	<td></td>
</tr>
<tr>
	<td>assertText</td>
	<td>link=Joomla!</td>
	<td>Joomla!</td>
</tr>
<tr>
	<td>clickAndWait</td>
	<td>link=Site Map</td>
	<td></td>
</tr>
<tr>
	<td>assertText</td>
	<td>//div[@id='main']/div/h2/a</td>
	<td>Site Map</td>
</tr>
<tr>
	<td>clickAndWait</td>
	<td>link=Login</td>
	<td></td>
</tr>
<tr>
	<td>assertText</td>
	<td>//button[@type='submit']</td>
	<td>Log in</td>
</tr>
<tr>
	<td>clickAndWait</td>
	<td>link=Home</td>
	<td></td>
</tr>

</tbody></table>
</body>
</html>

Converting Selenium IDE Tests to PHP[edit]

Tests recorded with Selenium IDE can be converted for inclusion in the /tests/system folder as well as integration in to the test suite.

We'll continue our example from above and convert the Selenium IDE test to a PHP file for inclusion in the /tests/system folder.

Since the test was exported in the HTML format, we can easily open it and re-play it in Selenium IDE.

Assuming that the test behaves as expected, we will convert it to PHP by selecting Options -> Format -> PHP - Selenium RC.

Selenium-change-format.png

The test can now be be exported as PHP by selecting File -> Export Test Case As -> PHP - Selenium RC.

Selenium-export-php.png

The converted Selenium IDE test now looks like:

<?php

require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

class Example extends PHPUnit_Extensions_SeleniumTestCase
{
  function setUp()
  {
    $this->setBrowser("*chrome");
    $this->setBrowserUrl("http://127.0.0.1/selsampledata/");
  }

  function testMyTestCase()
  {
    $this->open("/workspace/joomla-1-6-source/");
    $this->click("link=Using Joomla!");
    $this->waitForPageToLoad("30000");
    $this->assertEquals("Getting started", $this->getText("link=Getting started"));
    $this->assertTrue($this->isElementPresent("link=Extensions"));
    $this->click("link=The Joomla! Community");
    $this->waitForPageToLoad("30000");
    $this->assertEquals("The Joomla! Project", $this->getText("link=The Joomla! Project"));
    $this->click("//div[@id='breadcrumbs']/p/span/a");
    $this->waitForPageToLoad("30000");
  }
}

It is nearly ready to be added to /tests/system, but needs a few modifications before doing so.

  • We need to add a comment block to the top
<?php
/**
 * @version     $Id: exmaple0001Test.php
 * @package Joomla.SystemTest
 * @copyright Copyright (C) 2005 - 2010 Open Source Matters, Inc. All rights reserved.
 * @license GNU General Public License version 2 or later; see LICENSE.txt
 * Tests creating a test
 */
  • We need to change require_once 'PHPUnit/Extensions/SeleniumTestCase.php'; to require_once 'SeleniumJoomlaTestCase.php';
require_once 'SeleniumJoomlaTestCase.php';
  • Change the class Selenium IDE uses to a new class, that extends SeleniumJoomlaTestCase, using the naming convention, written in CamelCase, of subject + test number in the series (4 digits) + "Test".
    • For example, our test that we are calling example would be: Example + 0001 + Test resulting in Example0001Test
class Example0001Test extends SeleniumJoomlaTestCase
  • Remove the function setUp()
function setUp()
{
    $this->setBrowser("*chrome");
    $this->setBrowserUrl("http://127.0.0.1/selsampledata/");
}

created by Selenium IDE and add

$this->setUp();

to our test function. Finally, change the line

$this->open("/workspace/joomla-1-6-source/");

to

$this->gotoSite());

That change removes hard-coding the home page URL. The method gotoSite() navigates to the home page of your test site using the configuration information in your local configdef.php file.

The converted test now looks like:

<?php
/**
 * @version     $Id: exmaple0001Test.php
 * @package Joomla.SystemTest
 * @copyright Copyright (C) 2005 - 2010 Open Source Matters, Inc. All rights reserved.
 * @license GNU General Public License version 2 or later; see LICENSE.txt
 * Tests creating a test
 */

require_once 'SeleniumJoomlaTestCase.php';

class Example0001Test extends SeleniumJoomlaTestCase
{
    function testCreatDeleteGroup()
    {
        $this->setUp();
        $this->gotoSite();
        $this->click("link=Using Joomla!");
        $this->waitForPageToLoad("30000");
        $this->assertEquals("Getting started", $this->getText("link=Getting started"));
        $this->assertTrue($this->isElementPresent("link=Extensions"));
        $this->click("link=The Joomla! Community");
        $this->waitForPageToLoad("30000");
        $this->assertEquals("The Joomla! Project", $this->getText("link=The Joomla! Project"));
        $this->click("//div[@id='breadcrumbs']/p/span/a");
        $this->waitForPageToLoad("30000");
    }
}

Your test can now be saved to the /tests/system folder within Joomla and run as a member of the test suite. See Running_Automated_Tests_for_Version_1.6

Creating a Basic System Test in PHP[edit]

By leveraging the Selenium_Test_Case_Methods, we can streamline automated system test with just a few lines of code.

For example, to test logging into and then out of the back end, we could use the following code:

<?php
require_once 'SeleniumJoomlaTestCase.php';

class ControlPanelExample extends SeleniumJoomlaTestCase
{
    function testExample()
    {
        $this->setUp();
        $this->doAdminLogin();
        $this->doAdminLogout();
    }
}
?>
  • require_once 'SeleniumJoomlaTestCase.php';? allows use to utilize the methods that belong to the Selenium Joomla Test Case class
  • class ControlPanelExample extends SeleniumJoomlaTestCase extends a class into our SeleniumJoomlaTestCase to implement the client/server protocol to talk to Selenium RC as well as specialized assertion methods for web testing.
  • Each test is written as a function.
  • $this->setUp(); envokes our configuration from tests/system/servers/configdef.php see Running_Automated_Tests_for_Version_1.6#Create_a_Selenium_Configuration_File
  • $this->doAdminLogin(); is a Selenium Joomla Test Case method that logs into the back end.
  • $this->doAdminLogoutn(); is a Selenium Joomla Test Case method that logs out of the back end.

More Advanced Topics[edit]

To learn about more advanced topics related to system testing, please see the article Writing System Tests for Joomla! Part 2.