Jest Setup Guide
Jest Setup Guide
NOTE: This article previously focused on deprecated
jest-jasmine2
runner setup, and if you nevertheless need to access it, follow this Git history link.
This guide describes how to install Jest as a test runner to be used by Detox for running the E2E tests.
Introduction
As already mentioned in the Getting Started guide, Detox itself does not effectively run tests logic, but rather delegates that responsibility onto a test runner. At the moment, Jest is the only recommended choice, for many reasons, including - but not limited to, parallel test suite execution capability, and complete integration with Detox API.
By the way, Jest itself — much like Detox, also does not effectively run any tests. Instead, it is more of a dispatcher and orchestrator of multiple instances of a delegated runner capable of running in parallel. For more info, refer to this video (source: Jest architecture).
For its part, Detox supports only one Jest’s concrete runner, which is jest-circus
(ships by default with Jest since 27.0.0). The former runner, jest-jasmine2
, is deprecated due to specific bugs in the past, and architectural limitations at present.
Installation
Disclaimer:
- Here we focus on installing Detox on new projects. If you’re migrating a project with an existing Detox installation, please apply some common sense while using this guide.
- These instructions are relevant for
jest@^27.0.0
(andjest@^26.0.1 + jest-circus@^26.0.1
). They should likely work for the newerjest
versions too, but for the older ones (25.x, 24.x) — they will not, due to blocking issues.
1. Install Jest
Before starting with Jest setup, be sure to complete the preliminary sections of the Getting Started guide.
Afterward, install the respective npm package:
- npm
- Yarn
- pnpm
npm install -D "jest@>=27.2.5"
yarn add --dev "jest@>=27.2.5"
pnpm add -D "jest@>=27.2.5"
NOTE: The command will install the latest Jest version. However, @>=27.2.5
addendum is recommended just to be on the safe side in a common scenario, when a package-lock.json
generated by an official React Native project template limits Jest version to a very old 26.x
, maybe due to some optimization mechanism.
Generally we recommend not to stay on outdated Jest versions for too long, e.g. jest@27.2.5
will be the minimal version supported by Detox 20.
2. Set up Test-code Scaffolds
Run the automated init script:
detox init -r jest
Note: errors occurring in the process may appear in red.
If things go well, the following will be created:
- An
e2e/
folder in your project root - An
e2e/config.json
file; example - An
e2e/environment.js
file; example - An
e2e/firstTest.e2e.js
file with content similar to this.
3. Fix / Verify
Even if detox init
passes well, and everything is green, we still recommend going over the checklist below. You can also use our example project, demo-react-native-jest
, as a reference in case of ambiguities.
.detoxrc.json
Property | Value | Description |
---|---|---|
testRunner | "jest" | Required. Should be "jest" for the proper detox test CLI functioning. |
runnerConfig | (optional path to Jest config file) | Optional. This field tells detox test CLI where to look for Jest’s config file. If omitted, the default value is e2e/config.json . |
skipLegacyWorkersInjection | false or true | Optional. This field tells detox test to stop appending --maxWorkers 1 argument to jest ... command by default. Since detox@18.19.0 , the control over maxWorkers count has been transfered to Jest config files, and that allows you to set any other value as a default maxWorkers count. |
A typical Detox configuration in .detoxrc.json
file looks like:
{
"testRunner": "jest",
"runnerConfig": "e2e/config.json",
"skipLegacyWorkersInjection": true,
"devices": {
"simulator": {
"type": "ios.simulator",
"device": {
"type": "iPhone 12 Pro Max"
}
}
},
"apps": {
"ios.release": {
"type": "ios.app",
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/example.app",
"build": "<...xcodebuild command...>",
}
},
"configurations": {
"ios.sim.release": {
"device": "simulator",
"app": "ios.release"
}
}
}
e2e/config.json
Property | Value | Description |
---|---|---|
maxWorkers | 1 | Recommended. When being used with skipLegacyWorkersInjection: true in Detox config, it prevents overallocation of mobile devices in the light of Jest’s default logic (= cpusCount — 1 ), when you do not pass any specific worker count. To override it, use CLI arguments, or see Jest documentation if you plan to change the default value in the config. |
testEnvironment | "./environment" | Required. Needed for the proper functioning of Jest and Detox. See Jest documentation for more details. |
testRunner | "jest-circus/runner" | Required. Needed for the proper functioning of Jest and Detox. See Jest documentation for more details. |
testTimeout | 120000 | Required. Overrides the default timeout (5 seconds), which is usually too short to complete a single end-to-end test. |
reporters | ["detox/runners/jest/streamlineReporter"] | Recommended. Sets up our streamline replacement for Jest’s default reporter, which removes Jest’s default buffering of console.log() output. That is helpful for end-to-end tests since log messages appear on the screen without any artificial delays. For more context, read Detox 12.7.0 migration guide. |
verbose | true | Conditional. Must be true if above you have replaced Jest’s default reporter with Detox’s streamlineReporter . Optional otherwise. |
A typical jest-circus
configuration in e2e/config.json
file would look like:
{
"testRunner": "jest-circus/runner",
"testEnvironment": "./environment",
"testTimeout": 120000,
"reporters": ["detox/runners/jest/streamlineReporter"],
"verbose": true
}
e2e/environment.js
If you are not familiar with Environment concept in Jest, you could check their documentation.
For Detox, having a CustomDetoxEnvironment
class derived from NodeEnvironment
enables implementing cross-cutting concerns such as taking screenshots the exact moment a test function (it/test) or a hook (e.g., beforeEach) fails, skip adding tests if they have :ios:
or :android:
within their title, starting device log recordings before test starts and so on.
API of CustomDetoxEnvironment
is not entirely public in a sense that there’s no guide on how to write custom DetoxCircusListeners
and override initDetox()
and cleanupDetox()
protected methods, since this is not likely to be needed for typical projects, but this is under consideration if there appears specific demand. You may want to check out this simple example of overriding initDetox()
, or some alternative approaches to overriding initDetox()
.
const {
DetoxCircusEnvironment,
SpecReporter,
WorkerAssignReporter,
} = require('detox/runners/jest-circus');
class CustomDetoxEnvironment extends DetoxCircusEnvironment {
constructor(config, context) {
super(config, context);
// Can be safely removed, if you are content with the default value (=300000ms)
this.initTimeout = 300000;
// This takes care of generating status logs on a per-spec basis. By default, Jest only reports at file-level.
// This is strictly optional.
this.registerListeners({
SpecReporter,
WorkerAssignReporter,
});
}
}
module.exports = CustomDetoxEnvironment;
Notes:
- The custom
SpecReporter
is recommended to be registered as a listener. It takes care of logging on a per-spec basis (i.e. whenit('...')
functions start and end) — which Jest does not do by default. - The custom
WorkerAssignReporter
prints for every next test suite which device is assigned to its execution.
This is how a typical Jest log output looks when SpecReporter
and WorkerAssignReporter
are enabled in streamline-reporter
is set up in config.json
and
SpecReporter
added in e2e/environment.js
:
Writing Tests
There are some things you should notice:
- Don’t worry about mocks being used, Detox works on the compiled version of your app.
- Detox exposes its primitives (
expect
,device
, ...) globally, it will override Jest’s globalexpect
object.
Parallel Test Execution
Through Detox' CLI, Jest can be started with multiple workers that run tests simultaneously, e.g.:
detox test --configuration <yourConfigurationName> --workers 2
In this mode, Jest effectively assigns one worker per each test file.
Per-spec logging offered by the SpecReporter
mentioned earlier, does not necessarily make sense, as the workers' outputs get mixed up.
By default, we disable SpecReporter
in a multi-workers environment.
If you wish to force-enable it nonetheless, the --jest-report-specs
CLI option can be used with detox test
, e.g.:
detox test --configuration <yourConfigurationName> --workers 2 --jest-report-specs
How to Run Unit and E2E Tests in the Same Project
- Create different Jest configs for unit and E2E tests, e.g. in
e2e/config.json
(for Detox) andjest.config.js
(for unit tests). For example, in Jest’s E2E config you can settestRegex
to look for\.e2e.js$
regexp, and this way avoid accidental triggering of unit tests with.test.js
extension. - To run your E2E tests, use
detox test
command (ornpx detox test
, if you haven’t installeddetox-cli
).