Как расширения 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"])
}
}