Setting up Gray-box E2E testing with React Native using Detox

5 min readSep 4, 2021

Detox is an end to end testing library for React Native app that enable to interact just like real user, and test based on what we write on the script. In short, automation testing.

In this post, I will cover all required setup from the scratch in a React Native project for Android.


I’ve assumed you already know React Native before, especially about environment and emulator setup. So, I will skip those steps.

In this demo, we will be using react-native cli. Run these commands to create and run a new React Native project.

$ npx react-native init demo-detox
$ cd wixDetox
$ react-native run-android

Now that our app is already prepared, let’s get started.


First, we need to install detox-cli (global)

$ yarn global add detox-cli / npm install -g detox-cli

Then, we also need to install detox package in our project (will using yarn from this point)

$ yarn add detox

Detox need to work with Test Runner. In this case, we will be using Jest (it’s a very popular platform for testing and also recommended by them). In their guide, it’s said that we need to install both jest and jest-circus (detail here).

$ yarn add jest jest-circus

After we finished Test Runner installation, we need to create the default config. We only need to run this command.

$ npx detox init -r jest

If it’s successful, these files will be added to our project:

  1. .detoxrc.js
  2. .detoxrc.json
  3. .detoxrc
  4. detox.config.js
  5. detox.config.json
  6. package.json ("detox" section)

Let’s move to the integration.


Now we need to setup the configuration on detoxrc.json

"configurations": {
"android.emu.debug": {
"binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk",
"build": "cd android ; ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug ; cd -",
"type": "android.emulator",
"device": {
"android.emu.release": {
"binaryPath": "android/app/build/outputs/apk/release/app-release.apk",
"build": "cd android ; ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release ; cd -",
"type": "android.emulator",
"device": {

To find out your device/emulator name, you can just simply run this command:

$ emulator -list-avds

In my case, the code looks like this:


Now we need to register both google() and detox package in android/build.gradle

allprojects {
repositories {
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
maven {
// Android JSC is installed from npm

maven {
// All of Detox' artifacts are provided via the npm module
url "$rootDir/../node_modules/detox/Detox-android"
} /* here */
google() /* and here */ jcenter()
maven { url '' }

We also need to update minSdkVersion to 21 and add Kotlin (should the latest version).

buildscript {
ext {
buildToolsVersion = "28.0.3"
ext.kotlinVersion = "1.3.70" /* should be the latest version */
minSdkVersion = 21 /* update minSdkVersion here */
compileSdkVersion = 28
targetSdkVersion = 28
repositories {

dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" /* kotlin dependency */
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

Then, we need to add another dependency. Open up android/app/build.gradle file and update the dependencies section like the code below:

dependencies {
if (enableHermes) {
def hermesPath = "../../node_modules/hermes-engine/android/";
debugImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
implementation jscFlavor
androidTestImplementation('com.wix:detox:+') /* here */

We also need add an additional config, at defaultConfig subsection in the same file

defaultConfig {
applicationId "com.demorntester"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
testBuildType System.getProperty('testBuildType', 'debug') /* here */
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' /* and here */

Then, we need to add the file android/app/src/androidTest/java/com/reactnativedetox/ with the like code below:

package com.reactnativedetox;import com.wix.detox.Detox;import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
public class DetoxTest {
// Replace 'MainActivity' with the value of android:name entry in
// <activity> in AndroidManifest.xml
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false);
public void runDetoxTests() {
Detox.DetoxIdlePolicyConfig idlePolicyConfig = new Detox.DetoxIdlePolicyConfig();
idlePolicyConfig.masterTimeoutSec = 60;
idlePolicyConfig.idleResourceTimeoutSec = 30;
Detox.runTests(mActivityRule, idlePolicyConfig);


Detox has already provide some default tests in the e2e/firstTest.spec.js file. But the tests will fail, since in React Native default app, it doesn't provide testID that written in firstTest.spec yet. So, we have to manually set it up ourselves in App.js. But don't worry, you can just copy the App.js file with the code below (or here in GitHub file).

import React, {useState} from 'react';
import {Text, View, TouchableOpacity, StyleSheet} from 'react-native';
const App = () => {
const [displayedText, setDisplayedText] = useState(undefined);
const OutputText = () => (
flex: 1,
paddingTop: 20,
justifyContent: 'center',
alignItems: 'center',
<Text style={{fontSize: 25}}>{displayedText}!!!</Text>
if (displayedText) {
return <OutputText />;
return (
<View testID="welcome" style={styles.root}>
onPress={() => setDisplayedText('Hello')}>
<Text style={styles.buttonText}>Tap to display Hello!</Text>
style={{...styles.button, backgroundColor: '#b71540'}}
onPress={() => setDisplayedText('World')}>
<Text style={styles.buttonText}>Tap to display World!</Text>
export default App;const styles = StyleSheet.create({
root: {
flex: 1,
paddingTop: 20,
justifyContent: 'center',
alignItems: 'center',
button: {
width: 350,
height: 80,
borderRadius: 12,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#006266',
marginBottom: 32,
buttonText: {
fontSize: 24,
color: 'white',
fontWeight: 'bold',
padding: 10,

One more, we need to add additional scripts in package.json file to run the detox tests.

Open package.json file and add the code below

"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint .",
"build:android-debug": "detox build --configuration android.emu.debug", /* this */
"test:android-debug": "detox test --configuration android.emu.debug", /* this */
"e2e:android-debug": "yarn build:android-debug && yarn test:android-debug" /* and this */

Then in terminal, run this command to start the tests

$ yarn e2e:android-debug


Done! Detox provides a lot more other functionality like typing in TextInput, screen navigation, etc. Explore more about Detox in their documentation here.




Software Engineer | Interests: self-growth, tech, health, and neuroscience