Как расширения XCTestCase, вызываемые из вспомогательного метода, могут узнать, какие свойства были установлены в основном тестовом примере?

Фон

Следующие тесты вызывают метод, который является расширением XCTestCase. Цель:

  • waitForElementExists метод возвращает, потому что элемент существует или
  • waitForElementExists метод не прошел тестовый метод / метод setUp, вызвавший его, потому что элемент не существовал в течение указанного времени

Расширение пользовательского интерфейса 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 ответ

Так как ваш вспомогательный класс подклассов XCTestCase, он имеет свой собственный continueAfterFailure свойство, которое является истинным по умолчанию.

Если вам нужен вспомогательный класс, он не должен наследоваться от 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"])
  }

}
Другие вопросы по тегам