如何在 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 中测试本地文件导入/打开
如何在需要使用 Xamarin.UITest 访问 iOS 上的照片的权限对话框中点击确定按钮?