Setting up Detox on an Expo-managed React Native project

Rosen Toshev
3 min readMay 31, 2021

Setup Expo and Jest

Open your terminal. Install the expo command-line interface with

npm install -g expo-cli

Initialize an Expo project with the init command. And access the folder in your terminal. Install the dependencies and Pods.

expo init -- template blank detox-test-expo
cd detox-test-expo
expo install

Install the Expo-specific package for Jest.

npm install --save-dev jest-expo

End-to-end tests do not require mock results.

Make sure that the following is added to the package.json file.

In the scripts object, add the "test": "jest". After devDependencies, add

"jest": {  "preset": "jest-expo"},

Install the react-native-testing library and react-test-renderer as devDependencies.

npm install --save-dev react-native-testing-library
npm install --save-dev react-test-renderer

Setup Detox

Install the Detox command-line interface

brew tap wix/brew
brew install --HEAD applesimutils
npm install -g detox-cli

Now install detox-expo-helpers and expo-detox-hook as the last devDependencies needed to get our Expo-managed workflow to execute the detox-test command.

npm install --save-dev detox

Initialize Detox, with Jest as a test runner

detox init -r jest

Making Your First Test

Now we are ready to VS Code and edit the test files. In order to quickly open your project in VS Code from the root directory of your project, type code . in your terminal. You should see a folder called bin and a folder called e2e. First, download the Expo IPA from the Expo Tools page. Then unzip the file in the bin folder and change the name of the unzipped folder to Exponent.app.

bin and e2e folders in an Expo project

Then still in VS Code, open the firstTest.e2e.jsin the e2efolder. Change the await device.reloadReactNative() to await reloadApp() coming from the detox-expo-helpers package that we installed earlier.

const { reloadApp } = require('detox-expo-helpers');describe('Example', () => {beforeEach(async () => {   await reloadApp();});

Then following the sample with detox tests package.json from Expo, we need to set up Expo in our root project’s package.json. Add the following after jest.

"detox": {"test-runner": "jest","configurations": {"ios.sim": {"binaryPath": "bin/Exponent.app","type": "ios.simulator","name": "iPhone 11"  } }},

Now go to App.js in the root project and add two Text elements with theiraccessibilityLabelproperties set to “Text”.

import React, { Component } from 'react';
import { View, Text } from 'react-native';
export default class App extends Component {render() { return ( <View>
<Text accessibilityLabel="Text">
Text 1 </Text> <Text accessibilityLabel="Text"> Text 2 </Text> </View> ); }}

Go back to the firstTest.e2e.js file in the e2e folder. We are ready to write our first test. There are three parts to form a detox test: queries, actions, and expectations. The expectation that we use is .toBeVisible(). The .toBeVisible action tests if at least 75% of an element is visible on the screen. Detox requires the tests to be asynchronous. Put the await in the most outward section of the expression. In our test we are selecting the two elements we added to the App.js by their accessibilityLabels.

test('2 text nodes', async() => {
await expect(element(by.label("Text")).atIndex(0).toBeVisible();
await expect(element(by.label("Text")).atIndex(1).toBeVisible();
});

Your tests should look like this:

Completed firstTest.e2e.js file of your first Detox test.

Now we are ready to execute the tests. Run the expo server and select the ios simulator.

expo start
i

Open another tab on your terminal with CMND + T, and then run detox test. Detox should be opening the app as though a user is using your simulator. Our tests should pass now. You can take a congratulatory sip of your favorite beverage.

References

--

--