如何在 iOS UItest 中选择本地化的日期选择器项目

Posted

技术标签:

【中文标题】如何在 iOS UItest 中选择本地化的日期选择器项目【英文标题】:How to select a localized date picker item in an iOS UItest 【发布时间】:2016-11-01 20:53:54 【问题描述】:

我有一个选择器视图,其中包含在 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 中找到当前值 '(null)' . 麦, 16. 麦, 17. 麦, 18. 麦, 19. 麦, 20. 麦, 21. 麦, 22. 麦, 23. 麦, 24. 麦, 25. 麦, 26. 麦, 27. 麦, 28. Mai, 29. Mai, 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. Juni, 13. Juni, 14. Juni, 15. Juni, 16. Juni, 17. Juni, 18. Juni, 19. Juni, 20. Juni, 21. Juni , 22. 朱尼, 23. 朱尼, 24. 朱尼, 25. 朱尼, 26. 朱尼, 27. 朱尼, 28. 朱尼, 29.朱尼, 30. 朱丽, 1. 朱丽, 2. 朱丽, 3. 朱丽, 4. 朱丽, 5. 朱丽, 6. 朱丽, 7. 朱丽, 8. 朱丽, 9. 朱丽, 10. 朱丽, 11. Juli, 12. Juli, 13. Juli, 14. Juli, 15. Juli, 16. Juli, 17. Juli, 18. Juli, 19. Juli, 20. Juli, 21. Juli, 22. Juli, 23. Juli, 24. Juli, 25. Juli, 26. Juli, 27. Juli, 28. Juli, 29. Juli, 30. Juli, 31. Juli, 1. Aug., 2. Aug., 3. Aug., 4 . 八月, 5. 八月, 6. 八月, 7. 八月, 8. 八月, 9. 八月, 10. 八月, 11. 八月, 12. 八月, 13. 八月, 14 . Aug., 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 代码得到了相同的结果:

How to select a picker view item in an ios UI test in Xcode?

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

【问题讨论】:

【参考方案1】:

可能为时已晚,但这帮助了我

 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")

【讨论】:

【参考方案2】:

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

更安全的方法是使用正则表达式来推断哪个轮对应于每个日期组件。我的意思是,天满足正则表达式\d1,2,年满足正则表达式\d4,月满足正则表达式[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("^\\d1,2$").firstMatch
    case .month:
      return datePicker.pickerWheels.regex2("[A-Za-z]*").firstMatch
    case .year:
      return datePicker.pickerWheels.regex2("^\\d4$").firstMatch
    
  

【讨论】:

以上是关于如何在 iOS UItest 中选择本地化的日期选择器项目的主要内容,如果未能解决你的问题,请参考以下文章

iOS 在 Xcode UITest 中测试本地文件导入/打开

从 UITest 中选择集合视图中的第一个单元格

如何在需要使用 Xamarin.UITest 访问 iOS 上的照片的权限对话框中点击确定按钮?

如何使用 xamarin.UITest 从 iOS 上的表格单元格中清除文本?

尝试选择选取器元素时出现 iOS UITest 错误

如何与 Xamarin UITest 中的自定义键盘进行交互?