Run jest test suites in groups?

2019-07-18 20:57发布

问题:

I am writing extensive tests for a new API via jest and supertest. Prior to running the tests, I am setting up a test database and populating it with users:

Test command

jest --forceExit --config src/utils/testing/jest.config.js

jest.config.js

module.exports = {
  rootDir: process.cwd(),

  // Sets up testing database with users
  globalSetup: './src/utils/testing/jest.setup.js',

  // Ensures connection to database for all test suites
  setupTestFrameworkScriptFile: './src/utils/testing/jest.db.js',

}

So I am starting with a database of some users to test on. The problem is this:

Some of my tests rely upon the success of other tests. In this application, users can upload images, and group them into packs. So my grouping endpoint suite depends upon the success of my image upload suite, and so on.

I am well aware many people might say this is bad practice, and that tests should not rely upon other tests. That being said, I would really rather keep all my tests via supertest, and not get into dependency injection, etc. I don't want to have to meticulously set up testing conditions (eg creating a bunch of user images artificially before running the tests), because: (1) this is just duplication of logic, and (2) it increases the possibility of something breaking.

Is there any way to group jest suites? Eg to run suites in order:

jest run creationSuite
jest run modificationSuite

This way, all my "creationSuite" tests could be run simultaneously, and success of all would then trigger the "modificationSuite" to run, etc, in a fail-fast manner.

Alternatively, specifying inside a test suite dependencies on other test suites would be great:

describe('Grouping endpoint', () => {
    // Somehow define deps
    this.dependsOn(uploadSuite)

回答1:

Jest test suites are executed in multiple threads, this is one of its main benefits. Test runs can be completed much faster this way, but test sequence isn't preserved by design.

It's possible to disable this feature with runInBand option.

It's possible to pick tests and suites based on their names with testNamePattern option or based on their paths with testPathPattern option

Since one suite depends on another one, they possibly could be combined into a single suite in the order they are expected to run. They can still reside in different files (make sure they aren't matched by Jest), e.g.:

// foobar.test.js
describe(..., () => {
  require('foo.partial-test.js');
  require('bar.partial-test.js');
});

The problem is this:

Some of my tests rely upon the success of other tests.

This is the real problem here. The approach that relies on previous test state is considered flawed in any kind of automated tests.

I don't want to have to meticulously set up testing conditions (eg creating a bunch of user images artificially before running the tests), because: (1) this is just duplication of logic, and (2) it increases the possibility of something breaking.

There is no need to set up testing conditions (fixtures) artificially. Fixtures can be extracted from existing environment, even from the results of your current tests if you're sure about their quality.

  • Redundancy and tautology naturally occur in automated tests, there's nothing wrong with them. Tests can be made DRYer with proper management of fixtures and shared code.

  • Quite the contrary, errors are always accumulated. A test that created faulty prerequisites may pass but another test will fail, thus creating a debugging conundrum.