如何在iOS UItest

时间:2016-06-29 23:19:39

标签: ios swift datetime datepicker uitest

我有一个选择器视图,其中包含在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测试失败 - 内部错误:无法在可能的值中找到当前值'(null)' 11. Mai,12. Mai,13。Mai,14。Mai,15 。Mai,16. Mai,17. Mai,18. Mai,19. Mai,20. Mai,21. Mai,22. Mai,23. Mai,24. Mai,25. Mai,26 Mai,27. Mai ,28。Mai,29。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. Juni,23。Juni,24。Juni,25。Juni,26。Juni,27。Juni,28。Juni, 29。 Juni ,30。Juni,1。Juli,2。Juli,3。Juli,4。Juli,5。Juli,6。Juli,7。Juli,8。Juli,9。Juli,10。Juli, 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。8月,2。8月,3。8月,4 8月,5月8日,6月8日,7月8日,8月​​8日,9月8日,8月​​8日,8月​​8日,8月​​12日,8月13日,8月14日,14日8月,8月15日,8月16日,8月17日,8月18日,8月​​18日,选择轮“Heute”PickerWheel

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

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

这就是上升这个例外的原因。

仅当模拟器首选项“常规/语言和区域”未设置为默认“美国”时,才会显示所述问题。

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

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

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

2 个答案:

答案 0 :(得分: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")

答案 1 :(得分:0)

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

一种更安全的方法是使用正则表达式来推断哪个轮对应于每个日期组件。我的意思是,几天可以满足正则表达式\d{1,2},几年可以满足正则表达式\d{4},而几个月可以满足正则表达式[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
    }
  }