Automated functional testing with Javascript using Mocha and Selenium [Part 2]

(This is the second installment in my series on the basics of how to use Selenium and Mocha to perform functional tests on your web applications. For the previous article, click here.)

In today’s post, we’ll using Mocha and Selenium to test a basic sample application. Before getting into that however, you will need to download a few things:

Step 1: Install Node JS

If you haven’t already, install Node JS by following the instructions on http://nodejs.org/.

Step 2: Download Selenium

Selenium is a tool that automates web browsers, allowing us to run our functional tests against a real instance of a browser. It currently supports a number of versions of Internet Explorer, Firefox, as well as Google Chrome and Opera (although some of these require third party written code – for a full supported list of browsers go to here). At the core of how Selenium works is the Selenium Server, which is responsible for the execution of automation commands to the browser. A Selenium client can then connect to the server, and instruct it to perform a variety of different actions (ie. clicking a button, going to a URL, etc) or to retrieve information about the current state of the browser (such as using CSS selectors to retrieve elements, inspect text, and so on). The real advantage to this is that it allows for language specific clients (or WebDrivers) which allow for automation scripts to be written in a developer’s (or tester’s) language of choice, be it Ruby, Java, Python, C# or now, thanks to the experiemental WebDriverJS client, Javascript.

For the purposes of this article, you will to download the Selenium Server from the Selenium downloads page, and assuming that you have Java installed, you can then fire it up by running -

java -jar <path to the Selenium JAR file>

You should see the Selenium server load up, and be ready to start serving tests.

Step 3: Get the sample application

Now that we’ve got the base dependencies installed, you can either checkout my example project from my GitHub repository, or create your own simple application to test. My sample application is a very simple Express application running on Node, which we’ll be testing using Selenium and Mocha.

Before running the application, you’ll first have to install the module dependencies. This is done through the use of NPM (Node Package Manager – an exceptional tool for managing dependencies which is included with the Node JS installation) by running -

npm install

Once the dependencies, you can start up the application server by running -

node app.js

Navigate to http://localhost:3000 and you should see the application running as in the image below.

It is a very simple ‘Library’ index application – it consists of a home page, a books page with a list of books, and an authors page, with a list of authors. Links on each of the pages control the user’s navigation.

Before we get onto writing the tests proper, there were a few modules that were installed by NPM that are worth knowing about at this point.

Mocha

Mocha is an exceptional test framework for Node.js (as well as browser based) testing developed by TJ Holowaychuk – author of the Express web framework for Node. It allows for a comprehensive suite of test functionality and reporting that makes writing tests almost enjoyable – not quite, but about as close as you can get! While I have indicated that Mocha is to be installed as a development dependency of my sample application, you can also install it manually using the following command -

npm install mocha (or npm install -g mocha to install to the global NPM repository)


Chai

Once we have Mocha, we can also choose an assertion library to allow us to evaluate our test assertions – my personal favourite is Chai, which allows for BDD/TDD style assertions and works well with Mocha. Chai can be installed via NPM as well, using the following command:

npm install chai 

WebdriverJS

As mentioned in my first article, to communicate with the Selenium server from Javascript, you have a number of choices. The first is to take advantage of the WebDriverJS web driver for Selenium. In order to use this driver, you will have to checkout the Selenium source code from the SVN repository, and then build the WebDriverJS by following the instructions on the wiki.

The second one I’ll mention, and the one that we will use for the remainder of this article, is the webdriverjs NPM module written by Camilo Tapia, which utilizes the Selenium JSON Wire Protocol to communicate with the Selenium server.

There are few reasons as to why I chose the Camilo’s module over the standard WebDriverJS module. Primarily however, I believe that tests should be as easy to write as possible, and while the same functionality is present in both, Camilo’s module makes writing tests, and adding custom functionality a much more pleasant experience than the verbosity involved with working with the standard WebDriverJS module.

Step 4: Run some Selenium tests

So now that we’ve got our application all up and running, let’s run some tests to test that it’s working correctly. We’ll run one of the tests that’s included with the sample project – simple_test.js. This test will simply navigate to the page, and test to see if the title equals ‘Library’. To run the test, use the following command from the root directory of the sample project:

mocha tests/simple_test.js -t 30000

You should see the application fire up in Firefox (this can be configured to other browsers), and you should see Mocha complete the test successfully. If you find that Firefox takes a while to start up, and Mocha times the test out before completing successfully, you may have to increase the value of -t in the above command. (the value is in milliseconds so 30000 = 30 seconds)

Let’s take a look at the guts of this test to see what’s happening:


before(function(done) {
// Add some helper commands
client.addCommand('hasText', function(selector, text, callback) {
this.getText(selector, function(result) {
expect(result.value).to.have.string(text);
callback();
});
});
done();
 });

The before() function in Mocha allows us to setup code that runs before the tests are run. In this instance, we are using it to add a custom command to the webdriverjs client to allow it to have a .hasText function that will use Selenium to get the text of an element on the page, and then use a Chai assertion to assert whether it is the value we expected or not.

beforeEach(function(done) {
  // Navigate to the URL for each test
  client.init();
  client.url('http://localhost:3000', done);
});

The beforeEach function get’s executed before each test is run. In this case, it sets up the webdriverjs client, and instructs it to go to the application URL before actually starting the test.

it('should be able to view the home page', function(done) {
  this.timeout(10000);
  client.hasText('#title', 'Library');
  done();
});

The code above forms the actual content of the test. The this.timeout function instructs Mocha that it should fail the test if it hasn’t finished within 10 seconds. We then use the .hasText function that we added in the before() function to assert that the title element has the text ‘Library’. If it didn’t have the matching text, the test would have failed.

afterEach(function(done) {
  client.end();
  done();
});

After the test has finished (or failed), Mocha runs the afterEach function, which we use to clean up the Selenium sessions that were created over the course of the tests.

And that’s it – a Mocha test that uses Selenium to test a web application in the browser!

What next?

This has been a very simple demonstration of Mocha and Selenium and of course, any real test would be expected to do things like clicking links, uploading files, waiting for elements to appear/disappear – all of which is possible. For starters, if you are interested, you may wish to check out the slightly more complicated page_test.js file in the repository, which tests the navigation of the sample application.

Alternatively, additional reading resources can be found at:

If you have any questions, please feel free to leave a comment below and I’ll attempt to get back to you when I can.

If this article has interested you, you may wish to follow me on Twitter (@noehlman), or you may wish to browse the random collections of code on my GitHub repository.

About these ads

3 thoughts on “Automated functional testing with Javascript using Mocha and Selenium [Part 2]

  1. Awesome article, Thanks very much!
    I have a question, in your last example, when test fails which throws up expectation failed exception, it seems that the exception broke the ‘client’ and as a result the ‘client’ wouldn’t end() in the teardown.
    Also did you mean
    client.hasText(‘#title’, ‘Library’, done)
    rather than
    client.hasText(‘#title’, ‘Library’);
    done();
    ?
    Thanks

  2. Great tuto, you made good choices for your techno !
    Explanations for installs, references : very good.
    But you have an error in you exemple on github in simple_test.js
    you put :
    it(‘should be able to view the home page’, function(done) {
    this.timeout(10000);
    client.hasText(‘#title’, ‘Library’);
    done();
    });

    but it should be :
    it(‘should be able to view the home page’, function(done) {
    this.timeout(10000);
    client.hasText(‘#title’, ‘Library’, done);
    });

    (with your syntax, even if you put
    client.hasText(‘#title’, ‘FOO’);
    the test will succeed)

    Thx for your effort !
    Ben

  3. Pingback: mocha “Cannot find firefox binary in PATH” | erisianesque

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s