Load Testing with Cucumber PhantomJS and Docker Swarm, Part 1
08 Feb 2015Historically load testing had been pretty straightforward. Get a list of urls usually from the weblogs and use tools like Siege, Apache Benchmark and JMeter and your off to the races. This is a valid approach for load testing webservices or sites with that don’t do alot of javascript rendering, but javascript heavy sites change the dynamics of your load testing. Load tests need to open a browser, render the javascript and click on widgets. This two part blog is a simple example of creating load with Cucumber PhantomJS and an array of asynchronous clients on Docker containers.
For development I’m used Ubuntu 13.10 but also have it working with MacOS X Yosemite. I’ll also be referencing my phantomjs-load repo which has the complete code, individual sections will reference particular tags as the project evolves.
Part 1 describes the initial setup with all the major components working and a simple test. Part 2 uses the tests with Docker Swarm to create load with X clients running tests for X duration.
Getting Started w/ Cucumber and PhantomJS
Initially we will setup to run Cucumber and PhantomJS locally. This setup was heavily inspired by Bastan Krol’s blog on the same subject, https://blog.codecentric.de/en/2013/08/cucumber-capybara-poltergeist.
Ruby 2.1 - Assumes Ruby 2.1, haven’t tested with other versions.
PhantomJS - I’ve installed PhantomJS successfully with npm, keep in mind if you use a more recent version of Ubuntu you’ll need to symbolic link /usr/bin/node to /usr/bin/nodejs.
npm install -g phantomjs
If your having issues installing, reference the Dockerfile for various dependencies to successfully install. With the MacOS X brew install phantomjs
worked fine. The following is a snippet on how to install on Ubuntu 14.04
RUN apt-get install -y \
software-properties-common \
python-software-properties
RUN apt-add-repository ppa:brightbox/ruby-ng -y
RUN apt-get update
RUN apt-get install -y \
ruby2.1 \
ruby2.1-dev \
build-essential \
zlib1g-dev \
libxslt-dev \
libxml2-dev \
npm \
libfreetype6 \
libfontconfig
RUN ln -s /usr/bin/nodejs /usr/bin/node
RUN gem install bundler
RUN npm install -g phantomjs
Once installed test and make sure Cucumber is working headless and IN_BROWSER.
bundle
The the following two commands will visit Google News, click on Sports section and assert the text “Sports scores” exists.
bundle exec cucumber
IN_BROWSER=true bundle exec cucumber
NOTE: Initially this didn’t work with Firefox 35, so you may need to downgrade to Firefox 34 to get the Selenium driver working.
Docker
Docker Swarm requires the host’s containers to have Docker 1.4.1 installed, if you previously installed docker you’ll need to reinstall.
sudo su
curl https://get.docker.io/gpg | apt-key add -
echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list
sudo apt-get update
apt-get install lxc-docker
docker -v
MacOS X’s boot2docker installs docker 1.4.1 as well.
boot2docker init
boot2docker start
$(boot2docker shellinit)
Next we’ll build the image and run tests in the container.
./docker_build.sh
...
docker run -i -t keekdageek/phantomjs-load bundle exec cucumber
⏎
@javascript
Feature: Google News Example
As a user
I view google news sports
so that I get the latest chisme
Scenario: Google news sports # features/hello_world/google_news.feature:6
Given I visit "http://news.google.com" # features/step_definitions/base_steps.rb:2
useractiontype: load
When I click "Sports" # features/step_definitions/base_steps.rb:6
Then I should see "Sports scores" # features/step_definitions/base_steps.rb:10
1 scenario (1 passed)
3 steps (3 passed)
0m2.306s
Now Cucumber, PhantomJS and Docker are working in harmony locally. In the next Part we’ll integrate Docker Swarm and an example of inducing load with cucumber tests or a command line.