Testing with Selenium and PHPUnit

Aug 8, 2021 by Thibault Debatty | 274 views

PHP DevOps

https://cylab.be/blog/160/testing-with-selenium-and-phpunit

In this blog post we continue our series about testing a web application with Selenium. This time we will show how to integrate Selenium with PHPUnit tests and assertions.

PHPUnit tests

To help you write PHPUnit tests that rely on Selenium, you can use the phpunit-selenium extension. However, at the time of writing, there is an incompatibility between phpunit-selenium and phpunit >= 9.4. So you must force phpunit version 9.3.x in order to use phpunit-selenium:

composer require --dev phpunit/phpunit:9.3.*
composer require --dev phpunit/phpunit-selenium

To run my Selenium tests appart from other unit tests, I usually like to create a dedicated phpunit configuration file, for example phpunit-selenium.xml, with following content:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true">
  <testsuites>
    <testsuite name="Selenium">
      <directory suffix="Test.php">./tests/Selenium</directory>
    </testsuite>
  </testsuites>
</phpunit>

As you can see from the configuration file, the test files must be located in directory tests/Selenium and must end with Test.php.

So you should first create the appropriate directory:

mkdir -p tests/Selenium

Then you can create your first test file, tests/Selenium/ExampleTest.php:

<?php

namespace Tests\Selenium;

use PHPUnit\Extensions\Selenium2TestCase;

class ExampleTest extends Selenium2TestCase
{
    private $baseUrl = 'http://staging.myapp.com';

    protected function setUp() : void
    {
        parent::setUp();

        $selenium_host = getenv("SELENIUM_HOST");
        if ($selenium_host === false) {
            $selenium_host = "localhost";
        }
        $this->setHost($selenium_host);
        $this->setBrowser("chrome");
        $this->setBrowserUrl($this->baseUrl);
        // https://github.com/giorgiosironi/phpunit-selenium/issues/439#issuecomment-561740660
        $this->setDesiredCapabilities(['chromeOptions' => ['w3c' => false]]);
    }

    /**
     * @test
     */
    public function testRegisterLink() : void
    {
        $this->url('/');
        $this->assertEquals(
            "Cyber-Wise helps you to defeat cybercriminals",
            $this->byId("title")->text());
        $this->byId("btn-register")->click();
        $this->assertEquals(
            "Register for Cyber-Wise",
            $this->byId("title")->text());
    }
}

As you can see from the example, your tests must extend the class Selenium2TestCase. This class provides several methods to configure your Selenium session, that you will use in your setUp method:

  • setHost
  • setBrowser
  • setBrowserUrl

Selenium2TestCase also provides several methods to select an element on the page:

  • byId
  • byName
  • byXPath
  • byClassName
  • byLinkText
  • ...

Then you can either inspect or interact with the element with following methods:

  • text
  • value
  • click
  • name
  • submit
  • ...

Running tests locally

As you might recall from our previous blog post about Selenium, Selenium is actually a server that can control and drive a real web browser. The easiest way to run Selenium is using docker. In the command below, we will run Selenium together with an instance of the Chrome web browser:

docker run -d -p 4444:4444 --shm-size 2g selenium/standalone-chrome:3.141.59-20210311

Once Selenium is up and running, you can run your PHPUnit tests:

./vendor/bin/phpunit -c phpunit-selenium.xml -v

GitLab

Finally, you can integrate this test in your GitLab pipeline by adding the following job to your .gitlab-ci.yml. You should modify the stage value such that your test takes place after the new code has been deployed to your staging environment:

staging:selenium:
  stage: staging-test
  image: cylab/php74
  services:
    - selenium/standalone-chrome:3.141.59-20210311
  before_script:
    - composer install
  script:
    - SELENIUM_HOST="selenium-standalone-chrome" vendor/bin/phpunit -c phpunit-selenium.xml -v