如果事先询问过,请提前道歉。我遇到了用于响应 native 应用程序的detox e2e框架,因此想到了尝试一下。

我正在尝试自动执行此处给出的此演示移动应用程序-link
由于detox中的测试使用testID作为定位符之一,因此我在LoginScreenMaterial.js内的app/screen/LoginScreenMaterial.js文件中添加了一个这样的定位符

<View testID="login_screen" style={{width: this._width, justifyContent: 'center'}}>
          <RkCard style={styles.container}>
            <View rkCardHeader style={styles.header}>
              <RkText/>
              <RkText style={styles.label}>Sign in into your account</RkText>
            </View>

但是,即使在成功构建了应用程序之后,我还是通过这个简单的测试运行了该应用程序
it('should have welcome screen', async () => {
    await expect(element(by.id('login_screen'))).toBeVisible();
  });

但是,测试仍然失败,无法识别该元素。我在此测试中缺少什么?我们不能在testID文件中明确添加像这样的.js吗?

编辑1:添加错误消息
1) Example
       should have welcome screen:
     Error: Error: Cannot find UI Element.
Exception with Assertion: {
  "Assertion Criteria" : "assertWithMatcher:matcherForSufficientlyVisible(>=0.750000)",
  "Element Matcher" : "(((respondsToSelector(accessibilityIdentifier) && accessibilityID('login_screen')) && !(kindOfClass('RCTScrollView'))) || (kindOfClass('UIScrollView') && ((kindOfClass('UIView') || respondsToSelector(accessibilityContainer)) && ancestorThatMatches(((respondsToSelector(accessibilityIdentifier) && accessibilityID('login_screen')) && kindOfClass('RCTScrollView'))))))",
  "Recovery Suggestion" : "Check if the element exists in the UI hierarchy printed below. If it exists, adjust the matcher so that it accurately matches element."
}

Error Trace: [
  {
    "Description" : "Interaction cannot continue because the desired element was not found.",
    "Error Domain" : "com.google.earlgrey.ElementInteractionErrorDomain",
    "Error Code" : "0",
    "File Name" : "GREYElementInteraction.m",
    "Function Name" : "-[GREYElementInteraction matchedElementsWithTimeout:error:]",
    "Line" : "124"
  }
]
      at Client.execute (node_modules/detox/src/client/Client.js:74:13)

最佳答案

我看了看该应用程序,并使其能够正常工作。我在我的devDependencies中设置以下内容。

  "devDependencies": {
    ...
    "jest": "23.2.0",
    "detox": "8.0.0"
    ...
  },

我还向package.json添加了
"detox": {
    "configurations": {
      "ios.sim.debug": {
        "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/BoomApp.app",
        "build": "xcodebuild -project ios/BoomApp.xcodeproj -scheme BoomApp -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build",
        "type": "ios.simulator",
        "name": "iPhone 7"
      }
    },

我跑了detox init -r jest
然后,我可以通过将testID添加到ScrollView LoginScreenBlur.js(第23行)中来识别何时渲染了特定屏幕。
<AppWrapper>
    <ScrollView contentContainerStyle={{flex: 1}} testID={'login_screen'}>
    ....
    </ScrollView>
</AppWrapper>

然后在e2e/firstTest.spec.js中,我将测试替换为
  it('should have loginScreen', async () => {
    await expect(element(by.id('login_screen'))).toBeVisible();
  });

这是我运行detox build && detox test后的控制台响应
node_modules/.bin/jest e2e --config=e2e/config.json --maxWorkers=1 --testNamePattern='^((?!:android:).)*$'
 server listening on localhost:64579...
 : Searching for device matching iPhone 7...
 : Uninstalling org.reactjs.native.example.BoomApp...
 : org.reactjs.native.example.BoomApp uninstalled
 : Installing /Users/work/Downloads/react-native-ui-kitten-demo-app-master/ios/build/Build/Products/Debug-iphonesimulator/BoomApp.app...
 : /Users/work/Downloads/react-native-ui-kitten-demo-app-master/ios/build/Build/Products/Debug-iphonesimulator/BoomApp.app installed
 : Terminating org.reactjs.native.example.BoomApp...
 : org.reactjs.native.example.BoomApp terminated
 : Launching org.reactjs.native.example.BoomApp...
7: org.reactjs.native.example.BoomApp launched. The stdout and stderr logs were recreated, you can watch them with:
        tail -F /Users/work/Library/Developer/CoreSimulator/Devices/AF406169-5CF3-4480-9D00-8F934C420043/data/tmp/detox.last_launch_app_log.{out,err}
 PASS  e2e/firstTest.spec.js (7.935s)
  Example
    ✓ should have loginScreen (1499ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        8.87s, estimated 9s
Ran all test suites matching /e2e/i with tests matching "^((?!:android:).)*$".

看来该应用程序默认情况下会启动LoginLogBlur,因此先测试它,而不是LoginScreenMaterial才有意义。

我注意到的一件事是该应用程序使用RKTextInputRkButton,它们不是 native 组件,而是围绕 native 组件的包装。这意味着您将需要将testID向下传递给您想要拥有testID的 native 组件。我不确定react-native-ui-kitten是否支持辅助功能标签,因此,如果您希望自动输入文本和点击按钮,可能还有更多工作要做。

将testID添加到自定义组件

请参阅步骤3 https://github.com/wix/detox/blob/master/docs/Introduction.WritingFirstTest.md



https://github.com/wix/detox/blob/master/docs/Troubleshooting.RunningTests.md#cant-find-my-component-even-though-i-added-testid-to-its-props给出了将testID添加到自定义组件的更详细说明。

简要地说,您应该按如下方式实现自定义组件。

自定义组件
export class MyCompositeComponent extends Component {
  render() {
    return (
      <TouchableOpacity testID={this.props.testID}>
        <View>
          <Text>Something something</Text>
        </View>
      </TouchableOpacity>
    );
  }
}

使用自定义组件

然后,您应该像这样使用它。
render() {
  return <MyCompositeComponent testID='MyUniqueId123' />;
}

搜索层次结构

如果您已完成上述操作,并且确定您的商品具有正确的testID并且测试仍然失败,则可以在 View 层次结构https://github.com/wix/detox/blob/master/docs/Troubleshooting.RunningTests.md#debug-view-hierarchy中进行搜索

我不会完整重复以上帖子,但步骤是
  • 在模拟器中启动可调试的应用程序(不是发行版)
  • 打开Xcode
  • 将Xcode附加到应用程序的进程
  • 按下“调试 View 层次结构”按钮
  • 这将打开层次结构查看器,并显示应用程序的 native View 层次结构的分割。在这里您可以浏览
  • View
  • React native testID在 native View 层次结构
  • 中表现为可访问性标识符

    关于react-native - 排毒测试即使添加ID也无法识别View,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51094651/

    10-09 02:28