实际上是否可以通过在Expo上运行的React Native应用程序使Detox/Jest测试通过? [英] Is it actually possible to make Detox/Jest tests pass with a React Native app running with Expo?
问题描述
我正在尝试为我的带有Expo的React Native应用程序创建一个自动化的UI测试套件.我到处都在寻找好的教程,但是当我进入实际的测试写作部分时,由于环境问题,例如import Icon from...
上的意外标识符/令牌"或其他愚蠢的问题而我无法找到任何教程,因此我的测试甚至无法运行如何解决它们.我实际上花了一个星期的时间来尝试解决这些问题.
I'm attempting to create an automated UI test suite for my React Native app with Expo. I have looked everywhere for good tutorials but when I get to the actual test writing portion, my tests never even run because of environment issues such as "Unexpected Identifier/Token" on import Icon from...
or other stupid issues that I cannot find any tutorials on how to fix them. I literally have spent a week trying to resolve these issues.
我是React Native的新手,还是Jest/Detox/Expo的新手
I am new to React Native and new to Jest/Detox/Expo
这是我的package.json
Here's my package.json
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"test": "node_modules/.bin/jest test/**/*.spec.js",
"eject": "expo eject"
},
"jest": {
"verbose": true,
"preset": "jest-expo"
},
"dependencies": {
"apsl-react-native-button": "^3.1.1",
"react": "16.5.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
"react-native-camera": "git+https://git@github.com/react-native-community/react-native-camera.git",
"react-native-camera-roll-picker": "^1.2.3",
"react-native-elements": "^1.0.0",
"react-native-fontawesome": "^6.0.1",
"react-native-is-iphonex": "^1.0.1",
"react-native-vector-icons": "^6.2.0",
"react-navigation": "^3.1.5"
},
"devDependencies": {
"babel-preset-expo": "^5.0.0",
"bunyan-debug-stream": "^2.0.0",
"detox": "^10.0.9",
"detox-expo-helpers": "^0.6.0",
"expo-detox-hook": "^1.0.10",
"jest-expo": "^32.0.0",
"react-native-testing-library": "^1.5.0",
"react-test-renderer": "^16.8.2",
"babel-jest": "^24.1.0",
"enzyme": "^3.9.0",
"@babel/core": "^7.3.3",
"@expo/vector-icons": "^9.0.0",
"expo": "^32.0.0",
"jest": "^24.1.0"
},
"private": true,
"detox": {
"test-runner": "jest",
"configurations": {
"ios.sim": {
"binaryPath": "bin/Exponent.app",
"type": "ios.simulator",
"name": "iPhone X"
}
}
}
}
这是我遇到的错误
ip-10-101-32-118:KitchenProject bob.dole$ detox test --loglevel trace
configuration="ios.sim" loglevel="trace" artifactsLocation="artifacts/ios.sim.2019-02-21 21-54-14Z" node_modules/.bin/jest "e2e" --config=e2e/config.json --maxWorkers=1 '--testNamePattern=^((?!:android:).)*$'
● Deprecation Warning:
Option "setupTestFrameworkScriptFile" was replaced by configuration "setupFilesAfterEnv", which supports multiple paths.
Please update your configuration.
Configuration Documentation:
https://jestjs.io/docs/configuration.html
FAIL e2e/RoomLayout.spec.js
● Test suite failed to run
/Users/bob.dole/KitchenDetail/KitchenProject/node_modules/@expo/vector-icons/FontAwesome.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import glyphMap from './vendor/react-native-vector-icons/glyphmaps/FontAwesome.json';
^^^^^^^^
SyntaxError: Unexpected identifier
> 1 | import FontAwesomeI from 'react-native-vector-icons/FontAwesome'
| ^
2 | import React from 'react'
3 |
4 | export const FontAwesome = props => (
at ScriptTransformer._transformAndBuildScript (../node_modules/jest/node_modules/jest-runtime/build/ScriptTransformer.js:440:17)
at Object.<anonymous> (../Components/icons.js:1:1)
FAIL e2e/tests/components/RoomLayoutDetox.spec.js
● Test suite failed to run
/Users/bob.dole/KitchenDetail/KitchenProject/node_modules/@expo/vector-icons/FontAwesome.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import glyphMap from './vendor/react-native-vector-icons/glyphmaps/FontAwesome.json';
^^^^^^^^
SyntaxError: Unexpected identifier
> 1 | import FontAwesomeI from 'react-native-vector-icons/FontAwesome'
| ^
2 | import React from 'react'
3 |
4 | export const FontAwesome = props => (
at ScriptTransformer._transformAndBuildScript (../node_modules/jest/node_modules/jest-runtime/build/ScriptTransformer.js:440:17)
at Object.<anonymous> (../Components/icons.js:1:1)
Test Suites: 2 failed, 2 total
Tests: 0 total
Snapshots: 0 total
Time: 0.827s
Ran all test suites matching /e2e/i with tests matching "^((?!:android:).)*$".
child_process.js:677
throw err;
^
Error: Command failed: node_modules/.bin/jest "e2e" --config=e2e/config.json --maxWorkers=1 '--testNamePattern=^((?!:android:).)*$'
at checkExecSyncError (child_process.js:637:11)
at Object.execSync (child_process.js:674:13)
at runJest (/Users/bob.dole/KitchenDetail/KitchenProject/node_modules/detox/local-cli/detox-test.js:166:6)
at run (/Users/bob.dole/KitchenDetail/KitchenProject/node_modules/detox/local-cli/detox-test.js:86:7)
at Object.<anonymous> (/Users/bob.dole/KitchenDetail/KitchenProject/node_modules/detox/local-cli/detox-test.js:229:1)
at Module._compile (internal/modules/cjs/loader.js:738:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:749:10)
at Module.load (internal/modules/cjs/loader.js:630:32)
at tryModuleLoad (internal/modules/cjs/loader.js:570:12)
at Function.Module._load (internal/modules/cjs/loader.js:562:3)
这是我的组件文件 RoomLayout.js
Here's my component file RoomLayout.js
import React, { Component } from 'react';
import { StyleSheet, View, Text, Button } from 'react-native';
import { LayoutButtons } from './LayoutButtons';
import { CameraLauncher } from './CameraLauncher';
import { CommentsLauncher } from './CommentsLauncher';
export class RoomLayout extends Component {
render() {
return (
<View>
<Text testID='roomLayoutText' style={styles.room}>
Room Layout{"\n"}
</Text>
<Text testID='infoText' style={styles.infoText}>
Take photos from opposite corners of the room{"\n"}
</Text>
<LayoutButtons />
</View>
);
}
}
const styles = StyleSheet.create({
view: {
marginTop: 80,
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center'
},
infoText: {
marginTop: -10,
fontWeight: 'normal',
textAlign: 'center',
fontSize: 12,
justifyContent: 'center',
alignSelf: 'center',
color: 'grey'
},
room: {
marginTop: 15,
fontWeight: 'bold',
textAlign: 'center',
lineHeight: 14,
fontSize: 15
}
});
这是我的RoomLayout.spec.js文件
Here's my RoomLayout.spec.js file
import React from 'react';
// import { RoomLayout } from '../Components/RoomLayout';
import { render } from 'react-native-testing-library';
describe('RoomLayout', () => {
// *** EDIT - I have removed this code ***
// beforeEach(async () => {
// const tree = render(<RoomLayout />);
//
// });
test('should have header and info text', async () => {
await element(by.text('Room Layout'));
await element(by.id('infoText'));
await element(by.id('infoText').and(by.text(' Take photos from opposite corners of the room')));
await expect(element(by.id('layoutButtonsReference'))).toBeVisible();
});
});
推荐答案
使用Expo应用程序设置排毒.您可能最适合从一个还没有做任何事情的干净应用程序开始.您需要确保已遵循基本设置(步骤1)使排毒在您的机器上工作
Setting up Detox with an Expo app. You're probably best placed to start with a clean app that you haven't done anything with yet. You’ll want to make sure you have followed the basic setup (step 1) for getting detox to work on your machine
npm i -D detox detox-expo-helpers expo-detox-hook jest
更新package.json
将以下内容添加到您的package.json
文件中,这将配置排毒.您可以选择所需的iPhone类型.
Update the package.json
Add the following to your package.json
file, this configures detox. You can choose the type of iPhone that you want.
"detox": {
"configurations": {
"ios.sim": {
"binaryPath": "bin/Exponent.app",
"type": "ios.simulator",
"name": "iPhone X"
}
},
"test-runner": "jest"
}
在脚本部分中添加以下内容:
In the scripts section add the following:
"scripts": {
"e2e": "detox test --configuration ios.sim"
}
这将允许我们运行排毒测试,但使用npm run e2e
This will allow us to run the detox test but using npm run e2e
运行以下命令设置您的第一个测试
Run the following to set up your first test
detox init -r jest
这将在您的项目中添加一个名为e2e
的文件夹.您会在其中找到三个文件
This will add a folder called e2e
in your project. You will find three files inside it
-
config.json
-
firstTest.spec.js
-
init.js
config.json
firstTest.spec.js
init.js
firstTest.spec.js
是一个样本测试.您将需要对其进行以下更改.
firstTest.spec.js
is a sample test. You will need to make the following changes to it.
const { reloadApp } = require('detox-expo-helpers');
您还需要更改以下行
await device.reloadReactNative();
到
await reloadApp();
将Expo Client添加到您的项目中
- 从 Expo.io/tools 下载Expo Client iOS应用.
- 解压缩iOS IPA并将其重命名为
Exponent.app
.它会带有一个文件图标,但仍将是一个文件夹. - 创建
bin
文件夹并将Exponent.app
放入其中,使其与上面设置的binaryPath相匹配. - Download the Expo Client iOS App from Expo.io/tools.
- Unzip the iOS IPA and rename the folder to
Exponent.app
. It'll have a file icon but will still be a folder. - Create
bin
folder and putExponent.app
inside so it matches the binaryPath set above.
Add the Expo Client to your project
或者,您也可以使用以下脚本,在项目根目录中创建一个文件并将其命名为setup.sh
,复制内容然后运行它(您可能需要授予其运行权限,您可以通过首先运行chmod +x setup.sh
,然后可以使用./setup.sh
)运行它.
Or alternatively you could use the following script, create a file and name it setup.sh
in your project root directory, copy the contents and then run it (you will probably need to give it permission to run which you can do by running chmod +x setup.sh
first, then you can run it using ./setup.sh
).
#!/bin/bash -e
# query expo.io to find most recent ipaUrl
IPA_URL=`curl https://expo.io/--/api/v2/versions | python -c 'import sys, json; print json.load(sys.stdin)["iosUrl"]'`
# download tar.gz
TMP_PATH=/tmp/exponent.tar.gz
wget -O $TMP_PATH $IPA_URL
# recursively make app dir
APP_PATH=bin/Exponent.app
mkdir -p $APP_PATH
# unzip tar.gz into APP_PATH
tar -C $APP_PATH -xzf $TMP_PATH
此脚本与上述步骤相同.
This script does the same as the above steps.
使用expo start -c
启动计划用于测试的模拟器(因此,如果您选择了iPhone X,请启动iPhone X等).
Launch the simulator that you plan to use for your test (so if you picked an iPhone X, launch the iPhone X etc).
然后,如果添加了脚本,则可以在终端中运行npm run e2e
,也可以运行detox test
.
Then in your terminal you can run npm run e2e
if you added the script or you can run detox test
.
您将发现测试将失败.没关系,这是可以预期的.
What you will find is that your test will fail. This is ok and to be expected.
现在,如果要通过测试,则需要实现firstTest.spec.js
中存在的所有测试用例,也可以将其删除并编写自己的测试用例.
Now if you want to make your test pass you need to implement all of the test cases that exist in the firstTest.spec.js
or you can scrap those and write your own.
- Detox's own Expo Guide
- Detox setup
- Expo sample app with Detox
如果您希望通过测试,则可以更新以下文件,并且应该获得3个通过测试.
If you want to make your tests pass you can update the following files and you should get 3 passing tests.
firstTest.spec.js
const { reloadApp } = require('detox-expo-helpers');
describe('Example', () => {
beforeEach(async () => {
await reloadApp();
});
it('should have welcome screen', async () => {
await expect(element(by.id('welcome'))).toBeVisible();
});
it('should show hello screen after tap', async () => {
await element(by.id('hello_button')).tap();
await expect(element(by.label('Hello!!!'))).toBeVisible();
});
it('should show world screen after tap', async () => {
await element(by.id('world_button')).tap();
await expect(element(by.label('World!!!'))).toBeVisible();
});
});
App.js
import React, { Component } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
export default class App extends Component {
state = {
greeting: undefined
};
render () {
if (this.state.greeting) return this.renderAfterButton();
return (
<View
testID="welcome"
style={{
flex: 1,
paddingTop: 20,
justifyContent: 'center',
alignItems: 'center'
}}>
<Text style={{ fontSize: 25, marginBottom: 30 }}>Welcome</Text>
<TouchableOpacity
testID="hello_button"
onPress={this.onButtonPress.bind(this, 'Hello')}>
<Text style={{ color: 'blue', marginBottom: 20 }}>Say Hello</Text>
</TouchableOpacity>
<TouchableOpacity
testID="world_button"
onPress={this.onButtonPress.bind(this, 'World')}>
<Text style={{ color: 'blue', marginBottom: 20 }}>Say World</Text>
</TouchableOpacity>
</View>
);
}
renderAfterButton () {
return (
<View
style={{
flex: 1,
paddingTop: 20,
justifyContent: 'center',
alignItems: 'center'
}}>
<Text style={{ fontSize: 25 }}>{this.state.greeting}!!!</Text>
</View>
);
}
onButtonPress (greeting) {
this.setState({
greeting: greeting
});
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
});
这篇关于实际上是否可以通过在Expo上运行的React Native应用程序使Detox/Jest测试通过?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!