Detox是由Wix公司开发的一款移动应用程序的灰盒、端到端、自动化测试框架。底层使用了Google开源的 Earl Grey(iOS)和 Espresso(Android)。 可以用于React Native APP的自动化测试。
传统黑盒测试做RN APP自动化的缺点:
- 黑盒测试通常通过元素ID/Name等寻找目标元素,当找不到的时候,可能需要循环查询直至timeout或者是添加Sleep等待。找到这个元素之后再做 action,如果找不到则会报错。相当于不知道系统中发生了什么,只是把它当做黑盒去测试。 导致很多时候挂了很多case,但是没有Bug。
- 测试经常会因为不确定因素而挂掉。 因为黑盒测试框架并不能正确得到App是否已经执行完之前的 action,通常会写很多 Sleep 语句确保之前的action执行完成,再进行下一步。 导致自动加测试运行很慢。
- 因为RN App有两个 thread (js 和 native)来控制 App 的渲染,会更难控制 App 的行为
- RN App 第一次打开的时候需要 load 和 parse js bundle,就需要sleep不确定的时间来等待这个过程。
Detox 灰盒自动化测试特点:
- 可以从 App 的内部来监听 App 的行为, 保证测试用例的指令和 App 的行为是同步的。 和 App 在同一个进程中,可以访问 App 执行时的内存, 可以监听在进程中在执行的任务。比如网络请求是否完成/主线程是否空闲/其他的线程是否空闲等等
- Detox 会自动监视 App 的所有 Async 任务, 确保 App 完全闲置, UI 页面也不会变化的时候再执行下一步,因此从根本上保证了测试用例和 App 行为的同步,不需要加Wait或者Sleep条件
- Detox 支持 Android 和 iOS,在iOS和Android的代码几乎相同, 所以可以使用一套e2e的测试脚本
- Detox 的特性自然保证了在测试刚开始运行的时候等待load和parse js bundle, 然后立刻开始运行测试脚本
- 支持各种 Test runner, 比如Mocha, AVA,Jest等
- 搭建环境相对比较简单,运行的时候只需要detox build命令来编测试app和detox test来执行脚本即可
前期准备工作:
-
安装Xcode,可以在App Store里安装,Xcode较大,安装比较慢。后续需要使用Xcode的模拟器
-
安装 Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
- 安装 applesimutils
Detox要使用它与模拟器进行通信,用于iPhone模拟器的utils集合
brew tap wix/brew
brew install applesimutils
- 安装全局 detox-cli
npm install -g detox-cli
- 安装全局 react-native
npm install react-native -g
创建项目:
- 进入一个目录,将创建的项目放在目录下。执行命令创建项目, 下边命令先安装依赖然后创建一个非常简单干净的React Native项。 testReactNativeDetox是项目的名称,可以自定义
react-native init testReactNativeDetox
- 进入项目
cd testReactNativeDetox
- 启动模拟器
react-native run-ios
- 局部安装detox
npm install detox --save-dev
- 局部安装Jest和jest-cli
npm install jest jest-cli --save-dev
- 将Detox初始化为使用Jest
detox init -r jest
修改配置:
- 如果在初始化使用jest的时候,自动创建了.detoxrc.json 文件,将其删除掉
- 配置 package.json 文件,添加 下边代码
"detox": {
"test-runner": "jest",
"configurations": {
"ios.release": {
"binaryPath": "./ios/build/Build/Products/Release-iphonesimulator/testReactNativeDetox.app",
"build": "xcodebuild -workspace ios/testReactNativeDetox.xcworkspace -configuration release -scheme testReactNativeDetox -sdk iphonesimulator -derivedDataPath ios/build",
"type": "ios.simulator",
"name": "iPhone 11"
}
}
}
binaryPath: 是APP所在的路径,因为还没有build所以不存在,但是相对路径都是一样的,把项目名称修改清楚即可
build: build项目的时候用的命令,也需要把项目名称修改清楚
- e2e/config.json 文件配置
{
"setupFilesAfterEnv": [
"./init.js"
],
"testEnvironment": "node",
"reporters": [
"detox/runners/jest/streamlineReporter"
],
"verbose": true
}
- e2e/init.js 文件配置
const detox = require('detox');
const config = require('../package.json').detox;
const adapter = require('detox/runners/jest/adapter');
const specReporter = require('detox/runners/jest/specReporter');
const assignReporter = require('detox/runners/jest/assignReporter');
// Set the default timeout
jest.setTimeout(300000);
jasmine.getEnv().addReporter(adapter);
// This takes care of generating status logs on a per-spec basis. By default, jest only reports at file-level.
// This is strictly optional.
jasmine.getEnv().addReporter(specReporter);
// This will post which device has assigned to run a suite, which can be useful in a multiple-worker tests run.
// This is strictly optional.
jasmine.getEnv().addReporter(assignReporter);
beforeAll(async () => {
await detox.init(config);
});
beforeEach(async () => {
await adapter.beforeEach();
});
afterAll(async () => {
await adapter.afterAll();
await detox.cleanup();
});
- 在e2e文件夹下创建一个自动化测试用例文件 firstTest.test.js 文件,编写测试用例
describe('Example', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should show "Step One Two" at the begging', async () => {
await expect(element(by.text('Step One Two'))).toBeVisible();
});
});
运行测试:
- Build项目
detox build
- 执行测试用例
detox test
网友评论