Key Benefits of Detox Automation for Testers
Testing plays a crucial role in software development, especially when it comes to mobile apps. End-to-end testing ensures that the app behaves as expected from the user's perspective. One of the most widely used tools for this in React Native is Detox, a gray-box testing tool that automates interactions with the app.
In this blog, we'll dive deep into Detox automation for mobile testing, starting with basics and moving to advanced concepts. By the end of this guide, you'll have a clear understanding of how to set up Detox and use it effectively in your projects.
What is detox and why?
Detox is a JavaScript-based mobile testing automation framework that can be used to test apps on iOS and Android devices. It's a popular choice because it's fast, flexible, and can help reduce testing time. Here are some reasons why you might want to use Detox:
Fast and reliable: Detox's integration with the app allows tests to run directly from the app's launch, eliminating the need for external tools. It also uses a gray-box testing approach, which means it has some knowledge of the app's internal workings, making it more stable and faster than black-box testing.
End-to-end testing: Detox simulates real user interactions by running the app on a real device, emulator, or simulators and interacting with it directly.
Flexible: Detox is flexible and can be used to automate a manual QA process.
Rich API: Detox has a rich API that supports React Native.
Understanding Detox’s Mobile Testing Framework
Mobile end-to-end testing can be tricky and often comes with challenges that make it harder for developers to get good results. Detox changes the way mobile testing is approached to tackle these problems at their core.
Detox does not rely on WebDriver. Detox is built from the ground up to integrate with native layers of your mobile app directly. We try to avoid generic cross-platform interfaces that are often the lowest common denominator. We want to optimize per platform.
Detox does gray box, not black box. Theoretically, it sounds better to test exactly what you ship as a black box. In practice, switching to a gray box allows the test framework to monitor the app from the inside and delivers critical wins like fighting flakiness at the core.
Detox synchronizes with your app’s activity. By being aware of what your app is doing and synchronizing with it, Detox times its actions, by default, to run only when your app is idle, meaning it has determined that your app has finished its work, such as animations, network requests, React Native load, etc. You can further read this here.
Built from the ground up for mobile apps, has first-class React Native support - Detox is built from the ground up for native mobile and has first-class support for React Native apps.
Expectations run on the app, not the tester process. Traditionally, test frameworks evaluate expectations in the test script, running on Node.js. Detox evaluates expectations directly in the tested app, running on the device; this enables operations that were impossible before due to performance reasons.
Detox and Appium: Comparative Overview
Appium is an open-source tool widely used for mobile app quality control. When choosing a framework for running end-to-end tests, Appium is often the first to come to mind. This is because the tool has been on the market for a long time, has a large community, and provides QA teams with a wide range of capabilities.
However, many testers who have become familiar with Detox still prefer this tool for mobile testing. We have compiled a comparative table of these platforms to demonstrate the advantages of Detox for end-to-end testing of mobile React Native apps.
Functions | Detox | appium |
Testing method | Grey box testing | Black box testing |
Supported programming languages | JavaScript-oriented | Java, Objective-C, JavaScript with Node.js, PHP, Python, Ruby, C#, Clojure, and Perl |
Synchronization with the application under test | Yes, the tool waits until the app enters standby mode before proceeding to the next testing stage. | No. This can cause unstable test results. |
Execution speed of tests | High | Lower than detox. This is due to the installation and launch of the Webdriver connection. |
Available devices for conducting tests | Real device, emulator, or simulator | Real device, emulator, or simulator |
User Support | A small, growing community | Large community, making it easy to find help and share knowledge |
Cross-platform | Yes | Yes |
Open Source | Yes | Yes |
Pros and Cons of Detox
Pros:
Specialized Testing for React Native: Detox is specifically designed to test React Native applications. It provides a focused and tailored approach to address the unique challenges of testing React Native apps effectively.
Fast and Reliable Test Execution: Detox starts test execution with the app launch, eliminating the need for additional tools and ensuring faster and more accurate test results.
Real Device and Emulator Support: Detox allows running end-to-end (E2E) tests on real devices, simulators, and Android emulators, enabling a thorough evaluation of the app’s behavior from a real user’s perspective.
Cross-Platform Testing: You can write and execute cross-platform tests on both iOS and Android, ensuring consistency across different environments.
Automatic Synchronization: Detox automatically detects asynchronous operations in the system and triggers a synchronization process, ensuring reliable and stable test execution.
Jest and Test Runner Integration: The tool integrates seamlessly with Jest and can be used with any test runner or even without one, providing flexibility in test management.
Async-Await API Support: Detox leverages the async-await API, ensuring that asynchronous operations are handled as expected during testing, improving test reliability.
Mono repo: Detox supports mono repo, enabling multiple projects or packages to share the same repository. This allows efficient testing across different modules while maintaining a unified codebase.
Cons:
Limited platform support: Detox primarily focuses on testing iOS and Android applications and may have limited support for other platforms or device types.
Initial cost: Setting up Detox can be time-consuming and require additional resources for configuration and maintenance.
React Native dependency: Detox may require additional configuration to test non-React Native apps.
JavaScript dependency: Detox relies heavily on JavaScript.
Limitation: Detox automation does not support testing on iOS real devices.
Here’s an overview of how Detox works:
1. App Launch & Test Initialization
Detox starts by launching your mobile app automatically, without requiring any manual setup or additional tools. This ensures that tests can start immediately and cleanly every time. Tests are written in JavaScript and executed via Node.js.
2. Automatic Synchronization
A unique aspect of Detox is its ability to detect and handle asynchronous operations automatically. For example, during UI interactions, the app might be waiting for network requests, animations, or timers to complete. Detox monitors these operations and synchronizes test execution accordingly, ensuring that the next test step doesn't proceed until the app is fully idle and ready. This eliminates the need for manual waits or sleep in the test scripts, making tests more stable.
3. Cross-Platform Execution (iOS and Android)
You can write tests in a cross-platform manner using JavaScript. The same test scripts can run on both iOS and Android environments. Detox works with iOS simulators, Android emulators, and real devices, making it versatile for testing across different platforms.
4. Test Execution
Detox interacts with the app through its JavaScript API. You write tests in JavaScript/TypeScript using the Detox API to simulate user actions (e.g., tapping buttons, entering text, scrolling) and then assert expected outcomes (e.g., verifying if a certain element is visible).
5. Integration with Test Runners (e.g., Jest)
Detox can be integrated with popular test runners like Jest or used standalone. This allows you to organize, manage, and run your test cases easily. Detox’s async-await nature ensures that tests are well-suited to handle JavaScript’s asynchronous behavior during E2E tests.
6. Running Tests on Continuous Integration (CI)
Detox can be easily integrated with CI platforms such as Travis CI, Jenkins, or CircleCI. This allows tests to be automatically run in headless mode on simulators or emulators during each code build, ensuring that regressions or bugs are caught early in the development pipeline.
7. Generating Reports and Logs
Detox provides detailed logs of test executions and errors. When a test fails, you get information about what went wrong and at which step, which helps in debugging and improving the reliability of tests. Detox also supports generating screenshots during test failures to capture the app's state for further inspection.
Step-by-Step Guide to Setting Up Detox
Before diving into actual test writing, we need to set up Detox. This section will guide you through installation and configuration for both iOS and Android platforms.
Prerequisites
Node.js: Ensure you have a recent version of Node.js installed on your development machine. You can download it here.
JavaScript Test Runner: Detox integrates seamlessly with various JavaScript test runners like Jest (recommended) or Mocha.
React Native: Detox is best suited for React Native apps, so having basic knowledge of React Native is beneficial.
Xcode (for iOS): Required for building iOS apps.
Android Studio (for Android): needed for setting up emulators and running tests on Android.
Project config: Install Detox, Jest Runner,
Build configuration (iOS and Android)
Installation Steps
- Install Detox CLI: First, open your terminal and install the Detox command-line interface (CLI) globally:
npm install -g detox-cli |
- Add Detox to Your React Native Project: Inside your React Native project directory, install Detox as a development dependency:
npm install detox --save-dev |
- Initialize Detox in Your Project: Run the following command to initialize Detox in your project. This will create a detox folder in your project with configuration files:
detox init -r jest |
Set Up Detox Configuration
Configuring Detox for Android and iOS is a critical step. Both platforms have slight differences in how they are set up, but overall, the process is straightforward.
4.1 Configuring Detox for Android
Setting up Detox for Android requires configuring several tools, including Android Studio, Android SDK, AVD (Android Virtual Device), and Gradle. Below are the detailed steps for each of these configurations:
1. Prerequisites
Before configuring Detox for Android, ensure the following tools are installed and correctly set up:
Node.js: Ensure you have Node.js installed, as Detox relies on it. You can verify this by running node -v and npm -v in your terminal.
Android Studio: Install Android Studio to manage the Android SDK, emulator (AVD), and Gradle configuration. Make sure to install the necessary SDK platforms and system images.
Java Development Kit (JDK): Ensure that the JDK is installed and properly set up. Detox requires the JDK to compile Android code.
Setting Up the Android SDK
Detox requires the Android SDK to build and run tests. Follow these steps to set up the SDK:
Open Android Studio, go to File > Project Structure > SDK Location and ensure the SDK path is set.
In the SDK Manager (found in Preferences > Appearance & Behavior > System Settings > Android SDK), install the following SDKs:
Android SDK Platform 30 (or the SDK version matching your project)
Android SDK Build-Tools 30.0.3 (or the required version)
Intel x86 Atom System Image for the API version you're testing against.
Set the ANDROID_HOME environment variable to point to your Android SDK path:
export ANDROID_HOME=~/Library/Android/sdk |
3. Setting Up an Android Virtual Device (AVD)
Detox requires an Android Virtual Device (AVD) to run tests. Follow these steps to set up a virtual device:
Open Android Studio, go to the AVD Manager (accessible via the Tools menu or search bar), and create a new virtual device. Choose a device that closely matches your testing requirements, such as Pixel 4 API 30.
Make sure to use a Google Play or Google APIs image for the API version you installed. Choose an image with x86 architecture for faster performance.
Once the device is created, you can launch the AVD using:
emulator -avd <device_name> |
Alternatively, you can run detox test directly, and Detox will handle launching the AVD if configured correctly in the detox.config.js file.
4. Configuring Gradle for Detox
Detox uses Gradle to build your Android app for testing. You'll need to configure your Gradle files to include the Detox dependencies:
- Open the android/build.gradle file and add the following:
buildscript { |
In the android/app/build.gradle file, ensure you have the following configuration:
android { |
This configuration ensures that your app is properly instrumented for testing with Detox.
5. Configuring the Detox Configuration for Android
In your detox.config.js file, you'll need to specify the Android configurations:
/ @type {Detox.DetoxConfig} / |
detox build --configuration android.debug |
If everything is set up correctly, Detox will compile the app, launch the emulator, and start executing the E2E tests. Modify the test command based on your requirements.
4.2 Configuring Detox for iOS
Setting up Detox for iOS involves configuring Xcode, CocoaPods, and the appropriate simulators. Here's a detailed guide for the iOS setup:
1. Prerequisites
Ensure the following are installed and configured:
Node.js: Detox relies on Node.js for automation. Verify it by running node -v.
Xcode: Download and install Xcode from the Mac App Store. You will need the latest version compatible with your macOS version.
CocoaPods: Detox requires CocoaPods for dependency management. If you don’t have it installed, install it via:
sudo gem install cocopods |
2. Setting Up Xcode and Simulators
- Open Xcode and install the required command-line tools:
xcode-select --install |
Ensure that the correct iOS SDK is installed by going to Preferences > Components in Xcode. Install the required simulators, such as iOS 14.5.
Verify that simulators are set up correctly:
xcrun simctl list |
3. Configuring CocoaPods
In the ios folder of your React Native project, run the following command to install the required pods:
cd ios |
This will install the necessary iOS dependencies, including those required for Detox.
4. Configuring Xcode for Detox
You’ll need to modify the ios/YourApp.xcodeproj project to include Detox configurations:
Open your project in Xcode and navigate to Build Settings.
Set the "Build Active Architecture Only" setting to Yes for the Debug configuration and No for the Release configuration.
5. Configuring the Detox Configuration for iOS
In your detox.config.js, configure the iOS environment:
/* @type {Detox.DetoxConfig} / |
This config defines the build command, binary path, and simulator settings for iOS testing.
Note: The flavors can be customized based on the user’s choice, such as release, staging, or prod.
6. Running detox Tests on iOS
- Build the app with:
detox build --configuration ios.sim.debug |
Run the tests with:
detox test --configuration ios.sim.debug |
Detox will launch the iOS simulator and start running your tests.
Writing Your First Detox Test
Now that you have detox set up, let's write your first E2E test. We will be using Jest as our test runner.
Example: Testing a Login Screen
- Create a test file. Inside the e2e folder generated during setup, create a test file named login.spec.js:
describe('Login Screen Tests', () => { |
- Understanding the Test
beforeAll: Launches the app before the tests start.
element(by.id()): Finds an element on the screen by its unique test ID.
typeText(): Simulates typing text into input fields.
tap(): Simulates a user tapping a button.
expect().toBeVisible(): Asserts that an element is visible on the screen.
- Run the test. To execute the test, run the following command:
detox test --configuration ios.sim.debug |
How Detox Automatically Synchronizes With Your App
Detox's key feature is its automatic synchronization, ensuring test actions are executed only when the app is stable, without pending asynchronous tasks. This eliminates the need for manual wait() or sleep() functions, making tests more reliable.
1. Tracking Asynchronous Operations
Mobile applications often perform many background or asynchronous tasks, such as:
Network requests (API calls, data fetching)
UI animations (transitions, element loading)
Timers (setTimeout, setInterval)
React Native bridges (for communication between the native code and JavaScript).
2. App Busy/Idle Detection in Detox:
Network Requests: Waits for API calls to finish.
UI Transitions/Animations: Pauses until transitions/animations complete.
React Native Bridge: Monitors for pending UI updates.
Timers: Waits for all JS timers (e.g.,
setTimeout
,setInterval
) to finish.
3. Automatic Synchronization Flow
Here’s a shortened version of Detox’s automatic synchronization flow:
Action Trigger: Test action (e.g., tap, type) is initiated.
Idle Check: Detox monitors the app for an idle state.
Wait for Completion: Detox waits for async tasks (e.g., network calls, animations) to finish.
Action Execution: Once idle, the action is performed.
Assertion: Detox verifies the expected result.
Repeat: The process repeats for each test step.
4. Avoiding Flaky Tests
Thanks to Detox’s automatic synchronization, you don’t need to manually add wait commands, reducing the risk of flaky tests due to app readiness.
5. Example of detox synchronization in action.
describe('Login Test', () => { |
This test case checks if a user can successfully log in to the app:
Launch the app: The app is started with the device. launchApp().
Enter username and password: Detox waits until the app is ready and automatically waits for an idle state.
Login Button: Tap the login button only when all asynchronous tasks are done.
Assert for validation.
Verify Navigation: The test verifies that after logging in, the user is taken to the home screen by checking if the home screen element is visible.
Best Practices for Writing Detox Tests
Here’s a short summary of the best practices for using Detox in E2E testing:
Avoid Flaky Tests: Use waitFor and expect to ensure elements are stable before interacting.
Keep Tests Isolated: Ensure tests are independent and reset shared data before the next test.
Use Unique Test IDs: Assign unique IDs to UI elements for reliable identification.
Test Small Units: Break tests into smaller, independent units for better reliability.
Use Detox Logging: Enable detailed logging to identify issues quickly.
Efficient Matchers: Use stable matchers like element IDs or static text; avoid dynamic selectors.
Test Key Flows: Focus on core functionalities, avoid unnecessary checks.
Organize Test Suites: Group related tests describe blocks for better structure and readability.
Continuous Integration (CI) with Detox Automation
Detox seamlessly integrates into CI pipelines, making it easier to run end-to-end (E2E) tests in a fully automated manner. Detox's ability to run tests on both emulators and real devices ensures that your apps are tested in environments similar to production. To implement Detox in your CI pipeline, you'll need to prepare your CI environment by configuring necessary dependencies such as Android SDK or Xcode for iOS. Additionally, it's important to allocate sufficient resources, especially for running multiple tests in parallel.
For a detailed guide on preparing Detox for CI, you can refer to the official documentation here.
How to Create an Emulator Using Command Line
Creating and managing Android emulators (called AVDs, or Android Virtual Devices) via the command line can streamline your testing process, especially when working with Detox for end-to-end testing. Here's how you can create, configure, and manage Android emulators using command-line tools.To create an Android emulator, you will use two command-line tools provided by the Android SDK:
avdmanager: Manages Android Virtual Devices (AVDs).
sdkmanager: Installs system images and SDK components.
emulator: Launches the Android emulator.
Step-by-Step Guide to Creating an Emulator
- Ensure SDK Tools are Installed First, make sure you have the necessary SDK tools installed. You can do this with sdkmanager:
sdkmanager "platform-tools" "emulator" "platforms; android-30" "system-images; android-30;google_apis;x86_64" |
This command installs:
platform-tools: Essential tools such as adb (Android Debug Bridge).
emulator: The tool to launch and manage emulators.
Platforms; android-30: Android 30 (Android 11) platform.
system-images;android-30;google_apis;x86_64: The system image for the Android 11 emulator, including Google APIs.
2. Create an Android Virtual Device (AVD)
Once you have the system image installed, you can create an emulator using the avdmanager command.
avdmanager create avd -n <name_of_avd> -k "system-images; android-30;google_apis;x86_64" --device "pixel" |
3. List Available System Images
If you're unsure which system images are available on your machine, use the following command to list them:
sdkmanager --list |
It will show you the available Android versions, platforms, and system images. You can then choose the system image for your AVD.
4. Verify the AVD Creation: After creating the AVD, verify that it exists by listing all available AVDs:
Avdmanager list avd |
This will display a list of emulators you've created, along with their details.
Launching an Emulator from the Command Line
Once you've created an AVD, you can launch it using the emulator command.
- Launch the emulator. Use the following command to launch your emulator:
Emulator -avd <name_of_avd> |
This will boot up the emulator. You can now run your Detox tests on this emulator once it is fully initialized.
2. Check Available Emulators
If you have multiple emulators and need to check which ones are available, you can list them with:
emulator -list-avds |
Integrating Emulator Creation with Detox
Once your emulator is created and launched, Detox will automatically detect it when running tests. However, for fully automated workflows, you can create a script that builds the app, starts the emulator, and runs the Detox tests in sequence.
For example, to automate testing with Detox on the new emulator:
detox build --configuration android.emu.debug |
For a detailed guide on creating an emulator using the command line, you can refer to the official documentation here.
Conclusion
Detox is a powerful and flexible framework for mobile app testing, especially if you're working with React Native. It’s fast, reliable, and provides automatic synchronization, making it an excellent choice for end-to-end testing. For fresh engineering graduates, Detox provides an accessible entry point into mobile automation testing.
By following this guide, you should be able to set up Detox in your project, write tests, and run them on multiple devices. With practice, you can leverage Detox's advanced features to automate complex workflows and ensure that your mobile apps work flawlessly across different platforms.