From 641f4c80989adcf39a6579e2dce25e59698dc33c Mon Sep 17 00:00:00 2001 From: evilaliv3 Date: Tue, 5 May 2015 23:55:35 +0200 Subject: [PATCH] Improve unit testing by means of Coveralls and Saucelabs --- .travis.yml | 10 +++-- Gruntfile.js | 96 ++++++++++++++++++++++++++++++++++++++------- README.md | 5 ++- package.json | 29 +++++++------- test/unittests.html | 24 +++++++++++- 5 files changed, 129 insertions(+), 35 deletions(-) diff --git a/.travis.yml b/.travis.yml index f5632394..eff78b4d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,9 @@ language: node_js node_js: - - "0.10" -before_install: - - npm install -g grunt-cli \ No newline at end of file + - "0.12.2" +before_script: + - npm install -g grunt-cli +script: + - grunt + - grunt test_travis_mocha_coveralls + - grunt test_travis_mocha_saucelabs || true diff --git a/Gruntfile.js b/Gruntfile.js index 4aec8619..ef5ab611 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -37,6 +37,7 @@ module.exports = function(grunt) { }, unittests: { files: { + 'test/openpgp.js': [ './test/src/index.js' ], 'test/lib/unittests-bundle.js': [ './test/unittests.js' ] }, options: { @@ -105,10 +106,29 @@ module.exports = function(grunt) { } } }, + mocha_istanbul: { + coverage: { + src: 'test', + options: { + root: 'node_modules/openpgp', + timeout: 120000, + } + }, + coveralls: { + src: ['test'], + options: { + root: 'node_modules/openpgp', + timeout: 120000, + coverage: true, + reportFormats: ['cobertura','lcovonly'] + } + } + }, mochaTest: { unittests: { options: { - reporter: 'spec' + reporter: 'spec', + timeout: 120000 }, src: [ 'test/unittests.js' ] } @@ -121,6 +141,13 @@ module.exports = function(grunt) { src: ['mocha/mocha.css', 'mocha/mocha.js', 'chai/chai.js'], dest: 'test/lib/' }, + unittests: { + expand: true, + flatten: false, + cwd: './', + src: ['src/**'], + dest: 'test/' + }, zlib: { expand: true, cwd: 'node_modules/zlibjs/bin/', @@ -132,11 +159,43 @@ module.exports = function(grunt) { connect: { dev: { options: { - port: 8588, - base: '.', - keepalive: true + port: 9000, + base: '.' } } + }, + 'saucelabs-mocha': { + all: { + options: { + username: 'openpgpjs', + key: '60ffb656-2346-4b77-81f3-bc435ff4c103', + urls: ['http://127.0.0.1:9000/test/unittests.html'], + build: process.env.TRAVIS_JOB_ID, + testname: 'Sauce Unit Test for openpgpjs', + browsers: [ + { browserName:"firefox", version:"38.0", platform:"Linux" }, + { browserName:"firefox", version:"42.0", platform:"OS X 10.10" }, + { browserName:"firefox", version:"beta", platform:"Windows 10" }, + { browserName:"chrome", version:"38.0", platform:"Linux" }, + { browserName:"chrome", version:"46.0", platform:"OS X 10.10" }, + { browserName:"chrome", version:"beta", platform:"Windows 10" }, + { browserName:"internet explorer", version:"11", platform:"Windows 10" }, + { browserName:"microsoftEdge", version:"20.10240", platform:"Windows 10" }, + { browserName:"safari", version:"8", platform:"OS X 10.10" }, + { browserName:"safari", version:"9", platform:"OS X 10.11" }, + { browserName:"android", version:"4.4", deviceName: "Android Emulator", platform: "Linux" }, + { browserName:"android", version:"5.1", deviceName: "Android Emulator", platform: "Linux" }, + { browserName: "iphone", version:"7.0", deviceName: "iPad Simulator", "device-orientation": "portrait", platform:"OS X 10.10" }, + { browserName: "iphone", version:"9.1", deviceName: "iPad Simulator", "device-orientation": "portrait", platform:"OS X 10.10" } + ], + public: "public", + 'max-duration': 360, + maxRetries: 1, + throttled: 3, + pollInterval: 2000, + statusCheckAttempts: 360 + } + }, } }); @@ -147,10 +206,12 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-jsbeautifier'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-jsdoc'); + grunt.loadNpmTasks('grunt-mocha-istanbul'); grunt.loadNpmTasks('grunt-mocha-test'); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks('grunt-saucelabs'); grunt.registerTask('set_version', function() { if (!version) { @@ -188,16 +249,6 @@ module.exports = function(grunt) { grunt.registerTask('documentation', ['jsdoc']); - // Alias the `mocha_phantomjs` task to run `mocha-phantomjs` - grunt.registerTask('mocha_phantomjs', 'mocha-phantomjs', function () { - var done = this.async(); - var mocha = require('child_process').exec('node_modules/mocha-phantomjs/bin/mocha-phantomjs ./test/unittests.html', function (err) { - done(err); - }); - mocha.stdout.pipe(process.stdout); - mocha.stderr.pipe(process.stderr); - }); - // Alias the `npm_pack` task to run `npm pack` grunt.registerTask('npm_pack', 'npm pack', function () { var done = this.async(); @@ -217,6 +268,21 @@ module.exports = function(grunt) { npm.stderr.pipe(process.stderr); }); + grunt.event.on('coverage', function(lcov, done){ + require('coveralls').handleInput(lcov, function(err){ + if (err) { + return done(err); + } + done(); + }); + }); + // Test/Dev tasks - grunt.registerTask('test', ['copy:npm', 'mochaTest', 'mocha_phantomjs']); + grunt.registerTask('test', ['copy:npm', 'copy:unittests', 'mochaTest']); + grunt.registerTask('coverage', ['default', 'copy:npm', 'copy:unittests', 'mocha_istanbul:coverage']); + grunt.registerTask('coveralls', ['default', 'copy:npm', 'copy:unittests', 'mocha_istanbul:coveralls']); + grunt.registerTask('saucelabs', ['default', 'copy:npm', 'copy:unittests', 'connect', 'saucelabs-mocha']); + grunt.registerTask('test_travis_mocha_coveralls', ['copy:npm', 'copy:unittests', 'mocha_istanbul:coveralls']); + grunt.registerTask('test_travis_mocha_saucelabs', ['copy:npm', 'copy:unittests', 'connect', 'saucelabs-mocha']); + }; diff --git a/README.md b/README.md index a8235ee3..ad906d51 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -[![Build Status](https://travis-ci.org/openpgpjs/openpgpjs.svg?branch=master)](https://travis-ci.org/openpgpjs/openpgpjs) -[![Bountysource](https://www.bountysource.com/badge/team?team_id=10316&style=raised)](https://www.bountysource.com/teams/openpgpjs?utm_source=openpgpjs&utm_medium=shield&utm_campaign=raised) +[![Build Status](https://travis-ci.org/openpgpjs/openpgpjs.svg?branch=master)](https://travis-ci.org/openpgpjs/openpgpjs) [![Coverage Status](https://coveralls.io/repos/openpgpjs/openpgpjs/badge.svg)](https://coveralls.io/r/evilaliv3/openpgpjs) + +[![Saucelabs Test Status](https://saucelabs.com/browser-matrix/openpgpjs)](https://saucelabs.com/u/openpgpjs) OpenPGP.js ========== diff --git a/package.json b/package.json index ff1688ea..1c87fe15 100644 --- a/package.json +++ b/package.json @@ -32,22 +32,23 @@ }, "devDependencies": { "browserify": "~2.35", - "chai": "~1.8.1", - "grunt": "~0.4.2", + "chai": "~2.3.0", + "coveralls": "^2.11.2", + "grunt": "~0.4.5", "grunt-browserify": "~1.2.11", - "grunt-cli": "~0.1.13", - "grunt-contrib-clean": "~0.5.0", - "grunt-contrib-connect": "~0.6.0", - "grunt-contrib-copy": "~0.4.1", + "grunt-contrib-clean": "~0.6.0", + "grunt-contrib-connect": "~0.10.1", + "grunt-contrib-copy": "~0.8.0", "grunt-contrib-jshint": "*", - "grunt-contrib-uglify": "~0.3.2", - "grunt-jsbeautifier": "~0.2.6", + "grunt-contrib-uglify": "~0.9.1", + "grunt-jsbeautifier": "~0.2.10", "grunt-jsdoc": "*", - "grunt-mocha-test": "~0.8.1", - "grunt-text-replace": "~0.3.11", - "mocha": "~1.15.1", - "mocha-phantomjs": "~3.1.6", - "phantomjs": "~1.9.2-5" + "grunt-mocha-istanbul": "^2.4.0", + "grunt-mocha-test": "~0.12.7", + "grunt-saucelabs": "8.6.1", + "grunt-text-replace": "~0.4.0", + "istanbul": "^0.3.13", + "mocha": "~2.2.4" }, "dependencies": { "es6-promise": "^1.0.0", @@ -58,4 +59,4 @@ "type": "git", "url": "https://github.com/openpgpjs/openpgpjs" } -} \ No newline at end of file +} diff --git a/test/unittests.html b/test/unittests.html index 3a0a787b..04929df3 100644 --- a/test/unittests.html +++ b/test/unittests.html @@ -22,7 +22,29 @@ if (window.mochaPhantomJS) { mochaPhantomJS.run(); } else { - mocha.run(); + var runner = mocha.run(); + + var failedTests = []; + + runner.on('end', function(){ + window.mochaResults = runner.stats; + window.mochaResults.reports = failedTests; + }); + + runner.on('fail', logFailure); + + function logFailure(test, err) { + var flattenTitles = function(test) { + var titles = []; + while (test.parent.title) { + titles.push(test.parent.title); + test = test.parent; + } + return titles.reverse(); + }; + + failedTests.push({name: test.title, result: false, message: err.message, stack: err.stack, titles: flattenTitles(test)}); + }; }