测试用例成功后删除 py.test tmpdir 目录
Deleting py.test tmpdir directory after successful test case
我是 运行 测试,在执行过程中会创建大量大文件。为此,如果测试通过,我想删除 tmpdir 目录。但如果测试失败,tmpdir 的内容应该保持不变。
我知道如何判断测试结果:
from _pytest.runner import runtestprotocol
def pytest_runtest_protocol(item, nextitem):
reports = runtestprotocol(item, nextitem=nextitem)
for report in reports:
if report.when == 'call':
# value will be set to passed or filed
test_outcome = report.outcome
# But what next?
return True
但我不知道如何找到创建的tmpdir目录的路径
您应该 create a tmpdir fixture 创建临时目录,将其传递到您的代码中,然后删除它。
此外,fixture 必须设置为始终删除 tempdir,即使在失败时也是如此。否则,您可能会留下不干净的状态,这可能会导致其他测试失败(用户不会注意到)。
相反,我推荐
- 出现错误时使用
--pdb
进入 Python 调试器。夹具尚未清理,您可以检查文件。
- Creating a custom option 允许您禁用 tmpdir 的清理。
- 创建自定义 tmpdir 装置,将所有 tmp 文件复制到用户可配置的位置(同样,使用自定义选项)并随后清理 tmpdir。
在任何情况下,不干净的 tmpdir 状态都是用户有意识的决定,并且会防止意外的副作用。
您可以从实际项目的 funcargs 轻松检索您的 tmpdir。
你的情况:
from _pytest.runner import runtestprotocol
def pytest_runtest_protocol(item, nextitem):
reports = runtestprotocol(item, nextitem=nextitem)
for report in reports:
if report.when == 'call':
# value will be set to passed or filed
test_outcome = report.outcome
# depending on test_outcome value, remove tmpdir
if test_outcome is "OK for you":
if 'tmpdir' in item.funcargs:
tmpdir = item.funcargs['tmpdir'] #retrieve tmpdir
if tmpdir.check(): tmpdir.remove()
return True
对于这个故事,item.funcargs 是一个字典,其中包含传递给我们当前正在检查的测试 item 的 {arguments:value}。所以第一步是检查 tmpdir 确实是实际测试的 arg,然后检索它。最后在删除它之前检查它是否存在。
希望这会有所帮助。
编辑:
您的 pytest_runtest_protocol(..) 似乎还没有完全初始化该项目。确保它是..
只需覆盖 pytest_runtest_teardown(item),一旦 运行 完成(成功或失败),它就会作用于每个测试项目。
尝试添加这样的方法:
def pytest_runtest_teardown(item):
if item.rep_call.passed:
if 'tmpdir' in item.funcargs:
tmpdir = item.funcargs['tmpdir'] #retrieve tmpdir
if tmpdir.check(): tmpdir.remove()
当然,不要忘记以下内容(在文档中给出)以便轻松访问您的报告。
@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 an report attribute for each phase of a call, which can
# be "setup", "call", "teardown"
setattr(item, "rep_" + rep.when, rep)
我是 运行 测试,在执行过程中会创建大量大文件。为此,如果测试通过,我想删除 tmpdir 目录。但如果测试失败,tmpdir 的内容应该保持不变。
我知道如何判断测试结果:
from _pytest.runner import runtestprotocol
def pytest_runtest_protocol(item, nextitem):
reports = runtestprotocol(item, nextitem=nextitem)
for report in reports:
if report.when == 'call':
# value will be set to passed or filed
test_outcome = report.outcome
# But what next?
return True
但我不知道如何找到创建的tmpdir目录的路径
您应该 create a tmpdir fixture 创建临时目录,将其传递到您的代码中,然后删除它。
此外,fixture 必须设置为始终删除 tempdir,即使在失败时也是如此。否则,您可能会留下不干净的状态,这可能会导致其他测试失败(用户不会注意到)。
相反,我推荐
- 出现错误时使用
--pdb
进入 Python 调试器。夹具尚未清理,您可以检查文件。 - Creating a custom option 允许您禁用 tmpdir 的清理。
- 创建自定义 tmpdir 装置,将所有 tmp 文件复制到用户可配置的位置(同样,使用自定义选项)并随后清理 tmpdir。
在任何情况下,不干净的 tmpdir 状态都是用户有意识的决定,并且会防止意外的副作用。
您可以从实际项目的 funcargs 轻松检索您的 tmpdir。
你的情况:
from _pytest.runner import runtestprotocol
def pytest_runtest_protocol(item, nextitem):
reports = runtestprotocol(item, nextitem=nextitem)
for report in reports:
if report.when == 'call':
# value will be set to passed or filed
test_outcome = report.outcome
# depending on test_outcome value, remove tmpdir
if test_outcome is "OK for you":
if 'tmpdir' in item.funcargs:
tmpdir = item.funcargs['tmpdir'] #retrieve tmpdir
if tmpdir.check(): tmpdir.remove()
return True
对于这个故事,item.funcargs 是一个字典,其中包含传递给我们当前正在检查的测试 item 的 {arguments:value}。所以第一步是检查 tmpdir 确实是实际测试的 arg,然后检索它。最后在删除它之前检查它是否存在。
希望这会有所帮助。
编辑: 您的 pytest_runtest_protocol(..) 似乎还没有完全初始化该项目。确保它是..
只需覆盖 pytest_runtest_teardown(item),一旦 运行 完成(成功或失败),它就会作用于每个测试项目。 尝试添加这样的方法:
def pytest_runtest_teardown(item):
if item.rep_call.passed:
if 'tmpdir' in item.funcargs:
tmpdir = item.funcargs['tmpdir'] #retrieve tmpdir
if tmpdir.check(): tmpdir.remove()
当然,不要忘记以下内容(在文档中给出)以便轻松访问您的报告。
@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 an report attribute for each phase of a call, which can
# be "setup", "call", "teardown"
setattr(item, "rep_" + rep.when, rep)