Test Environment & Lifecycle
Understanding the execution lifecycle of React Native Harness is key to configuring complex test suites and ensuring test isolation.
Execution Lifecycle
When you run react-native-harness, the following process occurs for each test file:
- Node.js Setup: The CLI loads your configuration and prepares the Metro bundler.
- App Preparation: The target app is launched or brought to the foreground on the device.
- Harness Initialization: The native bridge is established.
setupFiles: Global setup files are evaluated in the app environment.- Test Collection: The test file is evaluated to build a structure of
describeanditblocks.setupFilesAfterEnv: These files are evaluated during this phase.
- Execution: Tests are run serially on the device.
- Teardown: Results are sent back to the CLI, and the environment is cleaned up.
Setup Files
Harness supports two types of setup files, configured in your jest.harness.config.mjs.
setupFiles
Executed before the testing environment is initialized.
- Context: Runs in the app's JavaScript environment, but before the Test Runner has initialized the test framework (Jest).
- Limitations:
describe,it,expect, andbeforeEachare not available. - Use Case: Polyfilling global APIs that the environment or third-party libraries expect to exist immediately upon import.
setupFilesAfterEnv
Executed after the testing environment is initialized, but before the test file itself.
- Context: Runs immediately before the test file is executed. The test framework is fully loaded.
- Capabilities: Full access to
describe,it,expect,beforeEach, and Harness APIs likemock,spyOn,clearAllMocks, etc. - Use Case: Configuring global mocks, custom matchers, or global setup/teardown hooks.
Isolation and Persistence
Environment Reset
By default, Harness ensures test isolation by resetting the environment between test files.
resetEnvironmentBetweenTestFiles: (Default:true) When enabled, the app is fully restarted between different test files. This prevents state leakage (like singleton native modules or global variables) from affecting subsequent tests.
Native Module Mocking
Mocks created via mock() are tied to the module cache. Use resetModules() in an afterEach hook to ensure mocks don't leak between individual tests within the same file.
Native Crash Detection
Testing native modules often involves calling code that might cause the host application to crash. Standard test runners often hang or report a generic "Device disconnected" error in these cases.
Harness includes a built-in Native Crash Monitor:
detectNativeCrashes: (Default:true) When enabled, Harness actively monitors the native process. If the app crashes, Harness catches the failure, reports aNativeCrashErrorfor the current test, and automatically restarts the app to continue with the remaining test files.crashDetectionInterval: (Default:500ms) How often the CLI polls the device to ensure the app is still alive.
Forwarding Client Logs
To aid in debugging, you can forward all console output from the device to your terminal.
When enabled, logs from the device appear in your terminal with indicators:
LOG-console.logWARN-console.warnERROR-console.error
