如何从辅助方法调用的XCTestCase扩展知道在主测试用例中设置了哪些属性?

时间:2016-10-21 19:23:23

标签: swift xctest xcode-ui-testing xctestcase xctestexpectation

背景

以下测试调用的方法是XCTestCase的扩展。目标:

  • waitForElementExists方法返回,因为元素存在或
  • waitForElementExists方法未通过调用它的测试用例/ setUp方法,因为该元素在指定时间内不存在

UI Automation XCTestCase扩展等待方法:

extension XCTestCase
{
    /**
    Wait for the view to load
    Note: Must be a part of XCTestCase in order to utilize expectationForPredicate and waitForExpectationsWithTimeout

    - Parameter
    - element:    The XCUIElement representing the view
    - timeout: The NSTimeInterval for how long you want to wait for the view to be loaded
    - file: The file where this method was called
    - line: The line where this method was called
    */
    func waitForElementExists(element: XCUIElement, timeout: NSTimeInterval = 60,
                       file: String = #file, line: UInt = #line)
    {
        let exists = NSPredicate(format: "exists == true")

        expectationForPredicate(exists, evaluatedWithObject: element, handler: nil)
        waitForExpectationsWithTimeout(timeout) { (error) -> Void in
            if (error != nil)
            {
                let message = "Failed to find \(element) after \(timeout) seconds."
                self.recordFailureWithDescription(message,
                                                  inFile: file, atLine: line, expected: true)
            }
        }
    }
}

waitForExpectationsWithTimeout正确工作的示例

测试用例

override func setUp()
{
    super.setUp()

    // Stop immediately when a failure occurs.
    continueAfterFailure = false

    XCUIApplication().launch()

    waitForElementExists(XCUIApplication().buttons["Foo"])
}

func testSample()
{
    print("Success")
}

这个有效!永远不会调用testSample

  

但是如果我们将waitForElementExists调用移动到辅助方法呢?

waitForExpectationsWithTimeout成功返回的示例,但不应该

这里,测试用例继续,好像断言从未发生过一样。如果我在waitForElementExists中放置一个断点,我会看到continueAfterFailure设置为true,所以很明显它没有与主要测试用例连接到相同的代码。

测试用例

lazy var SomeHelper = SomeHelperClass()

override func setUp()
{
    super.setUp()

    // Stop immediately when a failure occurs.
    continueAfterFailure = false

    XCUIApplication().launch()

    SomeHelper.waitForReady()

}

func testSample()
{
    print("Success")
}

帮助文件

class SomeHelperClass: XCTestCase
{
    /**
    Wait for the button to be loaded
    */
    func waitForReady()
    {
        waitForElementExists(XCUIApplication().buttons["Foo"])
    }
}

1 个答案:

答案 0 :(得分:0)

由于您的助手类是XCTestCase的子类,因此它具有自己的continueAfterFailure属性,默认情况下为true。

如果你想要一个帮助器类,它不应该从XCTestCase下降,因为XCTestCase子类应该实现测试方法。如果需要从辅助类中的XCTestCase扩展访问功能,请在创建辅助类时通过组合传入测试用例对象。

class SomeHelper {

  let testCase: XCTestCase

  init(for testCase: XCTestCase) {
    self.testCase = testCase
  }

  func await(_ element: XCUIElement) {
    testCase.waitForElementExists(element)
  }

}

class MyTests: XCTestCase {

  let app = XCUIApplication()
  var helper: SomeHelper!

  func setUp() {
    continueAfterFailure = false
    helper = SomeHelper(for: self)
    helper.await(app.buttons["foo"])
  }

}