Prev Next

Chapter 18. PHPUnit and Selenium

Selenium RC

Selenium RC is a test tool that allows you to write automated user-interface tests for web applications in any programming language against any HTTP website using any mainstream browser. It uses Selenium Core, a library that performs automated browser tasks using JavaScript. Selenium tests run directly in a browser, just as real users do. These tests can be used for both acceptance testing (by performing higher-level tests on the integrated system instead of just testing each unit of the system independently) and browser compatibility testing (by testing the web application on different operating systems and browsers).

Let us take a look at how Selenium RC is installed:

  1. Download a distribution archive of Selenium RC.
  2. Unzip the distribution archive and copy server/selenium-server.jar to /usr/local/bin, for instance.
  3. Start the Selenium RC server by running java -jar /usr/local/bin/selenium-server.jar.

Now we can send commands to the Selenium RC server using its client/server protocol.

PHPUnit_Extensions_SeleniumTestCase

The PHPUnit_Extensions_SeleniumTestCase test case extension implements the client/server protocol to talk to Selenium RC as well as specialized assertion methods for web testing.

Example 18.1 shows how to test the contents of the <title> element of the http://www.example.com/ website.

Example 18.1: Usage example for PHPUnit_Extensions_SeleniumTestCase

<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
 
class WebTest extends PHPUnit_Extensions_SeleniumTestCase
{
    protected function setUp()
    {
        $this->setBrowser('*firefox');
        $this->setBrowserUrl('http://www.example.com/');
    }
 
    public function testTitle()
    {
        $this->open('http://www.example.com/');
        $this->assertTitleEquals('Example WWW Page');
    }
}
?>
phpunit WebTest
PHPUnit 3.4.2 by Sebastian Bergmann.

F

Time: 5 seconds

There was 1 failure:

1) testTitle(WebTest)
Current URL: http://www.example.com/

Failed asserting that two strings are equal.
expected string <Example WWW Page>
difference      <         xx>
got string      <Example Web Page>
/home/sb/WebTest.php:30

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.


Unlike with the PHPUnit_Framework_TestCase class, test case classes that extend PHPUnit_Extensions_SeleniumTestCase have to provide a setUp() method. This method is used to configure the Selenium RC session. See Table 18.1 for the list of methods that are available for this.

Table 18.1. Selenium RC API: Setup

MethodMeaning
void setBrowser(string $browser)Set the browser to be used by the Selenium RC server.
void setBrowserUrl(string $browserUrl)Set the base URL for the tests.
void setHost(string $host)Set the hostname for the connection to the Selenium RC server.
void setPort(int $port)Set the port for the connection to the Selenium RC server.
void setTimeout(int $timeout)Set the timeout for the connection to the Selenium RC server.
void setSleep(int $seconds)Set the number of seconds the Selenium RC client should sleep between sending action commands to the Selenium RC server.


PHPUnit can optionally capture a screenshot when a Selenium test fails. To enable this, set $captureScreenshotOnFailure, $screenshotPath, and $screenshotUrl in your test case class as shown in Example 18.2.

Example 18.2: Capturing a screenshot when a test fails

<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
 
class WebTest extends PHPUnit_Extensions_SeleniumTestCase
{
    protected $captureScreenshotOnFailure = TRUE;
    protected $screenshotPath = '/var/www/localhost/htdocs/screenshots';
    protected $screenshotUrl = 'http://localhost/screenshots';
 
    protected function setUp()
    {
        $this->setBrowser('*firefox');
        $this->setBrowserUrl('http://www.example.com/');
    }
 
    public function testTitle()
    {
        $this->open('http://www.example.com/');
        $this->assertTitleEquals('Example WWW Page');
    }
}
?>
phpunit WebTest
PHPUnit 3.4.2 by Sebastian Bergmann.

F

Time: 5 seconds

There was 1 failure:

1) testTitle(WebTest)
Current URL: http://www.example.com/
Screenshot: http://localhost/screenshots/6c8e1e890fff864bd56db436cd0f309e.png

Failed asserting that two strings are equal.
expected string <Example WWW Page>
difference      <         xx>
got string      <Example Web Page>
/home/sb/WebTest.php:30

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.


You can run each test using a set of browsers: Instead of using setBrowser() to set up one browser you declare a public static array named $browsers in your test case class. Each item in this array describes one browser configuration. Each of these browsers can be hosted by different Selenium RC servers. Example 18.3 shows an example.

Example 18.3: Setting up multiple browser configurations

<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
 
class WebTest extends PHPUnit_Extensions_SeleniumTestCase
{
    public static $browsers = array(
      array(
        'name'    => 'Firefox on Linux',
        'browser' => '*firefox',
        'host'    => 'my.linux.box',
        'port'    => 4444,
        'timeout' => 30000,
      ),
      array(
        'name'    => 'Safari on MacOS X',
        'browser' => '*safari',
        'host'    => 'my.macosx.box',
        'port'    => 4444,
        'timeout' => 30000,
      ),
      array(
        'name'    => 'Safari on Windows XP',
        'browser' => '*custom C:\Program Files\Safari\Safari.exe -url',
        'host'    => 'my.windowsxp.box',
        'port'    => 4444,
        'timeout' => 30000,
      ),
      array(
        'name'    => 'Internet Explorer on Windows XP',
        'browser' => '*iexplore',
        'host'    => 'my.windowsxp.box',
        'port'    => 4444,
        'timeout' => 30000,
      )
    );
 
    protected function setUp()
    {
        $this->setBrowserUrl('http://www.example.com/');
    }
 
    public function testTitle()
    {
        $this->open('http://www.example.com/');
        $this->assertTitleEquals('Example Web Page');
    }
}
?>


PHPUnit_Extensions_SeleniumTestCase can collect code coverage information for tests run through Selenium:

  1. Copy PHPUnit/Extensions/SeleniumTestCase/phpunit_coverage.php into your webserver's document root directory.
  2. In your webserver's php.ini configuration file, configure PHPUnit/Extensions/SeleniumTestCase/prepend.php and PHPUnit/Extensions/SeleniumTestCase/append.php as the auto_prepend_file and auto_append_file, respectively.
  3. In your test case class that extends PHPUnit_Extensions_SeleniumTestCase, use
    protected $coverageScriptUrl = 'http://host/phpunit_coverage.php';
    to configure the URL for the phpunit_coverage.php script.

Table 18.2 lists the various assertion methods that PHPUnit_Extensions_SeleniumTestCase provides.

Table 18.2. Assertions

AssertionMeaning
void assertElementValueEquals(string $locator, string $text)Reports an error if the value of the element identified by $locator is not equal to the given $text.
void assertElementValueNotEquals(string $locator, string $text)Reports an error if the value of the element identified by $locator is equal to the given $text.
void assertElementValueContains(string $locator, string $text)Reports an error if the value of the element identified by $locator does not contain the given $text.
void assertElementValueContains(string $locator, string $text)Reports an error if the value of the element identified by $locator contains the given $text.
void assertElementContainsText(string $locator, string $text)Reports an error if the element identified by $locator does not contain the given $text.
void assertElementNotContainsText(string $locator, string $text)Reports an error if the element identified by $locator contains the given $text.
void assertSelectHasOption(string $selectLocator, string $option)Reports an error if the given option is not available.
void assertSelectNotHasOption(string $selectLocator, string $option)Reports an error if the given option is available.
void assertSelected($selectLocator, $option)Reports an error if the given label is not selected.
void assertNotSelected($selectLocator, $option)Reports an error if the given label is selected.
void assertIsSelected(string $selectLocator, string $value)Reports an error if the given value is not selected.
void assertIsNotSelected(string $selectLocator, string $value)Reports an error if the given value is selected.


Table 18.3 shows the template method of PHPUnit_Extensions_SeleniumTestCase:

Table 18.3. Template Methods

MethodMeaning
void defaultAssertions()Override to perform assertions that are shared by all tests of a test case. This method is called after each command that is sent to the Selenium RC server.


Please refer to the documentation of Selenium Core for a reference of the commands available and how they are used.

Using the runSelenese($filename) method, you can also run a Selenium test from its Selenese/HTML specification. Furthermore, using the static attribute $seleneseDirectory, you can automatically create test objects from a directory that contains Selenese/HTML files. The specified directory is recursively searched for .htm files that are expected to contain Selenese/HTML. Example 18.4 shows an example.

Example 18.4: Use a directory of Selenese/HTML files as tests

<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
 
class SeleneseTests extends PHPUnit_Extensions_SeleniumTestCase
{
    public static $seleneseDirectory = '/path/to/files';
}
?>


Prev Next
1. Automating Tests
2. PHPUnit's Goals
3. Installing PHPUnit
4. Writing Tests for PHPUnit
Test Dependencies
Data Providers
Testing Exceptions
Testing PHP Errors
5. The Command-Line Test Runner
6. Fixtures
More setUp() than tearDown()
Variations
Sharing Fixture
Global State
7. Organizing Tests
Composing a Test Suite Using the Filesystem
Composing a Test Suite Using XML Configuration
Using the TestSuite Class
8. TestCase Extensions
Testing Output
9. Database Testing
Data Sets
Flat XML Data Set
XML Data Set
CSV Data Set
Replacement Data Set
Operations
Database Testing Best Practices
10. Incomplete and Skipped Tests
Incomplete Tests
Skipping Tests
11. Test Doubles
Stubs
Mock Objects
Stubbing and Mocking Web Services
Mocking the Filesystem
12. Testing Practices
During Development
During Debugging
13. Test-Driven Development
BankAccount Example
14. Behaviour-Driven Development
BowlingGame Example
15. Code Coverage Analysis
Specifying Covered Methods
Ignoring Code Blocks
Including and Excluding Files
16. Other Uses for Tests
Agile Documentation
Cross-Team Tests
17. Skeleton Generator
Generating a Test Case Class Skeleton
Generating a Class Skeleton from a Test Case Class
18. PHPUnit and Selenium
Selenium RC
PHPUnit_Extensions_SeleniumTestCase
19. Logging
Test Results (XML)
Test Results (TAP)
Test Results (JSON)
Code Coverage (XML)
20. Build Automation
Apache Ant
Apache Maven
Phing
21. Continuous Integration
Atlassian Bamboo
CruiseControl
phpUnderControl
22. PHPUnit API
Overview
PHPUnit_Framework_Assert
assertArrayHasKey()
assertClassHasAttribute()
assertClassHasStaticAttribute()
assertContains()
assertContainsOnly()
assertEqualXMLStructure()
assertEquals()
assertFalse()
assertFileEquals()
assertFileExists()
assertGreaterThan()
assertGreaterThanOrEqual()
assertLessThan()
assertLessThanOrEqual()
assertNotNull()
assertObjectHasAttribute()
assertRegExp()
assertSame()
assertSelectCount()
assertSelectEquals()
assertSelectRegExp()
assertStringEndsWith()
assertStringEqualsFile()
assertStringStartsWith()
assertTag()
assertThat()
assertTrue()
assertType()
assertXmlFileEqualsXmlFile()
assertXmlStringEqualsXmlFile()
assertXmlStringEqualsXmlString()
PHPUnit_Framework_Test
PHPUnit_Framework_TestCase
PHPUnit_Framework_TestSuite
PHPUnit_Framework_TestResult
Package Structure
23. Extending PHPUnit
Subclass PHPUnit_Framework_TestCase
Assert Classes
Subclass PHPUnit_Extensions_TestDecorator
Implement PHPUnit_Framework_Test
Subclass PHPUnit_Framework_TestResult
Implement PHPUnit_Framework_TestListener
New Test Runner
A. Assertions
B. Annotations
@assert
@backupGlobals
@backupStaticAttributes
@covers
@dataProvider
@depends
@expectedException
@group
@outputBuffering
@runTestsInSeparateProcesses
@runInSeparateProcess
@test
@testdox
@ticket
C. The XML Configuration File
PHPUnit
Test Suites
Groups
Including and Excluding Files for Code Coverage
Logging
Test Listeners
Setting PHP INI settings, Constants and Global Variables
Configuring Browsers for Selenium RC
D. Index
E. Bibliography
F. Copyright