我正在尝试在React-Native / Expo移动应用上使用Detox设置端到端测试。该应用程序和Jest当前运行良好,但是Detox测试给出了ReferenceError。我已按照https://blog.expo.io/testing-expo-apps-with-detox-and-react-native-testing-library-7fbdbb82ac87链接以及Detox和Jest网站上的说明进行操作。
我已经通过开玩笑的脚本(yarn test
)和detox test
进行了测试。
$ detox test --loglevel trace
detox[51199] INFO: [test.js] configuration="ios.sim" loglevel="trace" artifactsLocation="artifacts/ios.sim.2019-04-26 12-31-53Z" recordLogs="none" takeScreenshots="manual" recordVideos="none" recordPerformance="none" node_modules/.bin/jest --config=e2e/config.json --maxWorkers=1 '--testNamePattern=^((?!:android:).)*$' "e2e"
● Validation Warning:
Unknown option "setupFilesAfterEnv" with value ["./init.js"] was found.
This is probably a typing mistake. Fixing it will remove this message.
Configuration Documentation:
https://jestjs.io/docs/configuration.html
FAIL e2e/features/login/index.spec.js
App
✕ should have login screen (272ms)
✕ should show hello screen after tap (104ms)
✕ should show world screen after tap (105ms)
● App › should have login screen
ReferenceError: device is not defined
at reloadApp (../node_modules/detox-expo-helpers/index.js:68:3)
● App › should have login screen
ReferenceError: element is not defined
...
setupFilesAfterEnv 是一个有趣的选择。
下载的Expo IPA位于bin / Exponent.app目录中。
package.json
{
...
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"test": "jest --watchAll --notify",
"lint": "eslint .",
"ci": "yarn lint && jest"
},
"dependencies": {
"expo": "^32.0.0",
"formik": "^1.5.1",
"invariant": "^2.2.4",
"prop-types": "^15.7.2",
"react": "16.5.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
"react-navigation": "^3.3.2",
"react-redux": "^6.0.1",
"redux": "^4.0.1",
"redux-persist": "^5.10.0",
"redux-thunk": "^2.3.0",
"reselect": "^4.0.0"
},
"devDependencies": {
"@babel/core": "^7.3.4",
"babel-eslint": "^10.0.1",
"babel-plugin-module-resolver": "^3.2.0",
"babel-preset-expo": "^5.0.0",
"detox": "^12.4.1",
"detox-expo-helpers": "^0.6.0",
"eslint": "^5.15.0",
"eslint-config-prettier": "^4.1.0",
"eslint-plugin-prettier": "^3.0.1",
"eslint-plugin-react": "^7.12.4",
"expo-detox-hook": "^1.0.10",
"jest-expo": "^32.0.0",
"prettier": "^1.16.4",
"react-native-testing-library": "^1.7.0",
"react-test-renderer": "^16.8.6",
"redux-devtools-extension": "^2.13.8",
"redux-mock-store": "^1.5.3"
},
"jest": {
"preset": "jest-expo",
"clearMocks": true
},
"detox": {
"test-runner": "jest",
"runner-config": "e2e/config.json",
"configurations": {
"ios.sim": {
"binaryPath": "bin/Exponent.app",
"type": "ios.simulator",
"name": "iPhone XR"
}
}
}
}
e2e目录直接来自Detox,对Expo进行了一些更改。
e2e / config.json
{
"setupFilesAfterEnv": ["./init.js"],
"testEnvironment": "node"
}
e2e / init.js
const detox = require('detox');
const config = require('../package.json').detox;
const adapter = require('detox/runners/jest/adapter');
jest.setTimeout(120000);
jasmine.getEnv().addReporter(adapter);
beforeAll(async () => {
await detox.init(config);
});
beforeEach(async () => {
await adapter.beforeEach();
});
afterAll(async () => {
await adapter.afterAll();
await detox.cleanup();
});
login.spec.js
import { reloadApp } from 'detox-expo-helpers';
describe('App', () => {
beforeEach(async () => {
await reloadApp();
});
it('should have login screen', async () => {
await expect(element(by.id('login'))).toBeVisible();
});
it('should show hello screen after tap', async () => {
await element(by.id('hello_button')).tap();
await expect(element(by.text('Hello!!!'))).toBeVisible();
});
it('should show world screen after tap', async () => {
await element(by.id('world_button')).tap();
await expect(element(by.text('World!!!'))).toBeVisible();
});
});
另一方面,我不知道为什么init.js中有茉莉花参考。我猜是因为JestJS基于Jasmine。无论如何,它似乎与错误无关。
答案 0 :(得分:0)
此问题有一个open pull-request。我引用Yaron Malim
ReferenceError: device is not defined
at Object.reloadApp (../node_modules/detox-expo-helpers/index.js:68:3)
当我添加以下要求时:
const { device } = require('detox');
问题已解决。 为此,我必须添加排毒作为依赖项。这是package.json
{
"name": "detox-expo-helpers",
"version": "0.6.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {},
"dependencies": {
"child-process-promise": "^2.2.1",
"detox": "^12.2.0",
"semver": "^5.6.0",
"xdl": "^51.5.0"
}
}
committed files in the pull request
的详细信息 detox-expo-helpers
github repo包括an example app。添加expo-detox-hook
to your package.json
并运行npm install
{
"devDependencies": {
"detox": "^9.0.6",
"detox-expo-helpers": "^0.6.0",
"expo-detox-hook": "^1.0.10",
"mocha": "^3.5.0"
},
"detox": {
"configurations": {
"ios.sim": {
"binaryPath": "bin/Exponent.app",
"type": "ios.simulator",
"name": "iPhone 7"
}
}
}
}
如official detox-expo-helpers
page所述,除to set up your detox
project以外,您应遵循the package.json
configurations included in this step的每个步骤,expo
与此不同。
detox-expo-helpers
包括仿真器at the step Download the Expo app to some directory in your project and configure in package.json
的正式配置。
它还包括一个example of the Detox
settings for your package.json
您的第二次测试失败,因为Detox
在页面上找不到该元素。
您需要将testID
道具传递给值为'hello_button'
的组件。
it('should show hello screen after tap', async () => {
await element(by.id('hello_button')).tap();
await expect(element(by.text('Hello!!!'))).toBeVisible();
});
documentation on by.id
matcher
by.id
将匹配通过testID
属性提供给视图的ID。
您的组件应该看起来像
<TouchableOpacity testID={'hello_button'}>