Your info daily

Detox and Appium: an automated interface test in React Native



Unfamiliar mobile environment


I, probably, like you, came to React Native as a developer of JavaScript rather than as a developer of native mobile applications. Absolutely new world with its own nuances and tricks.

One of the most important topics to learn will be testing. When everything is more or less clear with unit tests, what to do with interface tests and end-to-end tests? iOS. Android On the market a mixture of different types of devices.

Despite the fact that the technology itself is relatively new, it is still a mobile environment and you have to borrow and learn a lot from the native side.

I will briefly review two frameworks that you should pay attention to make your life as a developer easier.

Appium


Using behind the scenes Selenium WebDriver, Appium is a powerful framework with a huge community of native mobile application developers. Released before React.js, this is a leader and there is no equal to it.

Getting started with Appium is pretty easy. With the help of npm we install the “appium” and “appium-doctor” packages, we can globally, we can as part of the project. The “appium-doctor” team will tell us what else needs to be installed and configured before starting work, and, if possible, will help to correct the shortcomings. When everything is solved, the packages are installed and the Jest configuration is in place, we can run the Appium server and tests.

I will not go into the details of the settings, but this is how the simple test with the configuration looks like (comments are added):

/*  selenium webdriver  node */ import wd from 'wd' /* 60  ,    ,   */ jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000 /*   Appium.    ,  localhost */ const URL = 'localhost' const PORT = 4723 /*   webdriver */ const driver = wd.promiseChainRemote(URL, PORT) /*  . *    Appium, *   ,   . */ const capabilities = { platformName: 'iOS', //  Android platformVersion: '12.1', //   deviceName: 'iPhone 8', //  “Android Emulator”     automationName: 'XCUITest', //   (UIAutomator2  Android) app: '/path/to/.app' //   .app ( Android  .apk) } beforeAll(async () => { try { //  ,    await driver.init(capabilities) //   await driver.sleep(4000) //  ,       ,   ! } catch(err) { console.log(err) //  ,   ,    } }) afterAll(async () => { try { await driver.quit() //   } catch(err) { console.error(err) } }); /* Jest,   ,   Appium! *     ,    * 'topLabel'  'subLabel'  *       Appium */ describe("Home Screen landing", () => { test("render search screen", async () => { let topLabel = await driver.elementById('topLabel') let subLabel = await driver.elementById('subLabel') expect(await topLabel.text()).toBe("OK") expect(await subLabel.text()).toBe(" ") }) }) 

The test itself is the last few lines that check if the text “OK” and “main screen” are on the screen. As you can see, the test is nothing special, the same Jest. The documentation on the Appium site describes all the features of the framework, including also JavaScript examples.

Dislike only the await driver.sleep(4000) string. Unfortunately, tests have no idea what is happening in the application. The so-called “black box” or Blackbox. Imagine if you were writing code on Node, and before an http request, you would set a timer instead of using promise or callback. Here it is, the fragility of UI tests.

In this simple test, we wait 4 seconds to launch the application. With time and with an increase in the number of tests, we will set timers more often - http requests, animation, React Native itself - the bridge between native code and JavaScript only complicates the situation.

"Black box", we have an application build without access to internal structures.


What do you like about Appium?


What does not like in Appium



Note three tabs: Appium server logs, metro bundler package and the test itself.


Detox


Wix's Detox works similarly to Appium. The main difference is testing on the gray box strategy. One of the tasks of the Detox developers was to solve the problems with fragility - the task in the application will not be started until the previous one is over and the application is not free. This became possible thanks to another framework created under the name EarlGrey.

Just as with Appium, we set the settings.

 /*     package.json,   */ const detox = require("detox"); const config = require("./package.json").detox; /*  Jest */ const adapter = require("detox/runners/jest/adapter"); /* , *   Jest */ jest.setTimeout(120000); jasmine.getEnv().addReporter(adapter); beforeAll(async () => { /*   */ await detox.init(config); }); /* beforeEach  afterEach   Detox, *   Jest *    */ beforeEach(async function() { await adapter.beforeEach(); }); afterAll(async () => { await adapter.afterAll(); await detox.cleanup(); }); 

And setting in package.json:

 "detox": { "configurations": { "ios.detox": { //   iOS (  detox test -c ios.detox) "binaryPath": "path/to/.app", "build": "xcodebuild -workspace ios/app.xcworkspace -scheme scheme -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", //  workspace  project.      debug  production (release). "type": "ios.simulator", "name": "iPhone 8" //   }, "android.detox": { //   Android (  detox test -c android.detox) "binaryPath": "path/to/.apk", "build": "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..", //      debug  production (release). "type": "android.emulator", "name": "Pixel_2_API_28" //  . “adb devices”     Android } }, "test-runner": "jest", "runner-config": { "setupTestFrameworkScriptFile" : "./detox.init.js", //   "testEnvironment": "node", "testRegex": "(.*|\\.(ui))\\.(ts|tsx)$" //  ,     } "specs": "./__tests__/" //    } 

Tests are as easy to write as for Appium, but using the capabilities and limitations of Detox.

"Gray box", we have the assembly of the application and access to internal structures.


What I like about Detox


What I don't like about Detox


Fragility


Despite the fact that Detox uses the gray box principle, fragility is still present. The test with text input and svaypom did not work as it should in 1 case out of 10. You can not be 100% sure in the interface tests.

Speed


Appium “slows down” the “.sleep” timers set to manual, Detox in this case wins, because everything is synchronous. In general, I would not draw any conclusions from my side, since I did not write a large number of identical tests on both platforms. In 30-second tests and a simple test created for this article, Detox did a second faster. If you look at two different platforms, iOS and Android, the tests took + - the same time. The main thing to keep in mind is that interface tests take significantly longer unit tests.

What to choose


I still study both frameworks and it will take some time to understand all their advantages, but at the moment, as a JavaScript developer, I choose Detox.

Try both, fortunately, there are only two. It all depends on the application you are working on and the team.

Interface tests in the development team - for developers, try Detox. More sophisticated end-to-end tests - it may be better to take a closer look at Appium with its rich API capabilities and support on the BrowserStack, MS AppCenter and AWS DeviceFarm platforms.

Links


There are many useful resources and articles, but unfortunately, in English. The first thing I recommend of. sites.

Appium

Detox

More posts:


All Posts