2016-08-30 60 views
2

我有我的iOS用戶界面下面的測試輔助功能檢查:有沒有辦法在UITest中使用valueForKey和NSPredicate?

func waitForElementToHaveKeyboardFocus(element: XCUIElement) { 
    self.expectationForPredicate(NSPredicate(format:"valueForKey(\"hasKeyboardFocus\") == true"), evaluatedWithObject:element, handler: nil) 
    self.waitForExpectationsWithTimeout(5, handler: nil) 
} 

在我的測試,我有:

let usernameTextField = app.textFields["Username"] 
let passwordTextField = app.secureTextFields["Password"] 
waitForElementToHaveKeyboardFocus(usernameTextField) 

測試失敗,出現以下錯誤:

error: -[ExampleAppUITests.ExampleAppUITests testExampleApp] : failed: caught "NSUnknownKeyException", "[<_NSPredicateUtilities 0x10e554ee8> valueForUndefinedKey:]: this class is not key value coding-compliant for the key hasKeyboardFocus." 

如果我在失敗時在測試中放置了斷點,並在聚焦和未聚焦的字段上手動調用valueForKey("hasKeyboardFocus"),我似乎得到了正確的行爲:

(lldb) po usernameTextField.valueForKey("hasKeyboardFocus") 
    t = 51.99s  Find the "Username" TextField 
    t = 51.99s   Use cached accessibility hierarchy for ExampleApp 
    t = 52.00s   Find: Descendants matching type TextField 
    t = 52.01s   Find: Elements matching predicate '"Username" IN identifiers' 
▿ Optional<AnyObject> 
    - Some : 1 

(lldb) po passwordTextField.valueForKey("hasKeyboardFocus") 
    t = 569.99s  Find the "Password" SecureTextField 
    t = 569.99s   Use cached accessibility hierarchy for ExampleApp 
    t = 570.01s   Find: Descendants matching type SecureTextField 
    t = 570.01s   Find: Elements matching predicate '"Password" IN identifiers' 
▿ Optional<AnyObject> 
    - Some : 0 

是否有可能使valueForKey上的UI測試與NSPredicate一個XCUIElement工作?有沒有另一種優雅的方式來做到這一點?

回答

2

它看起來像你的謂詞稍微偏離。嘗試將其更改爲以下:

NSPredicate(format: "hasKeyboardFocus == true"), evaluatedWithObject:element, handler: nil) 

你並不需要在創建謂詞當valueForKey部分通過。

+0

太棒了,那有效!奇怪的是,我在調試器中試過,它不起作用:錯誤::2:1:錯誤:類型'XCUIElement'的值沒有成員'hasKeyboardFocus''。而具有該語法的其他謂詞,例如:'NSPredicate(format:「hittable == true」)'DO可以在調試器中工作。但'hasKeyboardFocus'只能在調試器中使用'valueForKey'。奇怪的。 – Mitochondrion

2

你可以做這樣的事情,在這裏你通過語句valueForKey("")作爲一個封閉的方法:

func waitForElementToHaveKeyboardFocus(statement statement:() -> Bool, timeoutSeconds: Int) 
{ 
    var second = 0 
    while statement() != true { 
     if second >= timeoutSeconds { 
      XCTFail("statement reached timeout of \(timeoutSeconds) seconds") 
     } 

     sleep(1) 
     second = second + 1 
    } 
} 

,然後像測試使用:

waitForElementToHaveKeyboardFocus(statement: { usernameTextField.valueForKey("hasKeyboardFocus") as? Bool == true }, timeoutSeconds: 10) 

您可以重命名這個方法是更通用的,它會驗證你傳遞給它的任何閉包。希望這可以幫助!