XCTest无法访问屏幕上的错误消息标签

时间:2017-08-29 13:20:10

标签: ios xcode8 xctest xcode-ui-testing

背景信息:

我需要为简单的应用程序屏幕编写一些UI测试,它在顶部有一个导航栏,在屏幕的其余部分有一个带有两个单元格的表格。

每个单元格包含:

  • 标签(“会员卡号”)
  • 输入的安全文本字段
  • 安全区域下的标签(“这是您必须放置的标签 10位忠诚卡号码“)
  • 一个可选的错误文本,仅在输入字段下显示 用户输入少于或多于所需数字的数量

这是一个图像,可以了解屏幕上的元素 image

目标:

编写测试执行以下操作:

  • 点击卡片输入栏
  • 键入无效的卡号(例如,12位而不是10位)
  • 检查字段
  • 下是否显示错误消息

问题:

XCTest无法识别包含错误的元素。

当我使用Debug View Hierarchy检查元素时,它在那里,清晰可见,文本属性为“不能少于或多于10位”,并且accessibiltyIndentifier为“errorField”。

Hierachy:UIWindow-> UILayoutContainerView-> UINavigationTransitionView-> UIViewControllerWrapperView-> UIView-> Form-> FormTextFieldCell-> UITableViewCellContentView-> UIView-> UILabel

它有一个兄弟,也有UILabel(“这是你必须把你的10位忠诚卡”的地方) - 并且访问这个兄弟没有问题。我可以通过accessibilityIdentifier或其文本访问它:

app.staticTexts["hintField"]
app.staticTexts["This is where you must put your 10-digit loyalty card"]

这些选项都不适用于我感兴趣的元素。当我打印app.debugDescription时,该元素就不存在,就好像它不存在一样。

在用户输入错误并且屏幕上已显示错误文本后,这是debugDescription的输出:

Element subtree:
 →Application 0x60000016e700: {{0.0, 0.0}, {414.0, 736.0}}, label: ‘test-app’
Window 0x60000016e7c0: Main Window, {{0.0, 0.0}, {414.0, 736.0}}
  Other 0x60000016e4c0: traits: 8589934592, {{0.0, 0.0}, {414.0, 736.0}}
    NavigationBar 0x60000016e580: traits: 35192962023424, {{0.0, 20.0}, {414.0, 44.0}}, identifier: ‘Card Info Screen’
      Button 0x60000016e880: traits: 8589934593, {{20.0, 26.7}, {53.0, 30.0}}, label: ‘Back’
      StaticText 0x60000016eac0: traits: 8590000192, {{158.7, 28.0}, {97.0, 27.0}}, label: ‘Next’
      Button 0x60000016ea00: traits: 8589934849, {{356.0, 26.7}, {38.0, 30.0}}, label: ‘Next’
    Other 0x60000016e940: traits: 8589934592, {{0.0, 0.0}, {414.0, 736.0}}
      Other 0x60000016ed00: traits: 8589934592, {{0.0, 0.0}, {414.0, 736.0}}
        Other 0x60000016edc0: traits: 8589934592, {{0.0, 64.0}, {414.0, 672.0}}
          Other 0x60000016ee80: traits: 8589934592, {{0.0, 64.0}, {414.0, 48.0}}
            StaticText 0x60000016eb80: traits: 8589934656, {{24.0, 79.0}, {366.0, 18.0}}, label: ‘Enter your loyalty card information.’
          Table 0x60000016ef40: traits: 35192962023424, {{0.0, 112.0}, {414.0, 573.0}}
            Cell 0x60000016ec40: traits: 8589934592, {{0.0, 112.0}, {414.0, 67.0}}
              StaticText 0x60000016f000: traits: 8589934656, {{16.0, 123.3}, {96.3, 18.0}}, label: ‘Your loyalty card nr’
              StaticText 0x60000016f0c0: traits: 8589934656, {{16.0, 158.7}, {390.0, 13.7}}, identifier: ‘hintField’, label: ‘This is where you must put your 10-digit loyalty card.’
              SecureTextField 0x60000016f180: traits: 8609071104, Keyboard Focused, {{119.3, 122.0}, {286.7, 20.0}}, identifier: ‘editField’, value: ••••••••••••
            Cell 0x60000016f240: traits: 8589934592, {{0.0, 179.0}, {414.0, 53.0}}
              StaticText 0x60000016f300: traits: 8589934656, {{16.0, 189.0}, {100.7, 18.0}}, label: ‘Birthday’
              StaticText 0x60000016f3c0: traits: 8589934656, {{16.0, 210.0}, {390.0, 13.7}}, identifier: ‘hintField’, label: ‘Please enter your birthday in DDMMYYYY format’
              SecureTextField 0x60000016f480: traits: 8606973952, {{123.7, 189.0}, {282.3, 18.0}}, identifier: ‘editField’, placeholderValue: ‘********’
            Cell 0x60000016f540: traits: 8589934592, {{0.0, 232.0}, {414.0, 70.0}}
          Other 0x60000016f600: traits: 8589934592, {{0.0, 685.0}, {414.0, 51.0}}
            StaticText 0x60000016f6c0: traits: 8589934656, {{112.0, 685.0}, {190.0, 15.7}}, label: ‘Don't have a loyalty card yet?’
            Button 0x60000016f780: traits: 8589934593, {{162.7, 705.7}, {90.0, 22.3}}, label: ‘Get one in one of our stores!’

当我尝试使用Test Recorder时,以任何方式与错误交互会导致: “带时间戳的事件匹配错误:找不到匹配的元素”。

我应该注意,Test Recorder对屏幕上的任何其他元素都没有这个问题。他无法录制的唯一元素是错误消息。他不能用忠诚卡为第一个单元格做这个,而且他也不能为生日那天的第二个单元格做这件事。

我尝试通过以下方式访问这个难以捉摸的元素:

app.staticTexts["ACCESSIBILITY_ID"]
app.staticTexts["ELEMENTS_TEXT]
app.cells.containing(.staticText, identifier: "ACCESSIBILITY_ID_OF_PARENT").otherElements.element

不幸的是,迄今为止没有任何工作。

我被其他测试阻止并严重绝望。

任何帮助,任何建议都将受到高度赞赏!

1 个答案:

答案 0 :(得分:3)

首先要检查的是Accessibility框架是否可以看到该元素。要查看可访问性,请启动您的应用并转到

打开辅助功能检查器
Xcode -> Open Developer Tool -> Accessibility Inspector

然后,选择左上方目标列表下的模拟器,并选择右上角的目标十字线。将鼠标悬停在要检查的标签上。这将显示可访问性值和标签(以及Xcode 9中的标识符)。如果辅助功能检查员无法看到它,则标签在代码中的设置方式存在问题,这意味着Voice Over用户也不会将其读取给他们。

由于您现有的XCUITest层次结构显示了UITableViewCell的内容,我们可能会排除该单元格是一个离散的可访问性元素(这会隐藏XCUITest / accessibility的子视图。您可以检查该单元格不是标记为可访问性元素.UIView标志为isAccessibilityElement = true。您还可以检查开发人员是否将其设置为true,然后设置可访问的子视图:

myCell.accessibilityElements = [inputTextField, label1, label2] // left out error label, hence it's not accessible

如果您担心层次结构可能无法刷新,您可以尝试通过以下方式显示错误视图后刷新它:

UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, myErrorLabel);

当它出现时,还会将可访问性焦点切换到该错误。 (有关在此处发布辅助功能通知的更多信息:https://developer.apple.com/documentation/uikit/accessibility/uiaccessibility