Having the right test automation is the key for success of any Product. Testing your application from the perspective of an end user automatically, ensuring the quality of code , along with delivering it, on the right medium available.
There are various tools when it comes to web automation like Cypress, Webdriverio and many others. But when it comes to the mobile, automation is not that common. The reason for writing an article on mobile automation is to explain how to achieve and implement end to end testing of mobile using Detox and integration with CI/CD pipeline like Appcenter for distribution.
Detox an End to End testing library for applications which are developed using React Native and for pure native applications. It allows mobile tests to be performed by running a real device/simulator and showcasing the interaction like a real User. Less flaky Cross Platform, supports both android and ios Debuggable Made for CI
Note: Lets focus on iOS, otherwise the length of the article will become too long.
The following React Native versions have been tested: iOS Android <=0.62 <=0.56 - Full support
=0.57 <=0.62 - Visibility edge-case: see this RN issue*
$ npm install react-native -g
$ npx react-native init <project_Name>
$ react-native run-ios
$ brew tap wix/brew
$ brew install applesimutils
$ npm install -g detox-cli
$ yarn add detox -D
Lets add detox configuration in your project.Always try keeping the detox configuration seperate in your package.json file. I have added 2 configuration, one incase of debug mode to run it locally and one in release mode, while trying to integrate it with a CI/CD pipeline.
"detox": {
"configurations": {
"ios.sim.debug": {
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/DetoxTest.app",
"build": "xcodebuild -workspace ios/DetoxTest.xcworkspace -scheme Staging -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build",
"type": "ios.simulator",
"device": {
"type": "iPhone 11 Pro"
}
},
"ios.sim.release": {
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/DetoxTest.app",
"build": "export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -workspace ios/DetoxTest.xcworkspace -scheme Staging -configuration Release -sdk iphonesimulator -derivedDataPath ios/build -quiet",
"type": "ios.simulator",
"device": {
"type": "iPhone 11 Pro"
}
}
},
"test-runner": "jest",
"runner-config": "e2e/config.json"
}
}
Now, lets install a one of the framework either jest or mocha.
$ detox init -r jest
OR
$ detox init -r mocha
It will create a e2e folder in your project, with some basic test files which allows you to start writing your first script, init.js and some config files, wherein you can mention the type of reporting required.
There are various reporters available, but I tried using jest-stare as it gives reports in both html and json format.
$ npm i jest-stare
Now, change the config.json
file to use the reporter you just added. By defining the jest-stare reporter, e.g
"reporters": ["../node_modules/jest-stare"]
Its always important to maitain the folder structure, so that the effort is always streamlined, hence better to keep common things together. I have tried keeping the specs in one folder and user data in a seperate json file. Let’s do it!
e2e
├── specs
e2e
├── specs
└── user.json
{
"dev": {
"devLoginDetails": {
"username": "abc@gmail.com",
"password": "12345"
}
},
"stage": {
"stgLoginDetails": {
"username": "cdf@gmail.com",
"password": "98765"
}
}
}
testEnvConfig.js
wherein you will mention the environment specific data, like in our case we have users specific to environmentprocess.env.ENV_NAME = "dev"
testID={'basics'}
firstTest.e2e.js
to verify some elements from the react welcome pagedescribe("Verify the react welcome page elements", () => {
beforeEach(async () => {
await device.reloadReactNative()
})
it("should have welcome screen", async () => {
await expect(element(by.id("welcome"))).toBeVisible()
})
it("should be able to click on basics link", async () => {
await element(by.id("basics")).tap()
await expect(element(by.text("The Basics"))).tap()
})
})
$ detox:build
$ detox:test e2e/specs
Yes, as promised we will see the functional tests written in detox to be integrated with CI/CD tools like appcenter. Having a automation scripts is wonderful, but would it make sense if there are error in code and scripts fail. But your app getting delivering to various environment. The most important part of having automation scripts is to reduce manual effort and having automated deployment and failing the deployments incase of errors.
Every CI/CD has its own shell files. Incase of appcenter we do have mutliple files for executing functions before build (post build), after build (pre-build), Post-clone and various others. Lets focus on appcenter-pre-build.sh
file, wherein our app has started building, and then lets add our commands to execute E2E testing before building the app
echo "Building the project for Detox tests..."
npx detox build --configuration ios.sim.release
But is that enough?
We still havent stopped the distribution of the app when your tests fails. Here’s a solution provided by appcenter, wherein you can use appcenters openAPI to cancel the build, using the token
echo "Executing Detox tests..."
if npx detox test e2e/specs/firstspec.e2e.js --configuration ios.sim.release --cleanup; then
echo "All tests succeeded"
else
echo "Test failed"
echo "Cancelling app center build"
API_TOKEN="<UserToken>"
OWNER_NAME="<ownerName>"
APP_NAME="<appName>"
curl -iv "https://appcenter.ms/api/v0.1/apps/$OWNER_NAME/$APP_NAME/builds/$APPCENTER_BUILD_ID" \
-X PATCH \
-d "{\"status\":\"cancelling\"}" \
--header 'Content-Type: application/json' \
--header "X-API-Token: $API_TOKEN"
exit
fi
Wahoo!! We have successfully implemented our e2e with CI/CD..
There are various elements that helps you perform different operations and actions of the device, the list is available here. Also tools like Detox, helps increase the speed and can be easily integrated with react native apps. The community is growing faster. Have you used Detox for mobile app testing?
Happy using Detox!! 👻