2016-08-19 21 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查詢。