Automate Unit testing of Javascripts with Karma Runner

The problem :

Working on TDD/BDD method with Javascripts is more tricky than with Java language. In the Java world you have Junit to test your unit tests and maven to execute all of them and create easily reports in Jenkins. In the Javascript world  the equivalent to run Junit is Qunit,Jasmine, Mocha . There is more tools because there is more complexity and these tools do not work perfectly . Not only you have different style of Unit testing but also different Test runner too. In Java you used just the one given by default.

Initially I was using Qunit with a maven plugin to run the tests. But it meant i could not use Jasmine 2 or Mocha. Qunit has limitations too that’s why i moved to Jasmine 2.0.

Now I use Karma test runner to run the Jasmine Unit Tests . But i can also run Qunit tests if I would like to. Karma is really flexible and can also run Mocha. It can also exclude or include some files to test them.  The other complexity of Javascript testing is the browser. Indeed Javascript can be run inside the Chrome,Firefox, Internet Explorer Browsers . For CI testing I used a headless browser called PhantomJs.

Also, Karma has a plugin to analyse Javascript code coverage.
This is the  best generic tool runner i found so far to run Javascript unit tests.

The solution :

I will present the solution I implemented to launch Javascript tests from Jenkins platform. Karma is launched From Jenkins. Also Karma is configured to find Javascripts Jasmine tests and generate a Junit report style, code coverage report.

Realise Unit test with Jasmine 2.0

You need to write specification .spec file describing the test. Example for CommonUtilSpec.js

describe("CommonUtil", function() {

it("trim testing ", function() {
var trimmed = trimFunc('tri');

expect(trimmed).toBe("tri");
expect(trimmed).not.toBe(null);
});

});

The documentation for Jasmine 2 :http://jasmine.github.io/2.0/introduction.html

Install tools on the Jenkins machine

Install Node.js like in this link :
http://karma-runner.github.io/1.0/intro/installation.html

Get as well yeoman and bower to get javascript packages
https://inviqa.com/blog/testing-javascript-get-started-jasmine-0

NOTE : Bower is an equivalent de maven pour javascript http://stackoverflow.com/questions/12334346/dependency-management-and-build-tool-for-javascript

Configure Karma configuration for Jenkins

I have used the following link to configure Karma for Jenkins https://karma-runner.github.io/1.0/plus/jenkins.html. The configuration for Karma of this link have compilation errors.

I have installed EnvInject in order to specify some environment variables for Jenkins.

Configure Karma for Jenkins. I have used the information for the junit reporter at https://www.npmjs.com/package/karma-junit-reporter . It does junit style unit test reporting. It is very practical. I have also used the coverage plugin in order to know which part of the code have been tested https://www.npmjs.com/package/karma-coverage .

The content of my file :

module.exports = function(config) {
config.set({

// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',

// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],

// list of files / patterns to load in the browser
files: [
'/myproject/src/test/**/*.js',
'/myproject/src/main/Javascripts/commonUtil.js'
],

// list of files to exclude
exclude: [
],

// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'/myproject/src/main/**/*.js' : ['coverage']
},

// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter

reporters: ['progress', 'junit','coverage'],

// the default configuration
junitReporter: {
outputDir: '', // results will be saved as $outputDir/$browserName.xml
outputFile: 'test_jasmine_js.xml', // if included, results will be saved as $outputDir/$browserName/$outputFile
suite: '', // suite will become the package name attribute in xml testsuite element
useBrowserName: true, // add browser name to report and classes names
nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element
classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element
properties: {} // key value pair of properties to add to the section of the report
},

// web server port
port: 9876,

// enable / disable colors in the output (reporters and logs)
colors: true,

// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,

// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,

// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],

plugins : [
'karma-phantomjs-launcher',
'karma-jasmine',
'karma-html-reporter',
'karma-junit-reporter',
'karma-coverage'
],

// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,

// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}

Configure and launch Jenkins

I configured jenkins to launch karma with shell script plugin. This solution is not optimized because the npm plugins are being installed at each launch. These plugins should be installed once.

npm install karma-jasmine --save-dev
npm install jasmine-core --save-dev
npm install karma-phantomjs-launcher --save-dev
npm install karma-junit-reporter --save-dev
npm install karma-jasmine-html-reporter --save-dev
npm install karma-html-reporter --save-dev
cp /home/myuser/myapp my.jenkins.conf.js .
karma start my.jenkins.conf.js

Here is a picture of the configuration in Jenkins :

config_jenkins_karma

Once you have finished the configuration, launch the tests. The result of the report should look like that

result_phantomsjs

The plugin coverage is really neat and show in details where the test were not covered  :

javascript_coverage

 

TROUBLESHOOTING

Erreur 1 : No provider for “framework:jasmine”! (Resolving: framework:jasmine
Correctif : npm install karma-jasmine –save-dev

Erreur 2 : Error: Cannot find module ‘jasmine-core’
Correctif : -npm install ‘jasmine-core –save-dev

Erreur 3 : Cannot load browser “PhantomJS”: it is not registered! Perhaps you are missing some plugin?
Correctif : npm install karma-phantomjs-launcher –save-dev

Erreur 4 : Can not load reporter “junit”,
Correctif :

plugins : [
        'karma-phantomjs-launcher',
        'karma-jasmine',
        'karma-junit-reporter'
    ],

Erreur 5 : Cannot find plugin “karma-junit-reporter
Correctif : -npm install ‘karma-junit-reporter –save-dev

Erreur 6 : reporter.junit Cannot write JUnit xml
Problem was specific to where my conf file was located.The fix was to copy the conf file locally in working directory of the slave.

Advertisements

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