Модульный тест Python: отменить все тесты, если определенный тест не пройден

Я использую unittest для тестирования своего приложения Flask и nose для фактического запуска тестов.

Мой первый набор тестов — убедиться, что среда тестирования чиста, и предотвратить запуск тестов в настроенной базе данных приложения Flask. Я уверен, что правильно настроил тестовую среду, но мне хотелось бы получить некоторую уверенность в этом, не запуская все тесты.

import unittest

class MyTestCase(unittest.TestCase):
    def setUp(self):
        # set some stuff up
        pass

    def tearDown(self):
        # do the teardown
        pass

class TestEnvironmentTest(MyTestCase):
    def test_environment_is_clean(self):
        # A failing test
        assert 0 == 1

class SomeOtherTest(MyTestCase):
    def test_foo(self):
        # A passing test
        assert 1 == 1

Я бы хотел, чтобы TestEnvironmentTest вызывал unittest или nose залог в случае неудачи и предотвращал запуск SomeOtherTest и любых дальнейших тестов. Есть ли какой-то встроенный метод сделать это либо в unittest (предпочтительно), либо в nose, который позволяет это сделать?


person Colin Dunklau    schedule 15.10.2012    source источник
comment
Знаете ли вы, решает ли нос проблему с заказом тестов? Потому что в python вам не гарантируется тестовый порядок (хотя я думаю, что он обычно разрешается в алфавитном порядке).   -  person Colleen    schedule 15.10.2012
comment
Что ж, тогда это тоже будет другая проблема... но я полагаю, что это решаемо, поместив тест в вашу настройку.   -  person Colleen    schedule 15.10.2012
comment
stackoverflow.com/ вопросы/6813837/ ?   -  person Colleen    schedule 15.10.2012
comment
@Colleen хм, не совсем ... Я хочу запустить все тесты, даже если в них есть ошибки, но я хочу, чтобы мои тесты среды прошли до запуска любого другого теста. Однако ваше первое предложение работает: я добавил тест среды в setUp. Кажется, я был неправ... что-то сохраняется между тестами, плохо, плохо, плохо!   -  person Colin Dunklau    schedule 15.10.2012
comment
О, извините, неправильно понял ваш вопрос. Думал, что вы хотите немедленно потерпеть неудачу, если вы не прошли TestEnvironmentTest.   -  person Colleen    schedule 15.10.2012
comment
@Colleen Я обновил свой ответ. Отправьте обновленный код в ответ, и я приму его через несколько дней, если ни у кого нет лучшего решения.   -  person Colin Dunklau    schedule 15.10.2012
comment
Используйте --with-id носа, чтобы гарантировать порядок проверки.   -  person dbn    schedule 16.01.2013
comment
Можно решить проблему порядка выполнения тестовых случаев, назвав тесты таким образом, чтобы они выстраивались в порядке возрастания. Например: Имя первого теста: test_1000_xxxx, Имя второго теста: test_1100_xxxx и т. д. В документации по модульному тесту упоминается: Note that the order in which the various test cases will be run is determined by sorting the test function names with respect to the built-in ordering for strings. URL-адрес: [ссылка]docs.python.org/2/library/unittest.html   -  person Deep    schedule 19.12.2014


Ответы (4)


Чтобы заставить один тест выполняться первым и остановить выполнение других тестов только в случае ошибки с этим тестом, вам нужно поместить вызов теста в setUp() (поскольку python не гарантирует тестовый порядок), а затем выполнить сбой или пропустить остальные в случае сбоя.

Мне нравится skipTest(), потому что на самом деле он не запускает другие тесты, тогда как создание исключения, похоже, все еще пытается запустить тесты.

def setUp(self):
    # set some stuff up
    self.environment_is_clean()

def environment_is_clean(self):
    try:
        # A failing test
        assert 0 == 1
    except AssertionError:
        self.skipTest("Test environment is not clean!")
person Colleen    schedule 15.10.2012

Для вашего варианта использования есть функция setUpModule():

Если в setUpModule возникнет исключение, то ни один из тестов в модуле не будет запущен, а tearDownModule не будет запущен. Если исключение является исключением SkipTest, модуль будет сообщен как пропущенный, а не как ошибка.

Проверьте свою среду внутри этой функции.

person Piotr Dobrogost    schedule 15.10.2012
comment
Или, в некоторых случаях, setUpClass() также будет работать If an exception is raised during a setUpClass then the tests in the class are not run and the tearDownClass is not run. docs.python. орг/2/библиотека/ - person Dennis Golomazov; 23.07.2013
comment
Если setUpModule() определяется как функция вне класса TestCase, как бы вы сделали утверждение? - person Stevoisiak; 28.02.2018

Вы можете пропустить целые тестовые случаи, вызвав skipTest() в setUp(). Это новая функция в Python 2.7. Вместо того, чтобы провалить тесты, он просто пропустит их все.

person kichik    schedule 15.10.2012
comment
Это хорошая функция, но конечный результат в порядке, когда он должен ныть об ошибках. - person Colin Dunklau; 15.10.2012
comment
Вот для чего у вас TestEnvironmentTest сбой. Если вы просто хотите, чтобы они потерпели неудачу, что не так с кодом, который у вас уже есть? - person kichik; 16.10.2012

Я не совсем уверен, соответствует ли это вашим потребностям, но вы можете сделать выполнение второго набора юнит-тестов зависимым от результата первого набора юнит-тестов:

envsuite = unittest.TestSuite()
moretests = unittest.TestSuite()
# fill suites with test cases ...
envresult = unittest.TextTestRunner().run(envsuite)
if envresult.wasSuccessful():
    unittest.TextTestRunner().run(moretests)
person silvado    schedule 15.10.2012