Commit a9fe3c0a authored by Robert Knight's avatar Robert Knight

Reduce test startup time when running a subset of tests

Change the way that the `FILTER` option works in `make test FILTER=<pattern>`
(or equivalently the `--grep` option if using `gulp test --grep
<pattern>`) to control which test files are executed rather than
matching test descriptions.

This enables the test configuration function in `src/karma.config.js` to
limit the test bundle to only the matching files and their dependencies.
This can make the initial bundling much faster and bundle updates (when
using `make servetests`) somewhat faster.

On my system, `make test FILTER=menu-item` takes ~40s on master but only
~7s on this branch.

As before, the filename filter can be combined with the `.only` modifier
on `description` or `it` calls to do more fine-grained filtering of
tests within matching files.

 - Change `--grep` option to gulp to filter test files as part of the
   test bundling process instead of setting the `grep` mocha option

 - Make `make servetests` accept a `FILTER` argument for consistency
   with `make test`

 - Simplify code in gulpfile.js for launching Karma

 - Update documentation for `make test`
parent b0cd5378
...@@ -29,7 +29,11 @@ endif ...@@ -29,7 +29,11 @@ endif
.PHONY: servetests .PHONY: servetests
servetests: node_modules/.uptodate servetests: node_modules/.uptodate
ifdef FILTER
node_modules/.bin/gulp test-watch --grep $(FILTER)
else
node_modules/.bin/gulp test-watch node_modules/.bin/gulp test-watch
endif
.PHONY: lint .PHONY: lint
lint: node_modules/.uptodate lint: node_modules/.uptodate
......
...@@ -110,8 +110,7 @@ Hypothesis uses Karma and mocha for testing. To run all the tests once, run: ...@@ -110,8 +110,7 @@ Hypothesis uses Karma and mocha for testing. To run all the tests once, run:
make test make test
You can filter the tests which are run by running ``make test FILTER=<pattern>``. You can filter the tests which are run by running ``make test FILTER=<pattern>``.
See the documentation for Mocha's Only test files matching ``<pattern>`` will be executed.
`grep <https://mochajs.org/#g---grep-pattern>`_ option.
To run tests and automatically re-run them whenever any source files change, run: To run tests and automatically re-run them whenever any source files change, run:
......
...@@ -36,15 +36,12 @@ let liveReloadChangedFiles = []; ...@@ -36,15 +36,12 @@ let liveReloadChangedFiles = [];
function parseCommandLine() { function parseCommandLine() {
commander commander
// Test configuration. .option(
// See https://github.com/karma-runner/karma-mocha#configuration '--grep [pattern]',
.option('--grep [pattern]', 'Run only tests matching a given pattern') 'Run only tests where filename matches a pattern'
)
.parse(process.argv); .parse(process.argv);
if (commander.grep) {
gulpUtil.log(`Running tests matching pattern /${commander.grep}/`);
}
return { return {
grep: commander.grep, grep: commander.grep,
}; };
...@@ -384,37 +381,20 @@ gulp.task( ...@@ -384,37 +381,20 @@ gulp.task(
) )
); );
function runKarma(baseConfig, opts, done) { function runKarma({ singleRun }, done) {
// See https://github.com/karma-runner/karma-mocha#configuration
const cliOpts = {
client: {
mocha: {
grep: taskArgs.grep,
},
},
};
const karma = require('karma'); const karma = require('karma');
new karma.Server( new karma.Server(
Object.assign(
{},
{ {
configFile: path.resolve(__dirname, baseConfig), configFile: path.resolve(__dirname, './src/karma.config.js'),
grep: taskArgs.grep,
singleRun,
}, },
cliOpts,
opts
),
done done
).start(); ).start();
} }
gulp.task('test', function(callback) { gulp.task('test', done => runKarma({ singleRun: true }, done));
runKarma('./src/karma.config.js', { singleRun: true }, callback); gulp.task('test-watch', done => runKarma({ singleRun: false }, done));
});
gulp.task('test-watch', function(callback) {
runKarma('./src/karma.config.js', {}, callback);
});
gulp.task( gulp.task(
'upload-sourcemaps', 'upload-sourcemaps',
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
const path = require('path'); const path = require('path');
const envify = require('loose-envify/custom'); const envify = require('loose-envify/custom');
const glob = require('glob');
let chromeFlags = []; let chromeFlags = [];
process.env.CHROME_BIN = require('puppeteer').executablePath(); process.env.CHROME_BIN = require('puppeteer').executablePath();
...@@ -50,6 +51,22 @@ if (process.env.RUNNING_IN_DOCKER) { ...@@ -50,6 +51,22 @@ if (process.env.RUNNING_IN_DOCKER) {
} }
module.exports = function(config) { module.exports = function(config) {
let testFiles = [
'annotator/**/*-test.coffee',
'**/test/*-test.js',
'**/integration/*-test.js',
];
if (config.grep) {
const allFiles = testFiles
.map(pattern => glob.sync(pattern, { cwd: __dirname }))
.flat();
testFiles = allFiles.filter(path => path.match(config.grep));
// eslint-disable-next-line no-console
console.log(`Running tests matching pattern "${config.grep}": `, testFiles);
}
config.set({ config.set({
// base path that will be used to resolve all patterns (eg. files, exclude) // base path that will be used to resolve all patterns (eg. files, exclude)
basePath: './', basePath: './',
...@@ -66,31 +83,13 @@ module.exports = function(config) { ...@@ -66,31 +83,13 @@ module.exports = function(config) {
// Empty HTML file to assist with some tests // Empty HTML file to assist with some tests
{ pattern: './annotator/test/empty.html', watched: false }, { pattern: './annotator/test/empty.html', watched: false },
// Karma watching is disabled for these files because they are // Test modules.
// bundled with karma-browserify which handles watching itself via ...testFiles.map(pattern => ({
// watchify pattern,
// Unit tests
{
pattern: 'annotator/**/*-test.coffee',
watched: false,
included: true,
served: true,
},
{
pattern: '**/test/*-test.js',
watched: false,
included: true,
served: true,
},
// Integration tests // Disable watching because karma-browserify handles this.
{
pattern: '**/integration/*-test.js',
watched: false, watched: false,
included: true, })),
served: true,
},
], ],
// list of files to exclude // list of files to exclude
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment