Acceptance testing at synyx – Part 3

After showing you how to request a remote browser from a Selenium Grid in the last part its time to put some effort in getting the grid running smoothly. Also, check out the first part of the series for the greater context of this blog post.

Setting up the Grid

As mentioned in part 2, its pretty straight forward to set up a selenium-grid by following the instructions at the Selenium Wiki. This worked out pretty well for us when setting up a simple hub plus node configuration on the dev-machines for evaluation purposes.
But as soon as you use selenium grid in production you probably want to wrap some professional services around this to make your local system administrator happy. Currently we are running the explained setup on a hub-node (server) as well as two virtual machines running the browsers (one ubuntu-based one windows7). But the system is designed to add more nodes as soon as they’re needed. And they will be needed soon, especially because the beloved Internet Explorer comes in so many flavours and tests do not run very fast on them compared to Chrome or even Firefox ;).

The Linux machines

The (virtual) machine running the selenium hub and the one running browsers on ubuntu are linux based machines of course. If you run services on linux-based machines you usually want to have them run as a daemon in background, started automatically upon system boot. So of course this is what I did here. I describe the way this is done on debian / ubuntu systems but this will probably work on other distributions with minimal adjustments.

Starting the Hub

Selenium provides a “runnable” jar file to start the server by something like

$ java -jar selenium-server.jar -role hub
Jan 16, 2013 2:14:39 PM org.openqa.grid.selenium.GridLauncher main
Information: Launching a selenium grid server
2013-01-16 14:14:40.662:INFO:osjs.Server:jetty-7.x.y-SNAPSHOT
...

The server binds itself on the configured port and keeps running until you hit CTRL-C while printing out log statements to STDOUT.
So the first thing I did is wrapp this within a upstart-script that made some stuff configurable and readable (where to log to, which java to use, where is the selenium-jar, the config and so on). I named this script selenium-hub.
For the sake of simplicity I put all my files to /opt/selenium/. This might not be the best “unix-way” but doing so helps me find all the files easily.

$ ls /opt/selenium
hubconfig.json
upstart-selenium-hub
selenium-hub
selenium-server.jar -> selenium-server-standalone-2.26.0.jar
selenium-server-standalone-2.26.0.jar

As you can see I also added some symlinks so that I dont need to adjust my scripts as soon as I upgrade selenium-server jar to a newer version (ln -s selenium-server-standalone-2.26.0.jar selenium-server.jar).
If you want to have a detailed look at the files you can check out the archive containing all scripts I wrote.

Managing the Hub as a service

So the next thing to be done is starting and stopping the services using init-scripts. This is usually done by adding the scripts to /etc/init.d/$servicename.
My upstart-scripts are basically copied from the skeleton-file ubuntu brings (/etc/init.d/skeleton) adjusted for my needs.
This script takes care of managing the pid-file for the process and starting and stopping it correctly. So I put the upstart-script to /opt/selenium and symlinked them to /etc/init.d/. Then the script can be added to the systems runlevels (so that it will be started automatically upon boot).

ln -s /opt/selenium/upstart-selenium-hub /etc/init.d/selenium-hub
update-rc.d selenium-hub defaults

So the hub can be now managed using the “service” command.

$ sudo service selenium-hub status
 * selenium-hub is not running
$ sudo service selenium-hub start
$ sudo service selenium-hub status
 * selenium-hub is running

Doing the same for Nodes

The procedure for nodes is pretty much the same as for the hub but it has some smaller differences:
Our system administration set up the ubuntu machine so that it automatically starts X with unity while automatically logging in the user “synyx” to the desktop. Since this should run the browsers the selenium-server process has to be able to access the display. This is usually done by exporting the correct information to the DISPLAY environment-variable. Also selenium-server needs a system-property where to find the chromedriver binary (see documentation). So I adjusted my start-script and my upstart-script (since it has to access the display its best to run the server as the same user the X-Session belongs to) and added everything new to /opt/selenium and updated my runlevels.
Also we use Vino-server to be able to connect via VNC to the Desktop (and view the browsers working) in case you want to reproduce bugs and so on.

Configuring the grid

Selenium-Server can be configured using command-line arguments or by JSON. I preferred the JSON way and added configuration-files to /opt/selenium/ and added the -nodeConfig /-hubConfig parameter in my start-scripts. Here you configure timeouts, urls and what kind of browsers the instance provides to the grid.
The available parameters as well as defaults can be best looked up at the selenium svn.

Getting some browsers

As soon as the hub is running try to access it with a browser and navigate to its console. Here you can see how many hosts there are, what kind of browsers they supply and so on. Here is an example of a grid with one node providing Firefox and Chrome instances, one providing Internet Explorers.
Console of a Selenium Hub

Context

You request these Browsers using the RemoteWebDriver as described in the last post.
In case you want do to something like this you can find all files I mentioned here to download: synyx-selenium-grid-scripts.tar.gz.
In the upcoming post I will describe how to add a Windows based node to the grid using a similar approach. Ah, and after that one we’re done with the technical stuff and proceed to questions like how do we test, how do we report results and so on…