我正在尝试构建一个函数findElementWithLabel(),它可以递归遍历任何给定元素的整个XCUIElement树,并返回具有指定标签或id的子元素。与内置的childrenMatchingType()函数不同,它将搜索多个级别的子级(不仅仅是直接子级)。我已经将此函数构建为XCUIElement的扩展,下面是示例代码:
public extension XCUIElement {
public func findElementWithLabel(label: String) -> XCUIElement? {
return findElementWithName(self, name:label)
}
private func findElementWithName(elementToSearch:XCUIElement?, name: String) -> XCUIElement? {
if let currentElement = elementToSearch {
if currentElement.label == name {
return currentElement
}
} else {
return nil
}
let children = elementToSearch?.childrenMatchingType(.Any)
var loopIndex:UInt = 0
while (loopIndex < children?.count) {
let foundElement = findElementWithName(children?.elementBoundByIndex(loopIndex), name:name)
if let unwrappedFoundElement = foundElement {
return unwrappedFoundElement
}
loopIndex += 1
}
return nil
}
}
该函数返回正确的结果,但不幸的是,性能很糟糕需要大约10-15秒才能返回。任何有关xcode ui自动化的专家都可以帮助我推断出可能导致这种情况的原因吗?最初我以为是重复调用&#34; XCUIElement.childrenMatchingType(.Any)&#34;但我认为我可以排除这种情况。该函数平均需要0.007秒来计算,我调用它大约30次,这意味着它不能成为罪魁祸首。我唯一的其他理论是:
1)某些地方正在应用某些延迟,这极大地影响了运行时间。我在使用javascript api的工具中编写了这个函数,并在使用popTimeout(0)进行树遍历之后调用了UIATarget.localTarget()。pushTimeout(0)。这实际上导致我的递归函数调用没有延迟并等待任何元素......如果这是罪魁祸首,我可以通过某种方式使用新API实现这个全局pushTimeout()和popTimeout()功能吗?
2)使用新的ui-automation进行大量的xcode控制台日志记录必须影响运行时。我知道NSLog是同步和慢的,所以这可能是罪魁祸首吗?如果是这样,我们如何关闭这些日志?如果内置的xcode xctest调试日志如此极大地影响运行时,那么如何进行均衡扩展呢?作为开发人员,我们需要这些日志,但我们也不能像这样影响运行时。
答案 0 :(得分:1)
我找到了问题的答案。看来我的递归调用是在Element级别工作,我应该在ElementQuery级别工作。编写查询的速度要快得多,因为元素只解析一次,然后解析查询链。
似乎在新的API中解析元素是非常昂贵的,因为它与应用程序通信以每次解析和验证元素。我怀疑Javascript API也是这样做的,但由于它们没有暴露任何ElementQuery结构,因此它们允许你将超时推送到0,告诉框架不要延迟并等待解决每个元素。无论如何,我的问题的答案只是在根元素上使用descendantsOfElement()并编写标签/ id查询。