Как вызвать setup один раз для всех тестов и разборки после того, как все закончено
У меня есть куча тестов, написанных с использованием pytest. Есть все в каталоге dir
. Например:
dir/test_base.py
dir/test_something.py
dir/test_something2.py
...
Упрощенная версия кода в них выглядит следующим образом:
test_base.py
import pytest
class TestBase:
def setup_module(module):
assert False
def teardown_module(module):
assert False
test_something.py
import pytest
from test_base import TestBase
class TestSomething(TestBase):
def test_dummy():
pass
test_something2.py
import pytest
from test_base import TestBase
class TestSomethingElse(TestBase):
def test_dummy2():
pass
Все мои файлы test_something*.py
расширяют базовый класс в test_base.py
. Теперь я написал методы setup_module(module)
и teardown_module(module)
в test_base.py
. Я ожидал, что setup_module будет вызван один раз для всех тестов, и teardown_module()
будет вызван в конце, когда все тесты будут завершены.
Но функции, кажется, не вызывают? Нужны ли декораторы для этого?
Ответы
Ответ 1
Поместите setup_module
и teardown_module
вне класса на уровне модуля. Затем добавьте свой класс в свои тесты.
def setup_module(module):
"""..."""
def teardown_module(module):
"""..."""
class TestSomething:
def test_dummy(self):
"""do some tests"""
Для получения дополнительной информации см. в этой статье.
Ответ 2
Требование OP состояло в том, чтобы каждая настройка и демонтаж выполнялись только один раз, а не один раз на модуль. Это можно сделать с помощью комбинации файла conftest.py
, @pytest.fixture(scope="session")
и передачи имени прибора в каждую тестовую функцию.
Они описаны в документации по приборам Pytest
Вот пример:
conftest.py
import pytest
@pytest.fixture(scope="session")
def my_setup(request):
print '\nDoing setup'
def fin():
print ("\nDoing teardown")
request.addfinalizer(fin)
test_something.py
def test_dummy(my_setup):
print '\ntest_dummy'
test_something2.py
def test_dummy2(my_setup):
print '\ntest_dummy2'
def test_dummy3(my_setup):
print '\ntest_dummy3'
Вывод при запуске py.test -s:
collected 3 items
test_something.py
Doing setup
test_dummy
.
test_something2.py
test_dummy2
.
test_dummy3
.
Doing teardown
Имя conftest.py
имеет значение: вы не можете дать этому файлу другое имя и ожидать, что Pytest найдет его в качестве источника данных.
Установка scope="session"
важна. В противном случае настройка и демонтаж будут повторяться для каждого тестового модуля.
Если вы предпочитаете не передавать имя прибора my_setup в качестве аргумента каждой тестовой функции, вы можете поместить тестовые функции в класс и применить декоратор pytest.mark.usefixtures
к классу.
Ответ 3
setup_module/teardown_module вызывают для модуля, где определены возможные (производные) тесты. Это также позволяет настроить настройку. Если у вас есть только один setup_module, вы можете поместить его в test_base.py и импортировать его из других мест. НТН.
Ответ 4
Прежде всего, это хорошая практика, чтобы поместить все тесты в модуль под названием "тесты":
<product>
...
tests/
__init__.py
test_something.py
Во-вторых, я думаю, вы должны использовать методы setup_class/teardown_class в базовом классе:
import unittest
class MyBase(unittest.TestCase):
@classmethod
def setup_class(cls):
...
@classmethod
def teardown_class(cls):
...
Дополнительная информация: http://pytest.org/latest/xunit_setup.html