Test your React Native applications end-to-end with Detox

Developing a mobile application is no small feat. Most apps require some form of integration with multiple systems outside of their own environment. End-to-end testing offers a way to ensure these dependencies work accurately under production-like circumstances by simulating real user scenarios from start to finish.

For example, imagine a user inputs some text into a notes app and presses the save button. You can use end-to-end tests to ensure user experience is similar across multiple devices, and to verify the database and and backend layers work seamlessly when data is saved.

You can use the Detox library for React Native applications.

Detox is a tool created by Wix to allow cross-platform end-to-end testing in JavaScript. It aims to solve the main problems with end-to-end tests — slowness and flakiness.

Prior to Detox, tools like Appium, offered tests that were completely black-box, relying solely on the user’s perspective. In this scenario, the tester provides an input and observes the output generated at the end of the test, with no knowledge of the internal workings. Although not knowing the implementation details of a system might be beneficial, it does make it difficult to determine the root cause of failing tests.

On the other end of the spectrum is White Box testing, where the tester can inspect the inner workings of the system and easily uncover structural problems and hidden errors. Grey Box testing lies somewhere in the middle — a compromise that combines the benefit of both. It allows us to perform tests from the user’s perspective, whilst also leveraging the inside knowledge of the system and making it easier to identify weaknesses.

There are 2 main parts to running a detox test:

  • Running the mobile application
  • Running the test suite on Node outside of the application.

To run Detox, you require both node and the Detox Command Line Tools (detox-cli) on your machine. There are also a set of platform specific steps that need to be followed to run on both iOS and Android. These can be found here.

  • First install the detox npm package into your project by running the following command from your project root in the terminal:
npm install detox --save-dev
  • Set up a dedicated test runner with Jest.

Before you can run a test, Detox searches for a configuration file with any of the following formats: .detoxrc.js , .detoxrc.json , .detoxrc , detox.config.js , detox.config.json and a detox object in the package.json . This configuration file also holds all the configurations needed for the device.

Below is an example of configurations being added through the package.json

"detox": {
...
"configurations": {
"ios.sim.debug": {
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator /example.app",
"build": "xcodebuild -project ios/example.xcodeproj -scheme example -configuration Debug
-sdk iphonesimulator -derivedDataPath ios/build",
"type": "ios.simulator",
"name": "iPhone 7 Plus"
}
}
}

The binaryPath is the relative path of the application that you would like to test. The type specifies the device being tested. The options available include ios.simulator, ios.none, android.emulator, android.attached . The name is simply the device name, and the build allows you to specify an optional build command.

You can then specify configurations when running Detox via the terminal using --configuration and a path to the file. For example, detox build --configuration ./detoxrc.js refers to a detox config file in the root.

For a list of possible configurations click here.

  • Running this command builds your detox tests:
detox build --configuration <path to configuration file>
  • Running this command runs your detox tests:
detox test --configuration <path to configuration file>

Detox contains methods that allow you to define behaviour whilst your test runs. These include:

detox.init() — Allows you to set up detox. It reads its configuration and starts a server

detox.beforeEach() — Called at the start of every test

detox.afterEach() — Called at the end of every test

detox.cleanup() — Starts the clean up phase after the completion of each test. At this point, the detox server shuts down.

The Device object allows you to control the device on which your tests are run, and to mock the users experience. An example is the device.launchApp(). The launchApp() method takes a set parameters that allow for things like launching a new instance of the application, or launching with permissions.

await device.launchApp({ 
newInstance: true,
url: url,
languageAndLocale: {
language: locale, locale
},
permissions: {
calendar: 'Yes'
}
})

However, some methods are platform specific. For example, device.setBiometricEnrollment(bool) and device.matchFinger() for iOS and device.pressBack() and device.getUiDevice() for android.

Software Developer