我正在使用pytest和selenium来自动化网站。我想在测试用例失败时才拍摄一些屏幕截图。我已经普遍使用TestNG和TestNG,它使用ITestListner。 我们在pytest中有类似的东西。
我试图使用teardown_method()来实现这一点 但是当测试用例失败时,这种方法不会被执行。
import sys
from unittestzero import Assert
class TestPY:
def setup_method(self, method):
print("in setup method")
print("executing " + method.__name__)
def teardown_method(self, method):
print(".....teardown")
if sys.exc_info()[0]:
test_method_name = method
print test_method_name
def test_failtest(self):
Assert.fail("failed test")
teardown_method()
仅在没有失败时执行
答案 0 :(得分:8)
根据你在stackoverflow上的post,我可以分享我的想法,我希望它会有所帮助:wink: 您要做的是处理可由 assert 关键字或unittest.TestCase中实现的任何断言方法引发的标准 AssertionError 异常或者可能是任何引发自定义异常的自定义断言方法。 有三种方法可以做到:
使用 try-except-finally 构造。一些基本的例子:
try: Assert.fail("failed test") except AssertionError: get_screenshot() raise
或使用 和 语句作为上下文管理器:
class TestHandler: def __enter__(self): # maybe some set up is expected before assertion method call pass def __exit__(self, exc_type, exc_val, exc_tb): # catch whether exception was raised if isinstance(exc_val, AssertionError): get_screenshot() with TestHandler(): Assert.fail("failed test")
here你可以深入了解如何玩它
在我看来,最后一个是最优雅的方法。使用decorators。有了这个装饰器,你可以装饰任何测试方法:
def decorator_screenshot(func): def wrapper(*args, **kwargs): try: func(*args, **kwargs) except AssertionError: get_screenshot() raise return wrapper @decorator_screenshot def test_something(): Assert.fail("failed test")
答案 1 :(得分:3)
经过一番努力,最终这对我有用。
在conftest.py中:
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
outcome = yield
rep = outcome.get_result()
setattr(item, "rep_" + rep.when, rep)
return rep
并且,在你的代码中,在一个夹具中(例如,在用于测试的拆卸夹具中)使用它如下:
def tear_down(request):
method_name = request.node.name
if request.node.rep_call.failed:
print('test {} failed :('.format(method_name))
# do more stuff like take a selenium screenshot
请注意"请求"是一个固定的" funcarg" pytest在您的测试环境中提供。你不必自己定义它。
答案 2 :(得分:1)
这就是我们这样做的方法,请注意 __ multicall __ 的文档非常少,我记得阅读 __ multicall __ 将被弃用,请使用一小撮盐和尝试将 __ multicall __ 替换为' 项,致电'按照例子。
def pytest_runtest_makereport(__multicall__):
report = __multicall__.execute()
if report.when == 'call':
xfail = hasattr(report, 'wasxfail')
if (report.skipped and xfail) or (report.failed and not xfail):
try:
screenshot = APP_DRIVER.take_screen_shot(format="base64")
except Exception as e:
LOG.debug("Error saving screenshot !!")
LOG.debug(e)
return report
答案 3 :(得分:0)
def pytest_runtest_makereport(item, call):
if call.when == 'call':
if call.excinfo is not None:
# if excinfor is not None, indicate that this test item is failed test case
error("Test Case: {}.{} Failed.".format(item.location[0], item.location[2]))
error("Error: \n{}".format(call.excinfo))