Выполнить код до и после каждого теста в py.test?
Я хочу запустить дополнительные проверки установки и проверки до и после каждого теста в моем наборе тестов. Я посмотрел на светильники, но не уверен, правильны ли они. Мне нужно запустить код установки перед каждым тестом, и мне нужно запустить проверки слежения после каждого теста.
Мой прецедент проверяет код, который не очищается правильно: он оставляет временные файлы. В моей настройке я проверю файлы, а в режиме срыва я также проверю файлы. Если есть дополнительные файлы, я хочу, чтобы тест завершился с ошибкой.
Ответы
Ответ 1
Инструменты py.test являются технически адекватным методом для достижения вашей цели.
Вам просто нужно определить такой инструмент:
@pytest.yield_fixture(autouse=True)
def run_around_tests():
# Code that will run before your test, for example:
files_before = # ... do something to check the existing files
# A test function will be run at this point
yield
# Code that will run after your test, for example:
files_after = # ... do something to check the existing files
assert files_before == files_after
Объявив ваше устройство с помощью autouse=True
, он будет автоматически вызываться для каждой тестовой функции, определенной в том же модуле.
Тем не менее, есть одно предостережение. Утверждая при установке/демонтаже является спорной практикой. У меня создалось впечатление, что основным авторам py.test это не нравится (мне тоже это не нравится, так что это может покрасить мое собственное восприятие), поэтому вы можете столкнуться с некоторыми проблемами или грубыми краями по мере продвижения вперед.
Ответ 2
Светильники - именно то, что вы хотите.
Это то, для чего они предназначены.
Используете ли вы фитинги стиля pytest или setup и разрывы (уровень модуля, класса или метода). xwit-стиль, зависит от обстоятельства и личный вкус.
Из того, что вы описываете, кажется, что вы можете использовать pytest autouse fixtures.
Или уровень функции xUnit style setup_function()/teardown_function().
Pytest полностью охватил вас. Настолько, что, возможно, это пожарный шланг информации.
Ответ 3
Вы можете использовать настройку/разборку уровня модуля Fiestures of Pytest.
Здесь ссылка
http://pytest.org/latest/xunit_setup.html
Он работает следующим образом:
def setup_module(module):
""" setup any state specific to the execution of the given module."""
def teardown_module(module):
""" teardown any state that was previously setup with a setup_module
method."""
Test_Class():
def test_01():
#test 1 Code
Он будет вызывать setup_module
перед этим тестом и teardown_module
после завершения теста.
Вы можете включить это приспособление в каждом тесте script, чтобы запустить его для каждого теста.
ЕСЛИ вы хотите использовать что-то общее для всех тестов в каталоге. Вы можете использовать инфраструктуру уровня пакета/каталога носа.
http://pythontesting.net/framework/nose/nose-fixture-reference/#package
В __init__.py
файле пакета вы можете включить следующие
def setup_package():
'''Set up your environment for test package'''
def teardown_package():
'''revert the state '''
Ответ 4
Вы можете использовать декораторы, но программно, поэтому вам не нужно помещать декоратор в каждый метод.
Я предполагаю несколько вещей в следующем коде:
Все тестовые методы называются: "testXXX()"
Декоратор добавлен в тот же модуль, где реализованы методы тестирования.
def test1():
print ("Testing hello world")
def test2():
print ("Testing hello world 2")
#This is the decorator
class TestChecker(object):
def __init__(self, testfn, *args, **kwargs):
self.testfn = testfn
def pretest(self):
print ('precheck %s' % str(self.testfn))
def posttest(self):
print ('postcheck %s' % str(self.testfn))
def __call__(self):
self.pretest()
self.testfn()
self.posttest()
for fn in dir() :
if fn.startswith('test'):
locals()[fn] = TestChecker(locals()[fn])
Теперь, если вы вызываете методы тестирования...
test1()
test2()
Результат должен выглядеть примерно так:
precheck <function test1 at 0x10078cc20>
Testing hello world
postcheck <function test1 at 0x10078cc20>
precheck <function test2 at 0x10078ccb0>
Testing hello world 2
postcheck <function test2 at 0x10078ccb0>
Если у вас есть методы тестирования как методы класса, этот подход также действителен. Например:
class TestClass(object):
@classmethod
def my_test(cls):
print ("Testing from class method")
for fn in dir(TestClass) :
if not fn.startswith('__'):
setattr(TestClass, fn, TestChecker(getattr(TestClass, fn)))
Вызов TestClass.my_test()
будет напечатан:
precheck <bound method type.my_test of <class '__main__.TestClass'>>
Testing from class method
postcheck <bound method type.my_test of <class '__main__.TestClass'>>
Ответ 5
Взгляните на декораторы python https://wiki.python.org/moin/PythonDecorators