5

我有一个选择器视图,其中包含在 Interface Builder 中创建的日期选择器。在属性检查器中选择:模式“日期和时间”。在我的 UI 测试中,我需要从中选择一个特定的日期和时间。我正在使用 Xcode 7 引入的 XCTest UI 测试 API。

我的本地化美国日期和时间选择器的测试代码如下所示:

app.tables.pickerWheels.elementBoundByIndex(0).adjustToPickerWheelValue("Jun 29")
app.tables.pickerWheels.elementBoundByIndex(1).adjustToPickerWheelValue("12")
app.tables.pickerWheels.elementBoundByIndex(2).adjustToPickerWheelValue("10")
app.tables.pickerWheels.elementBoundByIndex(3).adjustToPickerWheelValue("PM")

这将完美无缺!

我的本地化德语日期和时间选择器的测试代码如下所示:

app.tables.pickerWheels.elementBoundByIndex(0).adjustToPickerWheelValue("29. Juni")
app.tables.pickerWheels.elementBoundByIndex(1).adjustToPickerWheelValue("07")
app.tables.pickerWheels.elementBoundByIndex(2).adjustToPickerWheelValue("10")

在这种情况下,我得到以下异常:

断言失败:UI 测试失败 - 内部错误:无法在可能的值 11.Mai、12.Mai、13.Mai、14.Mai、15.Mai、16.Mai、17.Mai中找到当前值“(null)” , 18. 麦, 19. 麦, 20. 麦, 21. 麦, 22. 麦, 23. 麦, 24. 麦, 25. 麦, 26. 麦, 27. 麦, 28. 麦, 29. 麦, 30 . Mai, 31. Mai, 1. Juni, 2. Juni, 3. Juni, 4. Juni, 5. Juni, 6. Juni, 7. Juni, 8. Juni, 9. Juni, 10. Juni, 11. Juni , 12. 朱尼, 13. 朱尼, 14. 朱尼, 15. 朱尼, 16. 朱尼, 17. 朱尼, 18. 朱尼, 19. 朱尼, 20. 朱尼, 21. 朱尼, 22. 朱尼, 23. 朱尼, 24 . 朱尼, 25. 朱尼, 26. 朱尼, 27. 朱尼, 28. 朱尼, 29. 朱尼, 30. Juli, 1. Juli, 2. Juli, 3. Juli, 4. Juli, 5. Juli, 6. Juli, 7. Juli, 8. Juli, 9. Juli, 10. Juli, 11. Juli, 12 . 朱利 13. 朱利 14. 朱利 15. 朱利 16. 朱利 17. 朱利 18. 朱利 19. 朱利 20. 朱利 21. 朱利 22. 朱利 23. 朱利 24. 朱利, 25. Juli, 26. Juli, 27. Juli, 28. Juli, 29. Juli, 30. Juli, 31. Juli, 1. Aug., 2. Aug., 3. Aug., 4. Aug., 5 . 八月, 6. 八月, 7. 八月, 8. 八月, 9. 八月, 10. 八月, 11. 八月, 12. 八月, 13. 八月, 14. 八月, 15 . Aug., 16. Aug., 17. Aug., 18. Aug. 用于拾取轮“Heute” PickerWheel

我认为,“(null)”表示没有为 UITest 查询设置搜索字符串:

app.tables.pickerWheels.elementBoundByIndex(0).adjustToPickerWheelValue("29. Juni")

这就是引发此异常的原因。

仅当模拟器首选项“ General / Language & Region ”未设置为默认值“United States”时,才会出现所描述的问题。

当我在模拟器中切换到其他语言设置时,我使用上面自己的 swift 代码以及以下帖子中提到的 Objective-C 代码得到了相同的结果:

如何在 Xcode 的 iOS UI 测试中选择选择器视图项?

我绝对必须使用本地化的日期和时间选择器来执行我的 UITestings ! 有谁知道,这里出了什么问题以及是否有解决方案?

4

2 回答 2

2

Probably too late, but this helped me out

 let dateComponent = Calendar.current.dateComponents([.day, .month, .year], from: Date())
 let formatter = DateFormatter()
 formatter.dateFormat = "MMMM"
 let monthText = formatter.string(from: Date())

 datePicker.pickerWheels[String(dateComponent.year!)].adjust(toPickerWheelValue: "2017")
 datePicker.pickerWheels[monthText].adjust(toPickerWheelValue: "December")
 datePicker.pickerWheels[String(dateComponent.day!)].adjust(toPickerWheelValue: "21")
于 2017-12-23T21:45:43.840 回答
-1

前面的解决方案假定选择器在当前日期开始。如果我们想要更改日期两次或更多次,例如测试日期验证是否正常工作,我们可能会遇到问题。

更安全的方法是使用正则表达式来推断哪个轮对应于每个日期组件。我的意思是, days 满足 regex \d{1,2}, years 满足 regex \d{4},而 months 满足 regex [A-Za-z]*。无论我们使用哪种本地化。

所以,使用这个 XCUIElementQuery 扩展:

extension XCUIElementQuery {
  func regex(_ regexPattern: String) -> XCUIElementQuery {
    let satisfiesRegex = NSPredicate { (evaluatedObject, _) in
      guard let element = evaluatedObject as? XCUIElementAttributes else { return false }
      guard let text = element.value as? String else { return false }
      guard let regex = try? NSRegularExpression(pattern: regexPattern) else { return false }
      let range = NSRange(location: 0, length: text.count)
      return regex.firstMatch(in: text, options: [], range: range) != nil
    }
    return self.containing(satisfiesRegex)
  }
}

我们可以做到以下几点:

  func datePickerWheelFor(_ wheelType: DatePickerWheelType) -> XCUIElement {
    let datePicker = XCUIApplication().datePickers
    switch wheelType {
    case .day:
      return datePicker.pickerWheels.regex2("^\\d{1,2}$").firstMatch
    case .month:
      return datePicker.pickerWheels.regex2("[A-Za-z]*").firstMatch
    case .year:
      return datePicker.pickerWheels.regex2("^\\d{4}$").firstMatch
    }
  }
于 2019-04-05T20:32:36.327 回答