我正在使用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()
仅在没有失败时才执行
根据你在stackoverflow上的帖子,我可以分享我的想法,我希望它会有所帮助:眨眼:您要做的是处理标准的断言错误异常,该异常可以通过 assert 关键字或 unittest 中实现的任何断言方法引发。测试用例或任何引发自定义异常的自定义断言方法。有 3 种方法可以做到这一点:
-
使用"尝试-但-最终"构造。一些基本示例:
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")
在这里,您可以更深入地了解如何使用它
-
在我看来,最后一个是最优雅的方法。使用装饰器。使用此装饰器,您可以装饰任何测试方法:
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")
经过一番挣扎,最终这对我有用。
在 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
请注意,"request"是pytest在测试上下文中提供的固定装置"funcarg"。您不必自己定义它。
来源:pytest 示例和线程(不是)使这更容易。
这就是我们的做法,请注意__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
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))