Int*_*uff 14 uitableview ios xctest xcode-ui-testing xctestcase
我正在尝试使用(XCode 7)UI XCTestCase测试用例,我只是偶然发现了一个UIView的问题,其中我有一个带有许多单元格(4000+)的UITableView.
当应用程序正常运行时,仅呈现可见单元格,并且根本没有性能问题.但是,如果我在录制XCTestCase的上下文中运行应用程序并导航到此屏幕,则模拟器会冻结,显然是因为每个单个单元格都被渲染为好像是可见的.如果我尝试手动编写导航脚本并运行XCTestCase,则测试用例在导航到此屏幕后立即失败,退出时出现"UI测试失败 - 无法获得刷新快照",显然是因为所有单元格都在渲染,这样做没有及时完成.
我认为这与测试框架构建显示的屏幕的整个元模型这一事实有关,将4000多个单元格中的每一个添加到视图树层次结构中.
我尝试添加一个期望,希望这会给测试容器足够的时间来完成渲染所有单元格,但这不起作用.
这有解决方法吗?是否有可能跳过构建UI树层次结构的某些部分?我的目标是能够为这个屏幕编写UI测试.
如果您可以使用,您可能能够避免渲染整个表格 firstMatch代替element,并且还可以避免count。
我有一个测试,检查表格前两个单元格中的预期标签。起初,我使用app.table.cells.element(boundBy: 0)和app.table.cells.element(boundBy: 1)来查找第一个和第二个单元格。这导致在我可以访问单元格之前呈现整个表格。
我调整了我的测试稍微不那么精确,但对我来说仍然足够好(考虑到否则会花费大量时间)。相反,我使用matching在预期标签值上with 谓词, withfirstMatch来查找与我想要的条件匹配的第一个单元格。这样,一旦找到它们,遍历就会停止(并且由于它们位于表的顶部,因此速度很快)。
这是之前和之后的代码。
之前(缓慢,但更精确):
private func checkRhymes(query: String, expectedFirstRhyme: String, expectedSecondRhyme: String) {
let table = app.tables.element
let cell0 = table.cells.element(boundBy: 0)
let cell1 = table.cells.element(boundBy: 1)
let actualRhyme0 = cell0.staticTexts.matching(identifier: "RhymerCellWordLabel").firstMatch.label
let actualRhyme1 = cell1.staticTexts.matching(identifier: "RhymerCellWordLabel").firstMatch.label
XCTAssertEqual(expectedFirstRhyme, actualRhyme0, "Expected first rhyme for \(query) to be \(expectedFirstRhyme) but found \(actualRhyme0)")
XCTAssertEqual(expectedSecondRhyme, actualRhyme1, "Expected first rhyme for \(query) to be \(expectedSecondRhyme) but found \(actualRhyme1)")
}
Run Code Online (Sandbox Code Playgroud)
更快,但不太精确(但足够好):
private func checkRhymes(query: String, expectedFirstRhyme: String, expectedSecondRhyme: String) {
let table = app.tables.firstMatch
let label0 = table.cells.staticTexts.matching(NSPredicate(format: "label = %@", expectedFirstRhyme)).firstMatch
let label1 = table.cells.staticTexts.matching(NSPredicate(format: "label = %@", expectedSecondRhyme)).firstMatch
// We query for the first cells that we find with the expected rhymes,
// instead of directly accessing the 1st and 2nd cells in the table,
// for performance issues.
// So we can't add assertions for the "first" and "second" rhymes.
// But we can at least add assertions that both rhymes are visible,
// and the first one is above the second one.
XCTAssertTrue(label0.frame.minY < label1.frame.minY)
XCTAssertTrue(label0.isHittable)
XCTAssertTrue(label1.isHittable)
}
Run Code Online (Sandbox Code Playgroud)
参考:https : //developer.apple.com/documentation/xctest/xcuielementquery/1500515-element
当您期望查询的单个匹配元素,但希望在访问结果之前检查多个不明确的匹配时,使用 element 属性来访问查询的结果。element 属性在返回之前遍历应用程序的可访问性树以检查多个匹配元素,如果没有单个匹配元素,则当前测试失败。
如果您明确知道将有一个匹配元素,请改用 XCUIElementTypeQueryProvider firstMatch 属性。firstMatch 在找到匹配元素后立即停止遍历应用的可访问性层次结构,从而加快元素查询解析。
小智 1
我遇到了同样的问题,我同意等待整个表加载是令人沮丧的,但这就是我必须使用以下解决方法所做的事情。
这可能不是您正在寻找的内容,但它可能对其他人有帮助:
基本上,我连续计算表中的单元格两次,如果它们不相等,则意味着表仍在加载。将其放入循环中并执行此操作,直到两个计数返回相同的数字,这意味着表已完成加载。然后我停止 30 秒,这样如果花费的时间超过 30 秒,测试就会失败(对于我来说这时间足够了)。如果你的桌子需要的时间比这个长,你可以将数字增加到 180,持续 3 分钟等等......
let startTime = NSDate()
var duration : TimeInterval
var cellCount1 : UInt = app.tables.cells.count
var cellCount2 : UInt = app.tables.cells.count
while (cellCount1 != cellCount2) {
cellCount1 = app.tables.cells.count
cellCount2 = app.tables.cells.count
duration = NSDate().timeIntervalSince(startTime as Date)
if (duration > 30) {
XCTFail("Took too long waiting for cells to load")
}
}
//Now I know the table is finished loading and I can tap on a cell
app.tables.cells.element(boundBy: 1).tap()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2033 次 |
| 最近记录: |