Set up Multiple Jest Configs

Here's how to set up multiple Jest configs for different test suites.

Different needs

We have different kinds of tests that we might put in different test suites. Here are potentially two categories:

  1. Unit tests

  2. Integration tests

We want to run them separately, at different times. Let's say that we colocate each kind of test next to the source code that it exercises, named:

  1. *.spec.ts for unit tests

  2. *.integ.spec.ts for integration tests

These test suites have different needs in their configuration. We match the files differently, they might require different setup, the unit tests should be much faster than the integration tests. But there is also a fair amount of overlap in the config for each suite, so we don't want to repeat ourselves. How will we set this up?

Jest Config Inheritance

First, let's set up the common pieces. We might have module name mapping and transpiling that is common for all. We'll put that in a jest.common.config.js file:

module.exports = {
  moduleNameMapper: {
    '^@/app/(.*)$': '<rootDir>/src/app/$1',
    '^@/common/(.*)$': '<rootDir>/src/common/$1',
    '^@/test/(.*)$': '<rootDir>/test/$1',
    '\\.css$': 'identity-obj-proxy',
  },
  transform: {
    '\\.[jt]sx?$': ['babel-jest', { configFile: './babel.config.jest.js' }],
  },
}

Next, we'll take the unit tests. Here, we want all that was common to apply, and we'll add the name matching to find those .spec.ts files and avoid the other suites, in jest.unit.config.js:

const common = require('./jest.common.config.js')

module.exports = {
  ...common,
  testMatch: ['**/*.spec.ts?(x)', '!**/*.integ.spec.ts?(x)'],
}

Finally, we'll set up the integration tests. This suite requires some environmental setup, so we'll run an extra setup file and also give these tests more time to complete, in the jest.integ.config.js:

const common = require('./jest.common.config.js')

module.exports = {
  ...common,
  setupFiles: ['<rootDir>/test/setup-env.js'],
  testMatch: ['**/*.integ.spec.ts?(x)'],
  testTimeout: 10000,
}

Specify the Jest Config

Now at runtime, we can point Jest to the appropriate config file when we invoke it. In npm-scripts, we could write:

"scripts": {
  "test:unit": "jest --config=jest.unit.config.js",
  "test:integ": "jest --config=jest.integ.config.js",
}

Each suite has what it needs, and we don't repeat any common config, but inherit from a shared module.