Leg*_*ack 2 python pytest python-decorators
我的 pytest 测试装饰器在调用函数后立即退出装饰器。如果我使用 python 而不是 pytest 运行该文件,效果会很好。
这是代码:
def dec(func):
def wrapper(*args, **kwargs):
print('do some stuff')
result = func(*args, **kwargs)
print('ran function')
return False if result else return True
return wrapper
@dec
def test_something_is_not_true():
return False # assert False
@dec
def test_something_is_true():
return True # assert True
print(test_something_is_not_true())
print(test_something_is_true())
Run Code Online (Sandbox Code Playgroud)
当我用 python 运行该文件时,结果如下:
C:\tests> python test.py
do some stuff
ran function
True
do some stuff
ran function
False
Run Code Online (Sandbox Code Playgroud)
效果很好!
但是当我用 pytest 运行它时,它停在该result = func(*args, **kwargs)
行并且从不执行该print('ran function')
行:
C:\tests>pytest test.py
============================= test session starts =============================
platform win32 -- Python 3.6.4, pytest-3.3.2, py-1.5.2, pluggy-0.6.0
rootdir: C:\, inifile:
plugins: metadata-1.7.0, jira-0.3.6, html-1.19.0
collected 2 items
test.py F. [100%]
================================== FAILURES ===================================
_________________________ test_something_is_not_true __________________________
args = (), kwargs = {}
def wrapper(*args, **kwargs):
print('do some stuff')
> result = func(*args, **kwargs)
test.py:20:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
@dec
def test_something_is_not_true():
> assert False
E assert False
test.py:31: AssertionError
---------------------------- Captured stdout call -----------------------------
do some stuff
===================== 1 failed, 1 passed in 0.11 seconds ======================
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,装饰器函数实际上并没有做任何事情...但是如果我能让它工作,那么我可以查看测试是否在该函数中通过,如果是,则根据通过的结果执行一些额外的逻辑或测试失败。也许使用装饰器来完成捕获测试的输出并不是最好的方法?
你会怎么办?
如果您需要在测试之前和之后执行代码,可以在固定装置中完成。例子:
import pytest
@pytest.fixture
def wrapper(request):
print('\nhere I am before the test')
print('test function name is', request.node.name)
print('test file is located under', request.node.fspath)
yield
print('\nand here I am after the test')
@pytest.mark.usefixtures('wrapper')
def test_spam_good():
assert True
@pytest.mark.usefixtures('wrapper')
def test_spam_bad():
assert False
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这比编写自定义装饰器要强大得多。由于pytest
非常擅长围绕测试进行元编程,因此您可能需要的很多东西已经存在,您只需要知道如何访问它即可。pytest
文档包含许多适合初学者的示例和食谱。
如果您需要夹具中的测试结果,文档中提供了相关方法:在夹具中提供测试结果信息。在项目根目录中创建一个文件conftest.py
,内容如下:
import pytest
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
# execute all other hooks to obtain the report object
outcome = yield
rep = outcome.get_result()
# set a report attribute for each phase of a call, which can
# be "setup", "call", "teardown"
setattr(item, "rep_" + rep.when, rep)
Run Code Online (Sandbox Code Playgroud)
request
现在您可以通过自定义装置中的装置访问测试结果:
@pytest.fixture
def something(request):
yield
# request.node is an "item" because we use the default
# "function" scope
if request.node.rep_setup.failed:
print("setting up a test failed!", request.node.nodeid)
elif request.node.rep_setup.passed:
if request.node.rep_call.failed:
print("executing test failed", request.node.nodeid)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1990 次 |
最近记录: |