Welkom bij Bandhosting.nl,
hosting en webdevelopment.

Selenium logo

Testing your application using Selenium, Chrome/Firefox and Behat on docker-machine

Selenium is an automation tool which you can use to automate testing of your application. It allows you to run instances of Chrome and Firefox locally and perform automated tests against it, with which you can validate if your application does what it should.

We had quite a lot of issues with it in the past when running Selenium 2 in combination with Firefox. Things broke down with every new release of Firefox and needed a lot of time to get things running again. Eventually we pinned Firefox down on our test machine to Firefox 46 and never touched it again.

Luckily Selenium started to release docker containers which combined Firefox/Chrome with a specific version of Selenium making it a lot easier to test stuff. It took us a while to understand how this should interact with our local application development, but in the end we got things running.

Firstly, we created a docker-compose file in which the two docker containers will be loaded locally:

version: '2.1'
# install docker parallels driver: http://kb.parallels.com/en/123356
# to start the docker cluster: docker-compose up -d
# to stop the docker cluster: docker-compose stop
services:
    chrome:
        image: selenium/standalone-chrome:3.7.1-beryllium
        ports:
            - "4444:4444"
        extra_hosts:
         - "test.application.dev:10.211.55.2"
        external_links:
         - "web-api:api.application.dev"
    firefox:
        image: selenium/standalone-firefox:3.7.1-beryllium
        ports:
            - "4445:4444"
        extra_hosts:
         - "test.application.dev:10.211.55.2"
        external_links:
         - "web-api:api.application.dev"
networks:
  default:
    external:
      name: bandhosting

As you can see, we defined two services with the selenium standalone images. This is the docker image that contains Selenium and Chrome/Firefox. The second part is the most relevant part however:

extra_hosts:
         - "test.application.dev:10.211.55.2"

We bind the ip of our local machine (from the docker-machine perspective) as an external host, so that the Chrome instance running in the docker image can access our (locally running) frontend application and browse through it. This will effectively create a host file entry on the docker container.

external_links:
         - "web-api:api.application.dev"

Now, a frontend application normally won't function without a backend. We have that running on another docker instance in the same network, so we can create an external link to it using the docker name.

Taking these two steps, we made sure that our browser running in the docker container can access both the frontend and the backend of the application.

Now we can start writing our tests against it. We use behat for this. To install it we use composer:

{
  "name": "bandhosting/project",
  "type": "project",
  "require-dev": {
    "behat/behat": "^3.4.2",
    "behat/mink": "1.7.*@stable",
    "behat/mink-goutte-driver": "*",
    "behat/mink-extension": "*",
    "behat/mink-selenium2-driver": "*"
  }
}

To be able to execute tests, we'll need the following definition in our behat.yml file:

default:
  autoload: [ %paths.base%/test/behat/contexts ]
  suites:
    default:
      paths:
        - %paths.base%/test/behat/features
      contexts:
        - FeatureContext
      screenshotsDir: %paths.base%/test/behat/screenshots

chrome:
  extensions:
    Behat\MinkExtension:
      base_url: "http://test.bandhosting.dev:4000"
      default_session:  'selenium2'
      browser_name: chrome
      goutte: ~
      selenium2:
        wd_host: 10.211.55.41:4444/wd/hub
        capabilities:
          browser: chrome
          marionette: true
          version: ''

firefox:
  extensions:
    Behat\MinkExtension:
      base_url: "http://test.bandhosting.dev:4000"
      default_session:  'selenium2'
      browser_name: firefox
      goutte: ~
      selenium2:
        wd_host: 10.211.55.41:4445/wd/hub
        capabilities:
          browser: firefox
          marionette: true
          version: ''

In essence, it will point the browser to the correct test url and execute all features from the test/behat/features folder.

The above definition allows us to execute tests using the following commands (one for chrome and one for firefox):

vendor/bin/behat -p chrome
vendor/bin/behat -p firefox

The Behat documentation describes extensively how to write your tests using the Gurkin language. For more information on this, see their documentationa.