Build a basic framework for functional testing

This commit is contained in:
Rowan Manning
2013-11-20 16:14:21 +00:00
parent 9d72e50b4e
commit 623a52e112
9 changed files with 143 additions and 5 deletions

1
.gitignore vendored
View File

@@ -2,6 +2,7 @@
# Config files
config/development.json
config/production.json
config/test.json
# Generated npm files
node_modules

View File

@@ -34,6 +34,15 @@ module.exports = function (grunt) {
}
},
mochaTest: {
functional: {
src: ['test/functional/*.js'],
options: {
reporter: 'spec'
}
}
},
nodemon: {
development: {
options: {
@@ -43,6 +52,15 @@ module.exports = function (grunt) {
NODE_ENV: 'development'
}
}
},
test: {
options: {
cwd: __dirname,
file: 'index.js',
env: {
NODE_ENV: 'test'
}
}
}
},
@@ -84,12 +102,15 @@ module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-mocha-test');
grunt.loadNpmTasks('grunt-nodemon');
grunt.registerTask('lint', ['jshint']);
grunt.registerTask('test', ['mochaTest']);
grunt.registerTask('compile', ['less', 'uglify']);
grunt.registerTask('start', ['nodemon:development']);
grunt.registerTask('default', ['compile', 'lint']);
grunt.registerTask('ci', ['compile', 'lint']);
grunt.registerTask('start-test', ['nodemon:test']);
grunt.registerTask('default', ['compile', 'lint', 'test']);
grunt.registerTask('ci', ['lint', 'test']);
};

View File

@@ -1,5 +1,4 @@
{
"webservice": "http://localhost:3000/",
"port": 4000,
"noindex": true,
"readonly": false,

12
config/test.sample.json Normal file
View File

@@ -0,0 +1,12 @@
{
"port": 4000,
"noindex": true,
"readonly": false,
"webservice": {
"database": "mongodb://localhost/pa11y-webservice-test",
"host": "0.0.0.0",
"port": 3000,
"cron": "0 30 0 * * *"
}
}

View File

@@ -36,7 +36,11 @@
"grunt-contrib-less": "~0.8",
"grunt-contrib-uglify": "~0.2",
"grunt-contrib-watch": "~0.5",
"grunt-nodemon": "~0.1"
"grunt-mocha-test": "~0.7",
"grunt-nodemon": "~0.1",
"jsdom": "~0.8",
"proclaim": "~2.0",
"request": "~2.27"
},
"scripts": {

View File

@@ -0,0 +1,44 @@
'use strict';
var jsdom = require('jsdom');
var request = require('request');
module.exports = createNavigator;
// Create a navigate function
function createNavigator (baseUrl, store) {
return function (opts, callback) {
store.body = null;
store.dom = null;
store.request = null;
store.response = null;
store.status = null;
store.window = null;
request({
url: baseUrl + opts.endpoint,
method: opts.method || 'GET',
body: opts.body,
json: true,
qs: opts.query
}, function (err, res, body) {
store.body = body;
store.request = res.request;
store.response = res;
store.status = res.statusCode;
jsdom.env(
store.body,
function (err, window) {
store.window = window;
store.dom = window.document;
callback();
}
);
});
};
}

31
test/functional/index.js Normal file
View File

@@ -0,0 +1,31 @@
/* global beforeEach, describe, it */
/* jshint maxlen: 200, maxstatements: 20 */
'use strict';
var assert = require('proclaim');
describe('GET /', function () {
describe('with no query', function () {
beforeEach(function (done) {
var req = {
method: 'GET',
endpoint: '/'
};
this.navigate(req, done);
});
it('should send a 200 status', function () {
assert.strictEqual(this.last.status, 200);
});
it('should have an "Add new URL" button', function () {
var elem = this.last.dom.querySelectorAll('[data-test=add-task]');
assert.strictEqual(elem.length, 1);
assert.strictEqual(elem[0].getAttribute('href'), '/new');
});
});
});

26
test/functional/setup.js Normal file
View File

@@ -0,0 +1,26 @@
/* global before */
/* jshint maxlen: 200 */
'use strict';
var config = require('../../config/test.json');
var createNavigator = require('./helper/navigate');
var request = require('request');
// Run before all tests
before(function (done) {
this.baseUrl = 'http://localhost:' + config.port;
this.last = {};
this.navigate = createNavigator(this.baseUrl, this.last);
assertTestAppIsRunning(this.baseUrl, done);
});
// Check that the test application is running, and exit if not
function assertTestAppIsRunning (url, done) {
request(url, function (err) {
if (err) {
console.error('Error: Test app not started; run with `grunt start-test`');
process.exit(1);
}
done();
});
}

View File

@@ -8,7 +8,7 @@
<p class="supersize-me crunch">+</p>
</span>
{{else}}
<a class="well task-card-link crunch-bottom" data-role="add-task" href="/new">
<a class="well task-card-link crunch-bottom" data-role="add-task" href="/new" data-test="add-task">
<p class="h3 crunch">Add new URL</p>
<p class="supersize-me crunch">+</p>
</a>