Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to run some tests sequentially with Jest?

Tags:

Jest runs your test suite in parallel by default, but there is a flag (--runInBand) that allows you to run the whole suite sequentially (as pointed out here)

I have some tests that cannot run in parallel, but running the whole suite sequentially takes a lot longer in total, so my question is if there is way to only run some tests that way (such as setting a flag for those tests or something similar).

like image 408
Mario F Avatar asked Nov 14 '17 16:11

Mario F


1 Answers

I too needed the same functionality. I have a large set of Jest integration test suites I want to run. However, some can't be run in parallel due to the need of setup and teardown of a shared resource. So, here is the solution I came up with.

I updated my package.json scripts from:

{   ...   "scripts": {     ...     "test": "npm run test:unit && npm run test:integration",     "test:integration": "jest --config=__tests__/integration/jest.config.js",     "test:unit": "jest --config=__tests__/unit/jest.config.js"   },   ... } 

to

{   ...   "scripts": {     ...     "test": "npm run test:unit && npm run test:integration",     "test:integration": "npm run test:integration:sequential && npm run test:integration:parallel",     "test:integration:parallel": "jest --config=__tests__/integration/jest.config.js",     "test:integration:sequential": "jest --config=__tests__/integration/jest.config.js --runInBand",     "test:unit": "jest --config=__tests__/unit/jest.config.js"   },   ... } 

Then I updated __tests__/integration/jest.config.js from

module.exports = {   // Note: rootDir is relative to the directory containing this file.   rootDir: './src',   setupFiles: [     '../setup.js',   ],   testPathIgnorePatterns: [     ...   ], }; 

to

const Path = require('path');  const { defaults } = require('jest-config'); const klawSync = require('klaw-sync') const mm = require('micromatch');  // Note: rootDir is relative to the directory containing this file. const rootDir = './src'; const { testMatch } = defaults;  // TODO: Add the paths to the test suites that need to be run // sequentially to this array. const sequentialTestPathMatchPatterns = [   '<rootDir>/TestSuite1ToRunSequentially.spec.js',   '<rootDir>/TestSuite2ToRunSequentially.spec.js',   ... ];  const parallelTestPathIgnorePatterns = [   ... ];  let testPathIgnorePatterns = [   ...parallelTestPathIgnorePatterns,   ...sequentialTestPathMatchPatterns, ];  const sequential = process.argv.includes('--runInBand'); if (sequential) {   const absRootDir = Path.resolve(__dirname, rootDir);   let filenames = klawSync(absRootDir, { nodir: true })     .map(file => file.path)     .map(file => file.replace(absRootDir, ''))     .map(file => file.replace(/\\/g, '/'))     .map(file => '<rootDir>' + file);   filenames = mm(filenames, testMatch);   testPathIgnorePatterns = mm.not(filenames, sequentialTestPathMatchPatterns); }  module.exports = {   rootDir,   setupFiles: [     '../setup.js',   ],   testMatch,   testPathIgnorePatterns, }; 

The updated jest.config.js depends on jest-config, klaw-sync, and micromatch.

npm install --save-dev jest-config klaw-sync micromatch 

Now, you can run npm run test:integration:sequential if you only want to run the tests that need to be run sequentially.

Or run npm run test:integration:parallel for the parallel tests.

Or run npm run test:integration to first run the sequential tests. Then when that is finished, the parallel tests will run.

Or run npm run test to run both the unit and integration tests.

Note: The directory structure I am using with my unit and integration tests is as follows:

__tests__   integration     src       *.spec.js       *.test.js     jest.config.js   unit     src       *.spec.js       *.test.js     jest.config.js 
like image 181
Danny Hurlburt Avatar answered Sep 25 '22 07:09

Danny Hurlburt