I have a parameterized pytest test suite. Each parameter is a particular website, and the test suite runs using Selenium automation. After accounting for parameters, I have hundreds of tests in total, and they all run sequentially.
Once a week, Selenium will fail for a variety of reasons. Connection lost, could not instantiate chrome instance, etc. If it fails once in the middle of a test run, it'll crash all upcoming tests. Here's an example fail log:
test_example[parameter] failed; it passed 0 out of the required 1 times.
<class 'selenium.common.exceptions.WebDriverException'>
Message: chrome not reachable
(Session info: chrome=91.0.4472.106)
[<TracebackEntry test.py:122>, <TracebackEntry another.py:92>, <TracebackEntry /usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py:669>, <TracebackEntry /usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py:321>, <TracebackEntry /usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py:242>]
Ideally, I'd like to exit the suite as soon as a Selenium failure has occurred, because I know that all the upcoming tests will also fail.
Is there a method of this kind:
def pytest_on_test_fail(err): # this will be a pytest hook
if is_selenium(err): # user defined function
pytest_earlyexit() # this will be a pytest function
Or some other mechanism that will let me early exit out of the full test suite based on the detected condition.
CodePudding user response:
After some more testing I got this to work. This uses the pytest_exception_interact
hook and the pytest.exit
function.
WebDriverException is the parent class of all Selenium issues (see source code).
def pytest_exception_interact(node, call, report):
error_class = call.excinfo.type
is_selenium_issue = issubclass(error_class, WebDriverException)
if is_selenium_issue:
pytest.exit('Selenium error detected, exiting test suite early', 1)