Riding React Native and watching Appium (Part 1 – Let’s see how Appium works)

Tram Ho

1. Introduction

Due to the push and the customers with little money but like to inhale fragrant goods (all require 80 ~ 100 coverage -_-), I also went through react-native-testing-library for quite a while, and also played around. Detox , but no one satisfied me yet:

  • Testing-library: When testing e2e, you have to mock too much, it’s quite difficult to mock the component to behave like the real component. There are times when I just write to get% coverage but the fn of that test is mocked, so it doesn’t make much sense. The UI components are all mocked, so testing the pass and still dying is as normal as weighing the milk carton.
  • Detox: playing with each simulator, the device is not clear until now it has been electronically typed.

And recently, I reread the React Native docs and recommend one more guy – Appium. Appium uses drivers like XCUITest, UIAutomator, Espresso, … Native teito (big hands: v) at the company told the drivers all over the native side to run the test, so try to play around. After a period of tinkering, it is quite satisfied.

Why use Appium and not run healthy?

Saying that, in fact, running rice is not healthy at all.

When we develop a new feature for an app, we have to test for existing features, affecting them is inevitable.

Normally, we will think as “There is a tester, then what” is it right? However, the only developer must still check through the basic cases, (test more weird cases as possible) before moving on to the tester. But maybe just writing a feature is to turn on the app to press each button, not to mention a new bike (I have a very mistaken friend for newbie and newbike =))) newbie does not know the system, lack case is of course Moreover, we humans are not good at repetitive tasks like test apps, so even if we are a senior, there will be times of confusion.

Also, in the book “The Effective Engineer” by Edmond Lau (if nothing goes wrong, it’s page 159) it says:

If you have to do something manually more than twice, then write a tool for the third time

So why don’t we let the machine do boring jobs like testing, and focus on the things that make us more interested. Let’s learn how to write automated tests for our React Native app!

Some knowledge is required

  • React Native, Babel (no need to be too cool)
  • Get the basics of unit test writing (with jest, or something similar)
  • Typescript (optional): because in the article we will use Typescript

Hardware

  • Mac / Hackintosh to build iOS or Win (Android only)
  • An iOS or Android phone – say no to the integration test on the simulator: v

2. Run a small example

Suddenly stuffing up a bunch of theories while not knowing what I’m going to do, is it really boring? So let’s run a small example first: Register account

The following example uses Typescript + WebdriverIO, and has the same structure as the example on the home page of the Appium link (You can also go to the above link by visiting the Appium homepage and then clicking the Examples button), of course to go pro. then we will not code like that, I will perform refactor and convert the test environment in the following articles (if any =))).

After setting up Babel with Jest (since Jest always comes with React Native, I always use it for friendly demo), let’s write a simple test for our sign up process. Currently I only fill the text input fields, because the field select, the date picker is written quite long, so I will talk about it later.

Talking too much, where’s the code?

Yes, the code here (below has an explanation of the code)

Details of the source code can be found here

The source code of the screens can be found here:

  • Login screen link
  • Registration screen link

And here is the finished product:

iOSAndroid

What does the above example do?

  1. From the Login screen, click on the button ‘Create an account’ login/toRegistrationScreenButton to enter the Registration screen
  2. At the Registration screen

    1.1.Click the button “Register” registration/registerButton , because my Android device screen is a bit short, so before you right click, scroll to that element first.

    1.2. Do not fill anything, the expect error message displays accordingly

    1.3. Fill 「user..01」 in the input username, because this field only accepts alphabet and number, so that value is not valid, expect will display error message

    1.4. Fill username with a valid value 「user」

    1.5. Fill password 「password」

    1.6. Fill password confirmation 「password123」, because you don’t match the entered password, an error will be displayed

    1.7. Fill in valid password confirmation ‘password’

    1.8. Fill full name

    1.9. Click on the button 「Register」

  3. The user has been passed through the RegistrationCompleted screen, so we expect the button on this screen to be displayed.

Analyze a few notes about the syntax

The syntax of WebdriverIO looks quite clear and easy to understand, so I will not explain much, but there are a few notes below for you.

  • When searching for the element, I used ~ , this is the shorthand to find the element by the accessibility id of WebdriverIO, depending on the OS, we will have to assign a different prop to use the search strategy by accessibility id this link , just because of this. It took me a few hours, I don’t understand why I couldn’t find element =))
    • On iOS, we must use testID , and avoid assigning accessibilityLabel and accessibilityHint to components.
    • On the Android side, use accessibilityLabel
    • You can refer to other strategies in the docs of the webdriverio link
  • Why is accessibility id without using its content?
    • It is true that when pressing buttons or manipulating the screen, we should use its text, so that when the text (requirement) changes, the test will be the same. But basically because it’s a bit too lazy =)) and accessibility id is correct but the text is wrong, it must be accepted =))
  • Since WebdriverIO API returns Promise, almost every command needs to use async/await , you can use package @wdio/sync to make WebdriverIO API become synchronous.
  • Have you noticed the code in the beforeEach and afterEach ? For each test, we are creating a new session, and clearing that session after each test. It is more convenient to use the CLI of wdio.
  • The xcodeOrgId and xcodeSigningId within the capabilities of RemoteOptions iOS
    • To run the test on an iOS device, Appium will install a software called WebDriverAgent on the device, and to install it, we need to provide the developer team and signing certificate.

      You can see more here link

  • For real devices, we need to add UUID, you can see how to find UUID here
  • capabilities of Android
    • To get deviceName , run adb devices
    • com.learnrne2etest and .MainActivity can be obtained from android/app/src/main/AndroidManifest.xml

      Or refer to the following post link

It’s enough when riding a horse to see flowers, let’s learn more about how Appium works

3. Architecture, flow of Appium

Appium is based on client-server architecture, Appium itself is a server, you can easily see this in config.

3.1. Test library + WebDriver client

When writing tests, we spend most of our time working with them, as in the example in part 2, we used Jest (with the it , describe , afterEach , afterAll ) as the tools to run the test, and WebdriverIO (with $ , click() , setValue(value) ) to communicate with Appium server.

In addition to this duo, we can use any language we like (as long as Appium it supports: v), from Ruby, Python to PHP, C #, the list can be found here.

But I recommend the following combo:

  • Language: JS / TS is React Native dev friendly
  • WebDriver client: WebdriverIO because among clients, this guy has the most stars on github =))
  • Test library: jasmine
    • Because it has the same syntax as Jest, but the React Native code siblings are too familiar with Jest
    • It is one of the 3 test frameworks that are supported by WebdriverIO to go pro =)) (in addition, there are mocha and cucumber), if you use Jest, if you have an error, you have to figure it out:

As mentioned above, Appium adopts a client-server architecture. When we write the following statements

If you pay attention to the log, you can see the following log lines, webdriverio simply sends an HTTP request to the server, what does the server do, we will learn the following: v

  • iOS

  • Android

3.2. Appium server, Automation tool, Devices

This is the backbone of Appium’s architecture, it takes care of handling requests from clients, communicating with the native automation tool to execute the commands we need.

Appium server expose API to JSON Wire Protocol (WebDriver Protocol). Depending on whether the target is iOS or Android, it will have its own way of acting to suit that platform.

3.2.1. Appium meets iOS

Going back to the log in Section 3.1, it has more or less hinted at how Appium works

It can be seen that the Appium server simply proxies our request to another server running at port 8100 http://127.0.0.1:8100 .

Blessed are you? Who is running at port 8100?

It is WebDriverAgent server , originally developed by the big Facebook , the appium has forked to add something salt to it.

WDA helps communicate with XCUITest so you can control your iOS device / simulator remotely. It has already supported Webdriver Protocol, so surely Appium developer thought the following

What is the crime of having to re-code, have delicious products available, then use only =))

What WDA to do with the device, I would like to skip, because I don’t know =)) You can dig deeper by yourself if you are interested in it.

3.2.2. Appium meets Android

With Android, we have fewer suggestions

Can’t see some proxy, right? That’s right, because it doesn’t have a proxy: v

In the latest version, Appium uses appium-android-driver to communicate with UIAutomator2. So how to communicate?

Every time the test starts, Appium will install Appium Settings app on our device, this guy will open port 4724 on our device and expose some system APIs. Appium abc with app server installed on (over HTTP), and it will xyz with UIAutomator2 to perform the command.

4. Conclusion

As a dev, we are not subjective, depending on the tester, but let’s test it ourselves before passing it on to them. Rice testing is a boring job, so why don’t we make it more interesting by automating it. Although there will be some tricks, or to use many rather messy commands (such as the datepicker =))), but once it is run, it will give you a feeling of being like you. pangolin =))

The e2e code of the article is just temporary code, if you want to go pro you can refer to the webdriverio ‘s appium -boilerplate on how to split the module, as well as the setup project. If I have time I will write more about refactor the temporary pile of code above to go pro =)) Now, goodbye.

Share the news now

Source : Viblo