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.
So, how would you test this?
You can use the Detox library for React Native applications.
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.
So how does detox run?
There are 2 main parts to running a detox test:
- Running the mobile application
- Running the test suite on
Nodeoutside 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.
Adding detox to your project
- First install the
detoxnpm 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.
Adding your detox configurations
Before you can run a test, Detox searches for a configuration file with any of the following formats:
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
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator /example.app",
"build": "xcodebuild -project ios/example.xcodeproj -scheme example -configuration Debug
-sdk iphonesimulator -derivedDataPath ios/build",
"name": "iPhone 7 Plus"
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
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.
Building and running your detox tests:
- 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>
On writing detox tests:
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.
How to control your device during a test
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
launchApp() method takes a set parameters that allow for things like launching a new instance of the application, or launching with permissions.
language: locale, locale
However, some methods are platform specific. For example,
device.matchFinger() for iOS and
device.getUiDevice() for android.