SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.
SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.
Successfully reported this slideshow.
Activate your 30 day free trial to unlock unlimited reading.
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobile application testing
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.
1.
REACT Native is coming
The story of hybrid mobile application testing
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.
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.
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.
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
16.
The Native white Box Test
+ Fast
+ Easy setup
+ Wide range of open source
helpers
+ Compatible with Cloud Device
Farms
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
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.
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
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.
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
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.
How to make apps testable?
<Text
accessible= {true}
testID= {"ButtonText"}
accessibilityLabel= {"ButtonTextDesc"}
style={styles.textStyle}>
{!this.state.clicked? defaultButtonText: "Polidea"}
</Text>
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.
How to write Test scripts - Init script by example
require('babel-polyfill');
38.
How to write Test scripts - Init script by example
require('babel-polyfill');
const detox = require('detox');
const config = require('../package.json').detox;
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.
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.
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.
How to write Test scripts - Test class by example
43.
How to write Test scripts - Test class by example
describe('Example', () => {
44.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
45.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
await
46.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
await device
47.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
await device.reloadReactNative();
48.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
await device.reloadReactNative();
await waitFor
49.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
await device.reloadReactNative();
await waitFor(element
50.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
await device.reloadReactNative();
await waitFor(element(by.id('ButtonText')))
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.
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.
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.
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.
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.
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.
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.
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.
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.
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);
});
})
62.
How to integrate With CI - Gitlab CI
detox_test:iOS: detox_test:android:
63.
How to integrate With CI - Gitlab CI
detox_test:iOS:
stage: test
before_script:
detox_test:android:
stage: test
before_script:
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.
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.
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.
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 &
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
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.
1.
REACT Native is coming
The story of hybrid mobile application testing
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.
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.
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.
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
16.
The Native white Box Test
+ Fast
+ Easy setup
+ Wide range of open source
helpers
+ Compatible with Cloud Device
Farms
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
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.
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
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.
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
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.
How to make apps testable?
<Text
accessible= {true}
testID= {"ButtonText"}
accessibilityLabel= {"ButtonTextDesc"}
style={styles.textStyle}>
{!this.state.clicked? defaultButtonText: "Polidea"}
</Text>
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.
How to write Test scripts - Init script by example
require('babel-polyfill');
38.
How to write Test scripts - Init script by example
require('babel-polyfill');
const detox = require('detox');
const config = require('../package.json').detox;
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.
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.
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.
How to write Test scripts - Test class by example
43.
How to write Test scripts - Test class by example
describe('Example', () => {
44.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
45.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
await
46.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
await device
47.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
await device.reloadReactNative();
48.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
await device.reloadReactNative();
await waitFor
49.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
await device.reloadReactNative();
await waitFor(element
50.
How to write Test scripts - Test class by example
describe('Example', () => {
beforeEach(async () => {
await device.reloadReactNative();
await waitFor(element(by.id('ButtonText')))
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.
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.
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.
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.
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.
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.
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.
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.
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.
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);
});
})
62.
How to integrate With CI - Gitlab CI
detox_test:iOS: detox_test:android:
63.
How to integrate With CI - Gitlab CI
detox_test:iOS:
stage: test
before_script:
detox_test:android:
stage: test
before_script:
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.
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.
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.
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 &
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