VGTech is a blog where the developers and devops of Norways most visited website share code and tricks of the trade… Read more



Are you brilliant? We're hiring. Read more

Selenium tests

PHP

When we develop code at VG we have started to use Selenium tests for continuous integration. This allows us to easy write tests that programmatically checks that last commit didn’t break anything.

What is Selenium?
You can look at it like a browser that fires of a set of requests that you asks it to. Sort of like this:

  • Go to vg.no
  • Check that the title is “Forsiden at VG”

Or

  • Go to vg.no
  • Click on the first article
  • Check that the article loads correctly and some elements are present on the page

You can also do more advanced things like triggering a javascript method for show and hide a menu.

  • Go to vg.no
  • Click on menu tab
  • Wait for 500 ms
  • Check that the menu is now visible

So let’s start to write some tests. Ehm, okay, we actually don’t have to write it. We can use Selenium IDE, a Firefox plugin; Awesome!

Skjermbilde 2013-05-15 kl. 11.13.39

 

When the test works okay we can export it to PHP Unit Selenium tests.

Go to File -> Export Test Case As -> PHP (PHPUnit)

This gives you a file like this:

Show code
<?php

class Example extends PHPUnit_Extensions_SeleniumTestCase {   
 protected function setUp()   {     
    $this->setBrowser("*chrome");
    $this->setBrowserUrl("http://vg.no/");
  }

  public function testMyTestCase()
  {
    $this->open("utenriks");
    $lastTwenty = $this->getXpathCount("//section[@class='widget articles imageList section-index']/article");
    $this->click("//a[contains(text(),'Se neste')]");
    sleep(5);
    $this->assertNotEquals($lastTwenty, $this->getXpathCount("//section[@class='widget articles imageList section-index']/article"));
  }
}

}

Here is another example for testing that the menu becomes visible and gets populated with sub menu items:

Show code
<?php

   /**
     * Test menu
     */
    public function testMenu() {
        $this->open("");

        // Click on the menu button
        $this->click("link=MENY");

        // Wait for the ajax call to complete and populate the menu
        usleep(500000);

        // Check that the menu slides down and become visible
        $this->assertTrue($this->isVisible("//div[@id='sectionNavBar']"));

        // Check that first menu include eight sub menu items
        $this->assertEquals("8", $this->getXpathCount("//li[@id='menuItem_0']/ul/li"));

        // Click on sub menu header 1
        $this->click("//li[@id='menuItem_1']/a");

        // Wait for the animation to complete
        usleep(500000);

        // Check that its sub menu is not empty
        $this->assertNotEquals("0", $this->getXpathCount("//li[@id='menuItem_1']/ul/li"));

        // Click on sub menu header 2
        $this->click("//li[@id='menuItem_2']/a");

        // Wait for the animation to complete
        usleep(500000);

        // Check that its sub menu is not empty
        $this->assertNotEquals("0", $this->getXpathCount("//li[@id='menuItem_2']/ul/li"));

        // Click on sub menu header 3
        $this->click("//li[@id='menuItem_3']/a");

        // Wait for the animation to complete
        usleep(500000);

        // Check that its sub menu is not empty
        $this->assertNotEquals("0", $this->getXpathCount("//li[@id='menuItem_3']/ul/li"));

        // Click on sub menu header 4
        $this->click("//li[@id='menuItem_4']/a");

        // Wait for the animation to complete
        usleep(500000);

        // Check that its sub menu is not empty
        $this->assertNotEquals("0", $this->getXpathCount("//li[@id='menuItem_4']/ul/li"));

        // Click on sub menu header 5
        $this->click("//li[@id='menuItem_5']/a");

        // Wait for the animation to complete
        usleep(500000);

        // Check that its sub menu is not empty
        $this->assertNotEquals("0", $this->getXpathCount("//li[@id='menuItem_5']/ul/li"));

        // Close the menu
        $this->click("link=MENY");
}

This is what it looks like when you run the IDE
Skjermbilde 2013-05-29 kl. 14.14.24

Selenium is just great and should really be used whenever integrating new features. Properly designed tests can check and verify that existing interactivity and markup still works as intended when new features are introduced.

Finally, to create a really powerful environment, you should set up Jenkins to automatically start a build and run phpunit tests and Selenium tests for each commit. This will save you a lot of time, by automatically be notified when something unintentionally breaks.

My name is Ole-Kenneth. I'm a web developer at VG.  olekenneth.com @olekenneth


1 comments

  • Matt

    Firstly great article, I've had quite a bit of experience with Selenium but have trouble keeping a database in a constant state in order to run tests over and over again, I was wondering how you accomplish this task and whether or not you can share your experience especially with using it through Jenkins


Leave your comment