Recently, with GitLab Version 8.0 released in September 2015, GitLab Inc. included CI-functionality in GitLab.
We here at CosmoCode use GitLab since what feels like ages and hence, we are happy to embrace that new functionality and move our automated integration and regression testing from our Jenkins-server to GitLab CI.
One of the first things we implemented was support for our JavaScript testing with QUnit. As the runner for this task we chose to use a minimal docker container with the latest debian and git: samueldebruyn/debian-git.
However QUnit is designed to run in the browser by default, hence we need to go few extra steps to convince it to play nice with GitLab.
QUnit and the headless browser
The solution we chose is implemented with Grunt and by dependency PhantomJS. These are, if you happen to not know them, a JavaScript task runner and a headless WebKit "Browser" respectively.
We will install most of our dependencies with the node package manager npm. So the first thing we need is to declare those dependencies in a package.json:
{
"name": "my-package",
"devDependencies": {
"grunt": "^0.4.5",
"grunt-contrib-qunit": "^0.7.0",
"qunitjs": "^1.20.0",
"grunt-cli": "^0.1.13"
}
}
PhantomJS is a dependency of the Grunt QUnit plugin, so there is no need to specify it explicitly.
The tests are started by grunt, hence we need to tell it what to do by supplying the instructions in a Gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
qunit: {
all: ['_jstest/*.html']
}
});
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.registerTask('default', ['qunit']);
};
Here we tell Grunt to run the QUnit tests by default when just grunt
is invoked on the command-line.
However now we need to tell QUnit to use the local QUnit library we defined above if it is available. So by slightly modifying the minimal example:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>QUnit Example</title>
<link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.20.0.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="../node_modules/qunitjs/qunit/qunit.js"></script>
<script>window.QUnit || document.write('<script src="//code.jquery.com/qunit/qunit-1.20.0.js"><\/script>')</script>
<script src="tests.js"></script>
</body>
</html>
We now have QUnit test setup which both works when opened in browser and when invoked on the command-line via grunt
.
GitLab CI
Assuming that you have already configured the docker-runner for your project, the only step that remains is telling GitLab CI about our tests and how they should be run. The file that does that is .gitlab-ci.yml
. Unfortunately it's not as trivial as “install our dependencies from npm and then run grunt” (Though actually it is). We still need to work around a few debian issues first:
before_script:
- apt-get update
- apt-get install --assume-yes npm nodejs libfreetype6 libfontconfig1
- cd ~
- mkdir bin
- ln -s `which nodejs` bin/node
- export PATH=~/bin:$PATH
- cd -
- npm install
- export PATH=./node_modules/grunt-cli/bin/:$PATH
jobname:
script:
- grunt
Here we install npm and Node.js and a few dependencies of PhantomJS. However due to a naming collision in debian, the Node.js executable is called nodejs
instead of node
as expected by npm. So in order to fix this issue we are creating a symlink with the name node
and point it to the executable nodejs
. After we have added the location of this link to $PATH, we can continue with our original plan: install the dependencies via npm and run the tests via Grunt.