Preparing a Docker image for running Selenium tests

Sometimes your team members complain about automated tests not working on their computer while you are able to run the automated tests at your end completely fine. We too, at Qxf2, have experienced this issue. Our automated tests run fine at our end but occasionally fail when they run on our colleagues and client machines. Invariably, we trace this sort of failure down to variations in the setup/environment. So we looked to tackle this issue. We decided to build a Docker container for running our Selenium tests. The process was very quick and we decided to help all our fellow testers by sharing how we went about doing it.

This post assumes you already know a little about Docker.

NOTE: If you are just looking for a Docker image, you can skip ‘Step 1. Creating a Dockerfile’ section and directly move on to the step 2 titled as ‘Build/Pull the Docker image’.


Overview:

We will be performing the following steps:
1. Creating a Dockerfile
2. Build/Pull the Docker image
3. Creating a container and running Selenium tests


Step 1. Creating a Dockerfile for running Selenium tests:

To get setup with Docker CE you can refer to this link. To build a Docker image for running our Selenium tests, we needed to perform the following steps:

  1. Pull a Base image
  2. Install Xvfb virtual/headless display
  3. Setup Chrome and Chrome driver
  4. Setup Firefox and Geckodrivers
  5. Install Python 2.7 and Python Pip
  6. Get your project code into image/container and install requirements with help of pip and project requirements.txt file

All the steps except the final one rarely change unless when we decide to change the version of software installed. However, your project code and requirements change frequently. So, we decided to come up with a base image for Selenium which includes the first 5 steps i.e Ubuntu, Chrome with Chrome driver, Firefox with Geckodriver, Xvfb, Python and Python Pip.

We will code these steps into a file called a Dockerfile. A Dockerfile is a text document that contains all the commands a user could execute on the command line to assemble an image. To build the base image for running the Selenium test, we wrote the following Dockerfile.

1. Pull a Base Image
We used Ubuntu 16.04.

#Contents of Dockerfile
#Dockerfile to build an image which supports testing our Qxf2 Page Object Model.
FROM ubuntu
MAINTAINER Qxf2 Services

2. Install Xvfb virtual/headless display

# Essential tools and xvfb
RUN apt-get update && apt-get install -y \
    software-properties-common \
    unzip \
    curl \
    xvfb

3. Setup Chrome and Chrome driver

# Chrome browser to run the tests
RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub -o /tmp/google.pub \
    && cat /tmp/google.pub | apt-key add -; rm /tmp/google.pub \
    && echo 'deb http://dl.google.com/linux/chrome/deb/ stable main' > /etc/apt/sources.list.d/google.list \
    && mkdir -p /usr/share/desktop-directories \
    && apt-get -y update && apt-get install -y google-chrome-stable
# Disable the SUID sandbox so that chrome can launch without being in a privileged container
RUN dpkg-divert --add --rename --divert /opt/google/chrome/google-chrome.real /opt/google/chrome/google-chrome \
    && echo "#!/bin/bash\nexec /opt/google/chrome/google-chrome.real --no-sandbox --disable-setuid-sandbox \"\$@\"" > /opt/google/chrome/google-chrome \
    && chmod 755 /opt/google/chrome/google-chrome
 
# Chrome Driver
RUN mkdir -p /opt/selenium \
    && curl http://chromedriver.storage.googleapis.com/2.30/chromedriver_linux64.zip -o /opt/selenium/chromedriver_linux64.zip \
    && cd /opt/selenium; unzip /opt/selenium/chromedriver_linux64.zip; rm -rf chromedriver_linux64.zip; ln -fs /opt/selenium/chromedriver /usr/local/bin/chromedriver;

4. Setup Firefox and Geckodrivers

# Firefox browser to run the tests
RUN apt-get install -y firefox
 
# Gecko Driver
ENV GECKODRIVER_VERSION 0.16.0
RUN wget --no-verbose -O /tmp/geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v$GECKODRIVER_VERSION/geckodriver-v$GECKODRIVER_VERSION-linux64.tar.gz \
  && rm -rf /opt/geckodriver \
  && tar -C /opt -zxf /tmp/geckodriver.tar.gz \
  && rm /tmp/geckodriver.tar.gz \
  && mv /opt/geckodriver /opt/geckodriver-$GECKODRIVER_VERSION \
  && chmod 755 /opt/geckodriver-$GECKODRIVER_VERSION \
  && ln -fs /opt/geckodriver-$GECKODRIVER_VERSION /usr/bin/geckodriver \
  && ln -fs /opt/geckodriver-$GECKODRIVER_VERSION /usr/bin/wires

5. Install Python 2.7 and Python Pip

# python
RUN apt-get update && apt-get install -y \
    python \
    python-setuptools \
    python-pip

Putting it all together
Our final Dockerfile looks like this:

#Contents of Dockerfile
#Dockerfile to build an image which supports testing our Qxf2 Page Object Model.
FROM ubuntu
MAINTAINER Qxf2 Services
 
# Essential tools and xvfb
RUN apt-get update && apt-get install -y \
    software-properties-common \
    unzip \
    curl \
    xvfb 
 
# Chrome browser to run the tests
RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub -o /tmp/google.pub \
    && cat /tmp/google.pub | apt-key add -; rm /tmp/google.pub \
    && echo 'deb http://dl.google.com/linux/chrome/deb/ stable main' > /etc/apt/sources.list.d/google.list \
    && mkdir -p /usr/share/desktop-directories \
    && apt-get -y update && apt-get install -y google-chrome-stable
# Disable the SUID sandbox so that chrome can launch without being in a privileged container
RUN dpkg-divert --add --rename --divert /opt/google/chrome/google-chrome.real /opt/google/chrome/google-chrome \
    && echo "#!/bin/bash\nexec /opt/google/chrome/google-chrome.real --no-sandbox --disable-setuid-sandbox \"\$@\"" > /opt/google/chrome/google-chrome \
    && chmod 755 /opt/google/chrome/google-chrome
 
# Chrome Driver
RUN mkdir -p /opt/selenium \
    && curl http://chromedriver.storage.googleapis.com/2.30/chromedriver_linux64.zip -o /opt/selenium/chromedriver_linux64.zip \
    && cd /opt/selenium; unzip /opt/selenium/chromedriver_linux64.zip; rm -rf chromedriver_linux64.zip; ln -fs /opt/selenium/chromedriver /usr/local/bin/chromedriver;
 
# Firefox browser to run the tests
RUN apt-get install -y firefox
 
# Gecko Driver
ENV GECKODRIVER_VERSION 0.16.0
RUN wget --no-verbose -O /tmp/geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v$GECKODRIVER_VERSION/geckodriver-v$GECKODRIVER_VERSION-linux64.tar.gz \
  && rm -rf /opt/geckodriver \
  && tar -C /opt -zxf /tmp/geckodriver.tar.gz \
  && rm /tmp/geckodriver.tar.gz \
  && mv /opt/geckodriver /opt/geckodriver-$GECKODRIVER_VERSION \
  && chmod 755 /opt/geckodriver-$GECKODRIVER_VERSION \
  && ln -fs /opt/geckodriver-$GECKODRIVER_VERSION /usr/bin/geckodriver \
  && ln -fs /opt/geckodriver-$GECKODRIVER_VERSION /usr/bin/wires
 
# python
RUN apt-get update && apt-get install -y \
    python \
    python-setuptools \
    python-pip

Step 2. Build/Pull the Docker image:

You can either build your own image using above Dockerfile or you can directly download the image from our Docker Hub repository.

To build the image using above dockerfile, you need to save dockerfile to any directory in your system and use the following command:

docker build -t image_name path/to/dockerfile

To directly download it from our Docker Hub repository, you need to use the following command:

docker pull qxf2rohand/qxf2_pom_essentials

Step 3. Creating a container and running Selenium tests:

We decided to use this image for testing our Qxf2’s open sourced GUI automation framework. We named the image as qxf2_pom_essentials. qxf2_pom_essentials image is capable of running any Python based Selenium tests. To run the Selenium tests using this image, you need to go through following steps:

  1. Create a Docker container out of this image and enter into the container using the following command:
    docker run -it qxf2rohand/qxf2_pom_essentials "/bin/bash"
  2. Export display and enable Xvfb using following 2 commands:
    export DISPLAY=:20
    Xvfb :20 -screen 0 1366x768x16 &
  3. Install Selenium using pip
    pip install selenium
  4. Use any Linux editor you like and add your test inside the container. You can also use the sample Selenium code (selenium_docker.py) given below. This selenium test visits Qxf2 Services website and prints the title.
    # contents of selenium_docker.py
    from selenium import webdriver
     
    driver = webdriver.Firefox()
    driver.get("http://www.qxf2.com")
    print driver.title
    driver.quit()
  5. Run the selenium test using the following command:
    python selenium_docker.py

    The output will be similar to the screenshot shown below.

    Fig. 1 Output of selenium_docker.py

Note: The above steps are only to show you how to use our Docker image. At Qxf2 Services, for testing our Qxf2’s Public Page Object Model we use another Dockerfile which automatically gets our code from GitHub, setup our requirements, run shell script file to enable Xvfb and run the test.


To know more about how to get your code inside the container and run the test, please stay tuned. We will post about it soon. Until then enjoy running your tests anywhere without thinking about environment set up using this Docker image. Happy testing!

A weekly newsletter for testers


View a sample



Rohan Dudam
I love technology and learning new things. I explore both hardware and software. I am passionate about robotics and embedded systems which motivate me to develop my software and hardware skills. I have good knowledge of Python, Selenium, Arduino, C and hardware design. I have developed several robots and participated in robotics competitions. I am constantly exploring new test ideas and test tools for software and hardware. At Qxf2, I am working on developing hardware tools for automated tests ala Tapster. Incidentally, I created Qxf2’s first robot. Besides testing, I like playing cricket, badminton and developing embedded gadget for fun.

© 2013-2017, Rohan Dudam. All rights reserved.

Be First to Comment

Leave a Reply

Your email address will not be published.