2016-08-19 3 views
1

주어진 요소에 대해 전체 XCUIElement 트리를 반복적으로 탐색하고 지정된 레이블 또는 ID를 가진 자식 요소를 반환 할 수있는 findElementWithLabel() 함수를 작성하려고합니다. 빌트인 childrenMatchingType() 함수와는 달리, 아이들은 직접 자식뿐만 아니라 한 레벨 이상의 깊이를 검색합니다. 불행하게도 성능이 끔찍한 반환 거의 10-15초를 취하고있다좋은 성능으로 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 
     } 

    } 

기능은 적절한 결과를 반환하지만 : 나는 XCUIElement에 확장으로이 기능을 구축, 여기에 샘플 코드입니다. xcode 자동화에 대한 전문가라면이 문제의 원인을 추론 할 수 있습니까? 원래 나는 "XCUIElement.childrenMatchingType (.Any)"에 대한 반복 된 호출이라고 생각했지만, 이것을 배제 할 수 있다고 생각합니다. 이 기능은 평균 0.007 초의 계산 시간을 필요로하며, 대략 30 회 호출합니다. 이는 그 범인이 아닐 수 있음을 의미합니다. 내가 가지고있는 유일한 다른 이론은 다음과 같습니다.

1) 지연이 일부 적용되어 런타임에 큰 영향을줍니다. 나는이 함수를 자바 스크립트 api와 UIATarget.localTarget()을 호출하여 악기에 작성했습니다. popTimeout (0)을 사용한 트리 순회가 끝나기 전에 pushTimeout (0)이 트릭을 수행했습니다. 이것은 기본적으로 내 재귀 함수 호출 지연 및 모든 요소를 ​​기다리는 발생했습니다 ... 범인이 새로운 API를이 전역 pushTimeout() 및 popTimeout() 기능을 얻을 수있는 몇 가지 방법이 있나요?

2) 새로운 ui-automation을 사용하는 방대한 양의 xcode 콘솔 로깅은 런타임에 영향을 주어야합니다. 나는 NSLog가 동기적이고 느리다는 것을 알고 있습니다. 그래서 이것이 범인이 될 수 있습니까? 그렇다면 어떻게 이러한 로그를 전환 할 수 있습니까? 내장 된 xcode xctest 디버그 로그가 런타임에 너무 큰 영향을 미칠 경우이를 어떻게 확장 할 수 있습니까? devs는 이러한 로그가 필요하지만 이와 같이 런타임에 영향을 미칠 수는 없습니다.

+0

달성하려는 목표는 무엇입니까? XCUIElementQuery를 사용하지 않는 이유가 있다고 가정합니다. – Oletha

+0

XCElementQuery를 사용하여 이동하는 방법을 생각했습니다 ... – AyBayBay

답변

0

내 질문에 대한 답변을 발견했습니다. 재귀 호출이 Element 수준에서 작동하고 ElementQuery 수준에서 작업해야합니다. 요소를 한 번만 확인하고 쿼리 체인을 해결하기 때문에 쿼리 작성 속도가 훨씬 빨라집니다.

새로운 API에서는 요소를 해결할 때마다 요소를 확인하고 확인하기 위해 앱과 통신하므로 비용이 많이 드는 것으로 보입니다. Javascript API도 이와 같았지만, ElementQuery 구조체를 공개하지 않았기 때문에 프레임 워크가 지연되지 않고 각 요소를 해결할 때까지 기다리는 동안 타임 아웃을 0으로 설정할 수있었습니다. 어쨌든, 내 질문에 대한 대답은 루트 요소에 descendantsOfElement()를 사용하여 레이블/id 쿼리를 작성하는 것이 었습니다.

관련 문제