Как остановить все тесты изнутри теста или настройки, используя Unittest?
-
25-09-2019 - |
Вопрос
Я расширяю Python 2.7 unittest
Рамки для выполнения некоторого тестирования функций. Одна из вещей, которые я хотел бы сделать, это остановить все тесты, бегающие внутри теста, а внутри setUpClass()
метод. Иногда, если тест терпит неудачу, программа настолько сломана, это больше не имеет никакого использования для продолжения тестирования, поэтому я хочу остановить пробег тестов.
Я заметил, что TestResult имеет shouldStop
атрибут и stop()
Метод, но я не уверен, как получить доступ к этому внутри теста.
У кого-нибудь есть идеи? Есть ли способ лучше?
Решение 2
Вот еще один ответ, с которым я пришел через некоторое время:
Во-первых, я добавил новый исключение:
class StopTests(Exception):
"""
Raise this exception in a test to stop the test run.
"""
pass
Тогда я добавил новый assert
К моим классам теста на ребенка:
def assertStopTestsIfFalse(self, statement, reason=''):
try:
assert statement
except AssertionError:
result.addFailure(self, sys.exc_info())
и последнее я переполнул run
функция, чтобы включить это прямо под testMethod()
вызов:
except StopTests:
result.addFailure(self, sys.exc_info())
result.stop()
Мне это нравится, так как любой тест теперь имеет возможность остановить все тесты, и нет CPY-специфического кода.
Другие советы
Если вы заинтересованы, вот простой пример того, как вы могли бы принять решение о выходе в тестовой набор. пишет:
# content of test_module.py
import pytest
counter = 0
def setup_function(func):
global counter
counter += 1
if counter >=3:
pytest.exit("decided to stop the test run")
def test_one():
pass
def test_two():
pass
def test_three():
pass
И если вы запустите это, вы получаете:
$ pytest test_module.py
============== test session starts =================
platform linux2 -- Python 2.6.5 -- pytest-1.4.0a1
test path 1: test_module.py
test_module.py ..
!!!! Exit: decided to stop the test run !!!!!!!!!!!!
============= 2 passed in 0.08 seconds =============
Вы также можете положить py.test.exit()
Вызов внутри теста или в плагин, специфичный проект.
Примечание: py.test
родом поддерживает py.test --maxfail=NUM
реализовать остановку после сбоев Num.
Sidenote2: py.test
имеет только ограниченную поддержку для беговых испытаний в традиционном unittest.TestCase
стиль.
В настоящее время вы можете остановить только тесты на уровне набора. Как только вы находитесь в TestCase
, то stop()
метод для TestResult
не используется при итерации через тесты.
Несколько связан с вашим вопросом, если вы используете Python 2.7, вы можете использовать -f/--failfast
Флаг при вызове вашего теста с python -m unittest
. Отказ Это остановит тест по первой неудаче.
Видеть 25.3.2.1. Опции командной строки Failfaff, Catch и Buffer
Вы также можете рассмотреть вопрос Нос Чтобы запустить свои тесты и использовать -x, --stop
флаг остановить тест рано.
В тестовой петле unittest.TestSuite
, Eсть break
Состояние в начале:
class TestSuite(BaseTestSuite):
def run(self, result, debug=False):
topLevel = False
if getattr(result, '_testRunEntered', False) is False:
result._testRunEntered = topLevel = True
for test in self:
if result.shouldStop:
break
Поэтому я использую пользовательский тестовый набор, как это:
class CustomTestSuite(unittest.TestSuite):
""" This variant registers the test result object with all ScriptedTests,
so that a failed Loign test can abort the test suite by setting result.shouldStop
to True
"""
def run(self, result, debug=False):
for test in self._tests:
test.result = result
return super(CustomTestSuite, self).run(result, debug)
С пользовательским классом результата теста, как это:
class CustomTestResult(TextTestResult):
def __init__(self, stream, descriptions, verbosity):
super(CustomTestResult, self).__init__(stream, descriptions, verbosity)
self.verbosity = verbosity
self.shouldStop = False
И мои тестовые классы похожи:
class ScriptedTest(unittest.TestCase):
def __init__(self, environment, test_cfg, module, test):
super(ScriptedTest, self).__init__()
self.result = None
При определенных условиях я затем прерванию тестового набора; Например, тестовый набор начинается со входа в систему, и если это не удается, мне не нужно пробовать остальное:
try:
test_case.execute_script(test_command_list)
except AssertionError as e:
if test_case.module == 'session' and test_case.test == 'Login':
test_case.result.shouldStop = True
raise TestFatal('Login failed, aborting test.')
else:
raise sys.exc_info()
Затем я использую тестовый набор следующим образом:
suite = CustomTestSuite()
self.add_tests(suite)
result = unittest.TextTestRunner(verbosity=self.environment.verbosity, stream=UnitTestLoggerStream(self.logger),
resultclass=CustomTestResult).run(suite)
Я не уверен, что есть лучший способ сделать это, но он ведет себя правильно для моих тестов.
Я посмотрел на TestCase
Класс и решил подклассно это. Класс просто переопределяет run()
. Отказ Я скопировал метод и начиная с линии 318 в исходном классе, добавил это:
# this is CPython specific. Jython and IronPython may do this differently
if testMethod.func_code.co_argcount == 2:
testMethod(result)
else:
testMethod()
В нем есть какой-то код CPY-CEMPHON, чтобы сказать, может ли метод теста принять другой параметр, но поскольку я использую CPYthon везде, это не проблема для меня.
Хотя вы не получите обычные тестовые отчеты о прогонах тестов, очень простой способ остановить тестовый прогон из TestCase
Метод просто поднять KeyboardInterrupt
внутри метода.
Вы можете увидеть, как только KeyboardInterrupt
разрешено пузыми внутрь unittest
Тестовый бегун, глядя на код Cpython здесь внутри testPartExecutor()
.
Использовать:
if condition:
return 'pass'