Ошибка XCTestCase с assert без продолжения выполнения теста, но без остановки других тестов
Я пытаюсь протестировать свое приложение, используя платформу XCTest.
Я хочу, чтобы мой единственный контрольный пример провалился, если выполняется какое-то логическое условие (используя утверждение). Я не хочу, чтобы остальная часть кода в тестовом примере работала, потому что это может привести к проблемам (например, доступ к нулевым указателям). Я также хочу, чтобы остальная часть тестового примера работала нормально, и только неудачный тест быть отмеченным как неудачный.
Я заметил, что XCTestCase имеет свойство continueAfterFailure. Однако, установив его в YES, вынудивший неудавшийся тест продолжать выполнение строк после подтверждения, а установив его в NO, остальные тесты вообще не запускались.
Есть ли решение этой проблемы? Спасибо, Йоав
5 ответов
Ответ Паскаля дал мне идею достичь этого должным образом. XCTool теперь ведет себя как OCUnit, когда утверждение не выполняется: выполнение тестового примера немедленно прекращается, вызывается tearDown и запускается следующий тестовый пример.
Просто переопределите метод invokeTest
в вашем базовом классе (тот, который наследуется от класса XCTestCase):
- (void)invokeTest
{
self.continueAfterFailure = NO;
@try
{
[super invokeTest];
}
@finally
{
self.continueAfterFailure = YES;
}
}
Это оно!
Самый простой способ - добавить:
continueAfterFailure = false
в метод setUp(). Так это будет выглядеть так:
стриж
override func setUp() {
super.setUp()
continueAfterFailure = false
}
Objective-C
- (void)setUp {
[super setUp];
[self setContinueAfterFailure:NO];
}
Одним из вариантов может быть проверка состояния в обычном режиме, затем выполнить сбой и вернуться из теста, если оно ложно.
Что-то вроде этого:
if (!condition) {
XCFail(@"o noes");
return;
}
Вы можете обернуть это в вспомогательный макрос, чтобы сохранить читабельность.
Библиотеки тестов BDD, такие как Kiwi, более изящны для такого рода вещей, так как они упрощают распределение настроек между многими тестами, что приводит к меньшему количеству утверждений на тест.
Я могу использовать continueAfterFailure
и пусть другие тесты запускаются с использованием этого шаблона:
self.continueAfterFailure = NO;
@try
{
// Perform test code here
}
@finally
{
self.continueAfterFailure = YES;
}
В проектах Swift я использую вспомогательную функцию (определенную в общем суперклассе всех моих тестов, которая сама расширяется XCTestCase
):
/// Like `XCTFail(...)` but aborts the test.
func XCTAbortTest(_ message: String,
file: StaticString = #file, line: UInt = #line
) -> Never {
self.continueAfterFailure = false
XCTFail(message, file: file, line: line)
fatalError("never reached")
}
Как следует из комментария, призыв к fatalError
на самом деле никогда не выполняется; XCTFail
прерывает тест по порядку (tearDown
называется, следующие тестовые прогоны и т. д.). Вызов только для того, чтобы заставить компилятор принять Never
как тип возврата, так как XCTFail
возвращается Void
(это возвращает, если continueAfterFailure == true
).
Обратите внимание, что self.continueAfterFailure
сбрасывается на значение по умолчанию true
для каждого метода испытаний. Вы также можете сделать это явным в setUp()
,