Acceptance tests in a Nodejs application

Reading time ~3 minutes

I'm a big fan of the BDD or ATDD way of developing software, although I'm not clear about the difference between them. You can find a kind of explanation here. So, now that I'm starting to learn Nodejs and AngularJS one of the first things I want to make is discover how can I make acceptance tests with these technologies. This tests can include doing several things like start a node server, fill a database with sample data, etc. I'm following the fantastic Let's code: Test-Driven Javascript from James Shore. In this serie of tutorials, he does end to end tests too. He first uses Phantomjs directly, and after that he makes the same tests using Casperjs. At the end, he prefers Caperjs but the infrastructure for making both kind of tests is the same. Let's take a look. In the nodeunit tests you have to spawn a start a child process calling Casperjs test function, and passing the files with the tests as a parameter.

var casperJsProcess = child_process.spawn("./node_modules/.bin/casperjs", [ "test", "./src/features/shouldShowToDoItems.js" ], {
            stdio: "inherit",
            env: { "PHANTOMJS_EXECUTABLE": "./node_modules/phantomjs/lib/phantom/bin/phantomjs" }
        });
        casperJsProcess.on("exit", function(code) {
            test.equals(code, 0, "CasperJS test failures");
            test.done();
        });

And make all the tests you want in the file you pass as a parameter. For example:

casper.test.begin("simple test", function(test){
        casper.start("http://localhost:8090");
        test.assertTitle("Angular ToDo List", "The title is not the one expected");

        casper.waitForSelector('#todoItemsList', function() {
            test.assertEval(function() {
                return __utils__.findAll(".todoItem").length == 10;
            }, "There aren't 10 results");

        });

        casper.run(function()
        {
            test.done();
        });
    });

The problem with this solution is that, if you have a node module to, for example, fill the database with some sample data, you have to put in the nodeunit test file. That's because Casperjs is not a node module. There is a library to drive Casperjs from Nodejs, but the last update is 10 months old. So, if you need to do something with node modules before your tests are launched, you need to put in the external test file. This implies that, if you need to do something before each test, you have to have a separate file for each Casperjs test and your code could become a mess very quickly. I don't like this approximation, so I tried Protractor, the end-to-end test framework for AngularJS applications. Protractor is a Node program so, it seems more suitable for what I want to do. If you follow the tutorial, you can see that you need a Selenium Server running in order to be able to pass the tests. It has to be a way to automate this. Yes, the solution is gulp and gulp-protractor. Let's see what we have to do. First, install gulp and gulp-protractor for your project:

npm install --save-dev gulp-protractor protractor

Now we need to install the web driver server. Let's do this with this command:

node_modules/protractor/bin/webdriver-manager update

Then, make a gulp task to pass this kind of tests. You have to create a file called gulpfile.js in your project root with this contents.

var gulp = require('gulp'),
    protractor = require('gulp-protractor').protractor;

gulp.task('acceptanceTests', function(){
   return gulp.src('src/features/protractor.js')
       .pipe(protractor({
           configFile: 'protractorConf.js'
       }))
       .on('error', function(e){throw e});
});

gulp.task('default', [], function () {
    gulp.start('acceptanceTests');
});

In this snippet, you are telling protractor which are the test files you want to run, and which is its configuration file. As you can imagine, you need a protractorConf.js file. Create it with this content.

exports.config = {
    seleniumServerJar: 'node_modules/protractor/selenium/selenium-server-standalone-2.42.2.jar'
}

With this configuration you are telling protractor to start the Selenium Server automatically. The server will stop once your tests are done. That's great! And now we can write our tests. Something like this:

describe('simple test', function () {

    //1.- Fill database with data (recreate database or tables if needed)
    var databaseHelper = require('./helpers/databaseHelper');
    databaseHelper.ensureDataBaseIsFilledWithSampleData();

    it('should have a title', function () {
        browser.get('http://juliemr.github.io/protractor-demo/');

        expect(browser.getTitle()).toEqual('Super Calculator');
    });
});

Notice that we are requiring a Node module and we are using it. We cannot do this in a phantom or casper test (or, at least, I don't know how). To run the test just write this in your terminal.

gulp

And you will see your tests passing. That's great! I thing I will use this approximation for my projects. I will keep you up to date with any news. See you soon!

Let’s Code: Test-Driven JavaScript

Let’s Code: Test-Driven JavaScript

 

A simple Azure Function using F#

The other day my friend [Jero](https://twitter.com/jerolba) wrote an [article](http://www.jerolba.com/mujeres-y-hombres-y-serverless/) ex...… Continue reading

Definition of X

Published on March 24, 2017

Cargo cult

Published on March 16, 2017