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.

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

Over the past few years, I’ve become a firm believer in the value of automated testing, to such a point that I would never contemplate starting a serious project without at least some form of automated testing built in (be it unit testing, or functional testing). Like most, I’d say that my passion for automated testing has not developed from a sheer love of writing tests (although – if that’s you then you are a lucky person!) but rather because of a number of other things – ie. I’m passionate in my dislike of having to test things manually; passionate in my desire to deliver a quality product; and passionate about being able to refactor code without that fear of unknowingly breaking the entire build.

Fortunately for me, my interest in automated testing (fuelled by a automated testing pioneer colleague of mine) arose at the same time as feasible testing tools – such as JUnit for unit testing, and Selenium and Watir for functional testing – started to gain some serious traction, particularly in the J2EE world.

The moment you realise you broke the build

Given that I was then working as a contractor on a large J2EE web application, this allowed for me to really see the how impressive the benefits of automated testing really are (which, and I won’t go into detail here, have serious benefits to the bottom line of a project, robustness of the product, development time and general developer happiness). So much so, that when I moved full time into the world of Javascript at the start of this year I started looking to see what was on offer in this cutting edge new space.

In short, what I found was this – Javascript (particularly Node.js) has a lot of support for unit testing, such as the exceptional Mocha testing framework, but little support for functional testing. While this wasn’t a major issue given the fact that functional testing occurs in the browser, and so it’s just as easy to write tests in Ruby (or C#/Java/insert supported language here) and still get the same outcome. However, call me old fashioned, but if I’m writing a server side application in Javascript, with a client side Javascript application talking to it, being tested by Javascript unit tests – then it stands to reason that my functional tests should be Javascript as well – so imagine my delight when I found WebDriverJS, which provides a Javascript driver for Selenium. More to the point, after a bit of experimentation it became obvious that the WebDriverJS could be easily worked in with Mocha to provide a nice, easy to use (and pretty!) functional test suite.

So over the course of the next couple of days, I’ll be posting a few articles detailing some of the things that I’ve discovered while investigating the functional testing possibilities with Selenium and Javascript through the creation of a sample project. If you’ve had any experience using Selenium (or Watir) with Javascript, or have come across any great resources, then I’d love for you to leave a comment below.

For those interested in having a dig around while waiting, here are some of the resources that I’ve been using:

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.