如何使用XCTest UI测试在iOS 13中区分标题和静态文本

时间:2019-11-06 14:08:22

标签: ios xctest xcuitest

使用最新版本的Xcode 11在iOS 13上运行,我找不到在XCTest UI测试中区分标题和静态文本的方法。

如果我使用Xcode 11但在iOS 12上运行,则仍然可以通过XCTest按.header元素类型进行过滤来查找具有.other特征的视图,但在iOS 13上使用现在,即使您未在应用程序中设置.header可访问性特征,.staticText特征也仅由XCTest的.staticText元素类型标识。

这对我们来说是一个问题,因为我们使用它来确保记住要在视图上正确设置标头特征以实现可访问性,并确保我们在正确的屏幕中查看测试。

诚然,只能通过.other查找标头并不好,但至少是将标头与常规文本区分开的一种方式。

这里有一些示例代码来说明:

// ViewController.swift

headerLabel.isAccessibilityElement = true // headerLabel is just a UILabel IBOutlet
headerLabel.accessibilityTraits = [.header]
headerLabel.text = "My Header"

// ViewControllerTests.swift

XCTAssertTrue(XCUIApplication().otherElements["My Header"].firstMatch.waitForExistence(timeout: 30)) // This fails on iOS 13 but works on iOS 12 :(
XCTAssertTrue(XCUIApplication().staticTexts["My Header"].firstMatch.waitForExistence(timeout: 30)) // This fails on iOS 12 but works on iOS 13...

如果您在Xcode中po XCUIApplication(),则可以看到在iOS 13上,标头现在与其他所有标签都只是staticText

我尝试结合不同的accessibilityTraits(因为您可以拥有多个),例如:

headerLabel.accessibilityTraits = [.header, .staticText]

但这没有帮助。

2 个答案:

答案 0 :(得分:2)

好吧,经过几天的调查,我们有了一个解决方法。不幸的是,它使用了专用API,但是我们并不担心,因为它用于测试,并且比到目前为止我们尝试过的任何其他解决方法都要好。

使用私有API,可以找出UIAccessibilityTraits所代表的视图的基础XCUIElement

var underlyingAccessibilityTraits: UIAccessibilityTraits {
    guard let rawValue = value(forKey: "traits") as? UInt64 else { return [] }
    return UIAccessibilityTraits(rawValue: rawValue)
}

现在我们有了特征,我们可以与其他任何OptionSet一样查询它们:

element.underlyingAccessibilityTraits.contains(.header)

我们可以使用它来构建自己的查询,而不是使用XCUIElementQuery

let allElementsMatchingID = XCUIApplication().descendants(matching: .any).matching(.any, identifier: id) // id is an optional string as an ID, like when using `XCUIApplication().otherElements[id]`
let allHeaders = allElementsMatchingID.allElementsBoundByAccessibilityElement.filter { $0.underlyingAccessibilityTraits.contains(.header) }
let element = allHeaders[index] // index is an int, like when using `element(boundBy: 0`

此方法的一个缺点(除了必须使用私有API之外)是,与常规XCUIElementQuery不同,如果索引超出范围,则此方法将崩溃,但是如果您始终希望该元素存在那没什么大不了的。

答案 1 :(得分:0)

您可以在标头的accessibilityIdentifier中添加前缀,以区别于静态文本,例如:

myHeader.accessibilityIdentifier = "Header" + title

,并使用与以前相同的静态文本

myLabel.accessibilityIdentifier = title