2016-08-19 19 views
1

我想构建一个函数findElementWithLabel(),它可以递归地遍历任何给定元素的整个XCUIElement树,并返回一个具有指定标签或ID的子元素。与内置的childrenMatchingType()函数不同,它将搜索超过一个级别的子级(不仅仅是直接的子级)。我已经建立了这个功能作为XCUIElement的延伸,这里是示例代码:如何递归搜索性能良好的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 automation的专家都可以帮助我推断出可能导致这种情况的原因吗?最初我以为这是反复调用“XCUIElement.childrenMatchingType(.Any)”,但我想我可以排除这一点。这个函数平均需要0.007秒来计算,我调用它大概30次,这意味着不能是罪魁祸首。我唯一的理论是:

1)某些延迟正在应用某处,极大地影响了运行时间。我使用javascript api在仪器中编写了这个函数,并且在使用popTimeout(0)遍历树之前调用了UIATarget.localTarget()。pushTimeout(0)。这基本上导致我的递归函数调用不会延迟并等待任何元素......如果这是罪魁祸首,有什么办法可以通过新API实现此全局pushTimeout()和popTimeout()功能?

2)使用新的ui-automation进行大量xcode控制台日志记录必须影响运行时。我知道NSLog的同步和缓慢,所以这可能是罪魁祸首?如果是的话,我们如何才能关闭这些日志?如果内置的xcode xctest调试日志如此巨大地影响运行时间,那么如何进一步扩展呢?作为开发者,我们需要这些日志,但是我们也不能像这样影响运行时。

+0

你想达到什么目的?我假设你有一个不使用XCUIElementQuery的理由? – Oletha

+0

我想通过使用XCElementQuery是要走的路... – AyBayBay

回答

0

我发现了我的问题的答案。看来我的递归调用在Element级别工作,我应该在ElementQuery级别工作。编写查询的运行速度要快得多,因为该元素只解决一次,然后解析查询链。

看来在新的API中解析一个元素是非常昂贵的,因为它与应用程序进行通信以每次解析和验证元素。我怀疑JavaScript API也是这样做的,但是由于它们没有公开任何ElementQuery结构,它们允许你推迟0的超时时间,告诉框架不要延迟并等待解析每个元素。无论如何,我的问题的答案只是在根元素上使用descendantsOfElement()并写入标签/ id查询。