Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobile application testing

34 views

Published on

Main idea of this talk is to show what technologies can be used for cross-platform mobile app development and how to deal with UI tests automation for them. I will outline set of challenges every tester and developer needs to conquer and give some tips how to solve them. During this talk I will present how to apply UI tests in React Native project using Detox framework.

Published in: Education
  • Be the first to comment

QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobile application testing

  1. 1. REACT Native is coming The story of hybrid mobile application testing
  2. 2. Agenda
  3. 3. Agenda 1. Introduction 2. Cross-platform frameworks for mobile development 3. UI testing approaches for hybrid apps 4. Detox guide for applying UI tests in React Native projects
  4. 4. Agenda 1. Introduction 2. Cross-platform frameworks for mobile development 3. UI testing approaches for hybrid apps 4. Detox guide for applying UI tests in React Native projects
  5. 5. Agenda 1. Introduction 2. Cross-platform frameworks for mobile development 3. UI testing approaches for hybrid apps 4. Detox guide for applying UI tests in React Native projects
  6. 6. Agenda 1. Introduction 2. Cross-platform frameworks for mobile development 3. UI testing approaches for hybrid apps 4. Detox guide for applying UI tests in React Native projects
  7. 7. Long Story Short
  8. 8. SOme Time Ago... Customers And Their money
  9. 9. meantime in Software Houses
  10. 10. But Now Customers And Their money
  11. 11. Oh no ! O Nie ! Para Pollo ! Zonk !
  12. 12. Meanwhile in Software Houses
  13. 13. Cross Platform frameworks
  14. 14. How to Automate this as before ???
  15. 15. The Native white Box Test
  16. 16. The Native white Box Test + Fast + Easy setup + Wide range of open source helpers + Compatible with Cloud Device Farms
  17. 17. The Native white Box Test + Fast + Easy setup + Wide range of open source helpers + Compatible with Cloud Device Farms − Different languages in project repository − Duplicated test code
  18. 18. The Cross Platform Black Box Test
  19. 19. The Cross Platform Black Box Test + Many supported languages + Wide community + Similar to Selenium + Single test code base + Compatible with Cloud Device Farms
  20. 20. The Cross Platform Black Box Test + Many supported languages + Wide community + Similar to Selenium + Single test code base + Compatible with Cloud Device Farms − Slow − Difficult debugging − Lack of stability
  21. 21. The Cross Platform Gray Box Test
  22. 22. The Cross Platform Gray Box Test + Fast + Easy setup + Single test code base + The same language as default project one + Close integration with source code + API designed for a specific platform
  23. 23. The Cross Platform Gray Box Test + Fast + Easy setup + Single test code base + The same language as default project one + Close integration with source code + API designed for a specific platform − No way / difficult to integrate with Cloud Device Farm − No outspread community − Often still not developed enough
  24. 24. Based on experience with React Native
  25. 25. Automation Guide with Detox - cross platform React Native Framework
  26. 26. How to add Detox to an existing project - Package.json file
  27. 27. How to add Detox to an existing project - Package.json file "detox": {
  28. 28. How to add Detox to an existing project - Package.json file "detox": { "test-runner": "mocha", "specs": "e2e", "configurations": {
  29. 29. How to add Detox to an existing project - Package.json file "detox": { "test-runner": "mocha", "specs": "e2e", "configurations": { "ios.sim.debug": { "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/PolideaSample.app", "build": "xcodebuild -project ios/PolideaSample.xcodeproj -scheme PolideaSample -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", "type": "ios.simulator", "name": "iPhone X" }, "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", "name": "Nexus_5X_API_24" } } } }
  30. 30. How to add Detox to an existing project - Package.json file "detox": { "test-runner": "mocha", "specs": "e2e", "configurations": { "ios.sim.debug": { "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/PolideaSample.app", "build": "xcodebuild -project ios/PolideaSample.xcodeproj -scheme PolideaSample -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", "type": "ios.simulator", "name": "iPhone X" }, "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", "name": "Nexus_5X_API_24" } } } }
  31. 31. How to add Detox to an existing project - Package.json file "detox": { "test-runner": "mocha", "specs": "e2e", "configurations": { "ios.sim.debug": { "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/PolideaSample.app", "build": "xcodebuild -project ios/PolideaSample.xcodeproj -scheme PolideaSample -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", "type": "ios.simulator", "name": "iPhone X" }, "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", "name": "Nexus_5X_API_24" } } } }
  32. 32. How to add Detox to an existing project - Package.json file "detox": { "test-runner": "mocha", "specs": "e2e", "configurations": { "ios.sim.debug": { "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/PolideaSample.app", "build": "xcodebuild -project ios/PolideaSample.xcodeproj -scheme PolideaSample -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", "type": "ios.simulator", "name": "iPhone X" }, "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", "name": "Nexus_5X_API_24" } } } }
  33. 33. How to add Detox to an existing project - Package.json file "detox": { "test-runner": "mocha", "specs": "e2e", "configurations": { "ios.sim.debug": { "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/PolideaSample.app", "build": "xcodebuild -project ios/PolideaSample.xcodeproj -scheme PolideaSample -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", "type": "ios.simulator", "name": "iPhone X" }, "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", "name": "Nexus_5X_API_24" } } } }
  34. 34. How to make apps testable? <Text style={styles.textStyle}> {!this.state.clicked? defaultButtonText: "Polidea"} </Text> <Text accessible= {true} testID= {"ButtonText"} accessibilityLabel= {"ButtonTextDesc"} style={styles.textStyle}> {!this.state.clicked? defaultButtonText: "Polidea"} </Text>
  35. 35. How to make apps testable? <Text accessible= {true} testID= {"ButtonText"} accessibilityLabel= {"ButtonTextDesc"} style={styles.textStyle}> {!this.state.clicked? defaultButtonText: "Polidea"} </Text>
  36. 36. How to write Test scripts - API Overview Detox Object Test plan configuration Device Object Key events, Gestures, Device settings Matchers, Actions, Expectations Finding Views, User’s actions, Validation API
  37. 37. How to write Test scripts - Init script by example require('babel-polyfill');
  38. 38. How to write Test scripts - Init script by example require('babel-polyfill'); const detox = require('detox'); const config = require('../package.json').detox;
  39. 39. How to write Test scripts - Init script by example require('babel-polyfill'); const detox = require('detox'); const config = require('../package.json').detox; beforeAll(async () => { await detox.init(config); });
  40. 40. How to write Test scripts - Init script by example require('babel-polyfill'); const detox = require('detox'); const config = require('../package.json').detox; beforeAll(async () => { await detox.init(config); }); beforeEach(async () => { await adapter.beforeEach(); });
  41. 41. How to write Test scripts - Init script by example require('babel-polyfill'); const detox = require('detox'); const config = require('../package.json').detox; beforeAll(async () => { await detox.init(config); }); beforeEach(async () => { await adapter.beforeEach(); }); afterAll(async () => { await adapter.afterAll(); await detox.cleanup(); });
  42. 42. How to write Test scripts - Test class by example
  43. 43. How to write Test scripts - Test class by example describe('Example', () => {
  44. 44. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => {
  45. 45. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await
  46. 46. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device
  47. 47. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative();
  48. 48. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); await waitFor
  49. 49. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); await waitFor(element
  50. 50. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); await waitFor(element(by.id('ButtonText')))
  51. 51. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); await waitFor(element(by.id('ButtonText'))).toBeVisible()
  52. 52. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); await waitFor(element(by.id('ButtonText'))).toBeVisible().withTimeout(10000); });
  53. 53. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); await waitFor(element(by.id('ButtonText'))).toBeVisible().withTimeout(10000); }); it
  54. 54. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); await waitFor(element(by.id('ButtonText'))).toBeVisible().withTimeout(10000); }); it ('should Press me text be morphed in Polidea title after click on button',async () =>{
  55. 55. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); await waitFor(element(by.id('ButtonText'))).toBeVisible().withTimeout(10000); }); it ('should Press me text be morphed in Polidea title after click on button',async () =>{ await element(by.id('ButtonText'))
  56. 56. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); await waitFor(element(by.id('ButtonText'))).toBeVisible().withTimeout(10000); }); it ('should Press me text be morphed in Polidea title after click on button',async () =>{ await element(by.id('ButtonText')).tap();
  57. 57. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); await waitFor(element(by.id('ButtonText'))).toBeVisible().withTimeout(10000); }); it ('should Press me text be morphed in Polidea title after click on button',async () =>{ await element(by.id('ButtonText')).tap(); await waitFor(element(by.text("Press Me")))
  58. 58. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); await waitFor(element(by.id('ButtonText'))).toBeVisible().withTimeout(10000); }); it ('should Press me text be morphed in Polidea title after click on button',async () =>{ await element(by.id('ButtonText')).tap(); await waitFor(element(by.text("Press Me"))).toNotExist()
  59. 59. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); await waitFor(element(by.id('ButtonText'))).toBeVisible().withTimeout(10000); }); it ('should Press me text be morphed in Polidea title after click on button',async () =>{ await element(by.id('ButtonText')).tap(); await waitFor(element(by.text("Press Me"))).toNotExist().withTimeout(2000);
  60. 60. How to write Test scripts - Test class by example describe('Example', () => { beforeEach(async () => { await device.reloadReactNative(); await waitFor(element(by.id('ButtonText'))).toBeVisible().withTimeout(10000); }); it ('should Press me text be morphed in Polidea title after click on button',async () =>{ await element(by.id('ButtonText')).tap(); await waitFor(element(by.text("Press Me"))).toNotExist().withTimeout(2000); await waitFor(element(by.text("Polidea"))).toBeVisible().withTimeout(100); }); })
  61. 61. How to integrate With CI - Gitlab CI
  62. 62. How to integrate With CI - Gitlab CI detox_test:iOS: detox_test:android:
  63. 63. How to integrate With CI - Gitlab CI detox_test:iOS: stage: test before_script: detox_test:android: stage: test before_script:
  64. 64. How to integrate With CI - Gitlab CI detox_test:iOS: stage: test before_script: detox_test:android: stage: test before_script: - adb connect pixel:5555; sh ./scripts/waitForDevice.sh pixel
  65. 65. How to integrate With CI - Gitlab CI detox_test:iOS: stage: test before_script: - brew tap wix/brew - brew install --HEAD applesimutils - npm install -g detox-cli - npm install -g react-native-cli - npm install detox_test:android: stage: test before_script: - adb connect pixel:5555; sh ./scripts/waitForDevice.sh pixel - mkdir -p ./detox_node/ - npm install --prefix ./detox_node/ -g detox-cli - npm install --prefix ./detox_node/ -g react-native-cli - npm install
  66. 66. How to integrate With CI - Gitlab CI detox_test:iOS: stage: test before_script: - brew tap wix/brew - brew install --HEAD applesimutils - npm install -g detox-cli - npm install -g react-native-cli - npm install script: detox_test:android: stage: test before_script: - adb connect pixel:5555; sh ./scripts/waitForDevice.sh pixel - mkdir -p ./detox_node/ - npm install --prefix ./detox_node/ -g detox-cli - npm install --prefix ./detox_node/ -g react-native-cli - npm install script:
  67. 67. How to integrate With CI - Gitlab CI detox_test:iOS: stage: test before_script: - brew tap wix/brew - brew install --HEAD applesimutils - npm install -g detox-cli - npm install -g react-native-cli - npm install script: - react-native start --port 2137 & detox_test:android: stage: test before_script: - adb connect pixel:5555; sh ./scripts/waitForDevice.sh pixel - mkdir -p ./detox_node/ - npm install --prefix ./detox_node/ -g detox-cli - npm install --prefix ./detox_node/ -g react-native-cli - npm install script: - ./detox_node/bin/react-native start --port 2137 &
  68. 68. How to integrate With CI - Gitlab CI detox_test:iOS: stage: test before_script: - brew tap wix/brew - brew install --HEAD applesimutils - npm install -g detox-cli - npm install -g react-native-cli - npm install script: - react-native start --port 2137 & - detox build -c ios.sim.debug detox_test:android: stage: test before_script: - adb connect pixel:5555; sh ./scripts/waitForDevice.sh pixel - mkdir -p ./detox_node/ - npm install --prefix ./detox_node/ -g detox-cli - npm install --prefix ./detox_node/ -g react-native-cli - npm install script: - ./detox_node/bin/react-native start --port 2137 & - ./detox_node/bin/detox build -c android.emu.debug
  69. 69. How to integrate With CI - Gitlab CI detox_test:iOS: stage: test before_script: - brew tap wix/brew - brew install --HEAD applesimutils - npm install -g detox-cli - npm install -g react-native-cli - npm install script: - react-native start --port 2137 & - detox build -c ios.sim.debug - detox test -c ios.sim.debug detox_test:android: stage: test before_script: - adb connect pixel:5555; sh ./scripts/waitForDevice.sh pixel - mkdir -p ./detox_node/ - npm install --prefix ./detox_node/ -g detox-cli - npm install --prefix ./detox_node/ -g react-native-cli - npm install script: - ./detox_node/bin/react-native start --port 2137 & - ./detox_node/bin/detox build -c android.emu.debug - ./detox_node/bin/detox test -c android.emu.debug
  70. 70. How to integrate With CI - Gitlab CI detox_test:iOS: stage: test before_script: - brew tap wix/brew - brew install --HEAD applesimutils - npm install -g detox-cli - npm install -g react-native-cli - npm install script: - react-native start --port 2137 & - detox build -c ios.sim.debug - detox test -c ios.sim.debug - kill -9 $(lsof -n -i4TCP:2137) detox_test:android: stage: test before_script: - adb connect pixel:5555; sh ./scripts/waitForDevice.sh pixel - mkdir -p ./detox_node/ - npm install --prefix ./detox_node/ -g detox-cli - npm install --prefix ./detox_node/ -g react-native-cli - npm install script: - ./detox_node/bin/react-native start --port 2137 & - ./detox_node/bin/detox build -c android.emu.debug - ./detox_node/bin/detox test -c android.emu.debug - kill -9 $(lsof -n -i4TCP:2137)
  71. 71. How to integrate With CI - Gitlab CI detox_test:iOS: stage: test before_script: - brew tap wix/brew - brew install --HEAD applesimutils - npm install -g detox-cli - npm install -g react-native-cli - npm install script: - react-native start --port 2137 & - detox build -c ios.sim.debug - detox test -c ios.sim.debug - kill -9 $(lsof -n -i4TCP:2137) tags: detox_test:android: stage: test before_script: - adb connect pixel:5555; sh ./scripts/waitForDevice.sh pixel - mkdir -p ./detox_node/ - npm install --prefix ./detox_node/ -g detox-cli - npm install --prefix ./detox_node/ -g react-native-cli - npm install script: - ./detox_node/bin/react-native start --port 2137 & - ./detox_node/bin/detox build -c android.emu.debug - ./detox_node/bin/detox test -c android.emu.debug - kill -9 $(lsof -n -i4TCP:2137) tags:
  72. 72. How to integrate With CI - Gitlab CI detox_test:iOS: stage: test before_script: - brew tap wix/brew - brew install --HEAD applesimutils - npm install -g detox-cli - npm install -g react-native-cli - npm install script: - react-native start --port 2137 & - detox build -c ios.sim.debug - detox test -c ios.sim.debug - kill -9 $(lsof -n -i4TCP:2137) tags: - xcode-9.2 detox_test:android: stage: test before_script: - adb connect pixel:5555; sh ./scripts/waitForDevice.sh pixel - mkdir -p ./detox_node/ - npm install --prefix ./detox_node/ -g detox-cli - npm install --prefix ./detox_node/ -g react-native-cli - npm install script: - ./detox_node/bin/react-native start --port 2137 & - ./detox_node/bin/detox build -c android.emu.debug - ./detox_node/bin/detox test -c android.emu.debug - kill -9 $(lsof -n -i4TCP:2137) tags: - android-emu
  73. 73. How to integrate With CI - Gitlab CI detox_test:iOS: stage: test before_script: - brew tap wix/brew - brew install --HEAD applesimutils - npm install -g detox-cli - npm install -g react-native-cli - npm install script: - react-native start --port 2137 & - detox build -c ios.sim.debug - detox test -c ios.sim.debug - kill -9 $(lsof -n -i4TCP:2137) tags: - xcode-9.2 detox_test:android: stage: test before_script: - adb connect pixel:5555; sh ./scripts/waitForDevice.sh pixel - mkdir -p ./detox_node/ - npm install --prefix ./detox_node/ -g detox-cli - npm install --prefix ./detox_node/ -g react-native-cli - npm install script: - ./detox_node/bin/react-native start --port 2137 & - ./detox_node/bin/detox build -c android.emu.debug - ./detox_node/bin/detox test -c android.emu.debug - kill -9 $(lsof -n -i4TCP:2137) tags: - android-emu services: - name: android-emulator:latest
  74. 74. How to integrate With CI - Gitlab CI detox_test:iOS: stage: test before_script: - brew tap wix/brew - brew install --HEAD applesimutils - npm install -g detox-cli - npm install -g react-native-cli - npm install script: - react-native start --port 2137 & - detox build -c ios.sim.debug - detox test -c ios.sim.debug - kill -9 $(lsof -n -i4TCP:2137) tags: - xcode-9.2 detox_test:android: stage: test before_script: - adb connect pixel:5555; sh ./scripts/waitForDevice.sh pixel - mkdir -p ./detox_node/ - npm install --prefix ./detox_node/ -g detox-cli - npm install --prefix ./detox_node/ -g react-native-cli - npm install script: - ./detox_node/bin/react-native start --port 2137 & - ./detox_node/bin/detox build -c android.emu.debug - ./detox_node/bin/detox test -c android.emu.debug - kill -9 $(lsof -n -i4TCP:2137) tags: - android-emu services: - name: android-emulator:latest alias: pixel
  75. 75. How to integrate With CI - Gitlab CI detox_test:iOS: stage: test before_script: - brew tap wix/brew - brew install --HEAD applesimutils - npm install -g detox-cli - npm install -g react-native-cli - npm install script: - react-native start --port 2137 & - detox build -c ios.sim.debug - detox test -c ios.sim.debug - kill -9 $(lsof -n -i4TCP:2137) tags: - xcode-9.2 detox_test:android: stage: test before_script: - adb connect pixel:5555; sh ./scripts/waitForDevice.sh pixel - mkdir -p ./detox_node/ - npm install --prefix ./detox_node/ -g detox-cli - npm install --prefix ./detox_node/ -g react-native-cli - npm install script: - ./detox_node/bin/react-native start --port 2137 & - ./detox_node/bin/detox build -c android.emu.debug - ./detox_node/bin/detox test -c android.emu.debug - kill -9 $(lsof -n -i4TCP:2137) tags: - android-emu services: - name: android-emulator:latest alias: pixel entrypoint: ["/start-emulator.sh", "android-23", "x86", "pixel"]
  76. 76. Show time!
  77. 77. Key TAkeaways ● Cross platform apps can be tested with the same frameworks as native ones ● For typical apps you can avoid code duplication and use cross- platform frameworks ● Detox is a great tool for React Native UI testing
  78. 78. Questions ? :)
  79. 79. Thank You! You can read about Testing and more at polidea.com/blog @astasIcons by: Freepik and Roundicons

×