Make logging improvements to the sb pytest fixture

This commit is contained in:
Michael Mintz 2020-08-14 01:58:16 -04:00
parent b07e065864
commit 3baf9fe064
3 changed files with 87 additions and 21 deletions

View File

@ -37,24 +37,41 @@ def log_test_failure_data(test, test_logpath, driver, browser, url=None):
data_to_save.append("Last Page: %s" % last_page)
data_to_save.append(" Browser: %s" % browser)
data_to_save.append("Timestamp: %s" % int(time.time()))
if sys.version_info[0] >= 3 and hasattr(test, '_outcome'):
if test._outcome.errors:
try:
exc_message = test._outcome.errors[0][1][1]
traceback_address = test._outcome.errors[0][1][2]
traceback_list = traceback.format_list(
traceback.extract_tb(traceback_address)[1:])
traceback_message = ''.join(traceback_list).strip()
except Exception:
exc_message = "(Unknown Exception)"
traceback_message = "(Unknown Traceback)"
data_to_save.append("Traceback: " + traceback_message)
data_to_save.append("Exception: " + str(exc_message))
if sys.version_info[0] >= 3 and hasattr(test, '_outcome') and (
hasattr(test._outcome, 'errors') and test._outcome.errors):
try:
exc_message = test._outcome.errors[0][1][1]
traceback_address = test._outcome.errors[0][1][2]
traceback_list = traceback.format_list(
traceback.extract_tb(traceback_address)[1:])
traceback_message = ''.join(traceback_list).strip()
except Exception:
exc_message = "(Unknown Exception)"
traceback_message = "(Unknown Traceback)"
data_to_save.append("Traceback: " + traceback_message)
data_to_save.append("Exception: " + str(exc_message))
else:
data_to_save.append("Traceback: " + ''.join(
the_traceback = None
the_traceback = ''.join(
traceback.format_exception(sys.exc_info()[0],
sys.exc_info()[1],
sys.exc_info()[2])))
sys.exc_info()[2]))
if not the_traceback or len(str(the_traceback)) < 30 or (
the_traceback.endswith("StopIteration\n")):
good_stack = []
the_stacks = traceback.format_list(
traceback.extract_tb(sys.last_traceback))
for stack in the_stacks:
if "/site-packages/pluggy/" not in stack:
if "/site-packages/_pytest/" not in stack:
good_stack.append(stack)
the_traceback = ''.join(good_stack)
data_to_save.append("Traceback: " + the_traceback)
last_value = sys.last_value
if last_value:
data_to_save.append("Exception: " + str(last_value))
else:
data_to_save.append("Traceback: " + the_traceback)
log_file.writelines("\r\n".join(data_to_save))
log_file.close()

View File

@ -84,6 +84,7 @@ class BaseCase(unittest.TestCase):
self._language = "English"
self._presentation_slides = {}
self._presentation_transition = {}
self._sb_test_identifier = None
self._html_report_extra = [] # (Used by pytest_plugin.py)
self._default_driver = None
self._drivers_list = []
@ -6315,7 +6316,9 @@ class BaseCase(unittest.TestCase):
def __has_exception(self):
has_exception = False
if sys.version_info[0] >= 3 and hasattr(self, '_outcome'):
if hasattr(sys, 'last_traceback') and sys.last_traceback is not None:
has_exception = True
elif sys.version_info[0] >= 3 and hasattr(self, '_outcome'):
if hasattr(self._outcome, 'errors') and self._outcome.errors:
has_exception = True
else:
@ -6326,6 +6329,8 @@ class BaseCase(unittest.TestCase):
test_id = "%s.%s.%s" % (self.__class__.__module__,
self.__class__.__name__,
self._testMethodName)
if self._sb_test_identifier and len(str(self._sb_test_identifier)) > 6:
test_id = self._sb_test_identifier
return test_id
def __create_log_path_as_needed(self, test_logpath):

View File

@ -520,6 +520,7 @@ def pytest_configure(config):
sb_config.visual_baseline = config.getoption('visual_baseline')
sb_config.timeout_multiplier = config.getoption('timeout_multiplier')
sb_config.pytest_html_report = config.getoption('htmlpath') # --html=FILE
sb_config._sb_node = {} # sb node dictionary (Used with the sb fixture)
if sb_config.reuse_session:
arg_join = " ".join(sys.argv)
@ -592,19 +593,35 @@ def sb(request):
from seleniumbase import BaseCase
class BaseClass(BaseCase):
def base_method():
def setUp(self):
super(BaseClass, self).setUp()
def tearDown(self):
self.save_teardown_screenshot()
super(BaseClass, self).tearDown()
def base_method(self):
pass
if request.cls:
request.cls.sb = BaseClass("base_method")
request.cls.sb.setUp()
request.cls.sb._needs_tearDown = True
sb_config._sb_node[request.node.nodeid] = request.cls.sb
yield request.cls.sb
request.cls.sb.tearDown()
if request.cls.sb._needs_tearDown:
request.cls.sb.tearDown()
request.cls.sb._needs_tearDown = False
else:
sb = BaseClass("base_method")
sb.setUp()
sb._needs_tearDown = True
sb_config._sb_node[request.node.nodeid] = sb
yield sb
sb.tearDown()
if sb._needs_tearDown:
sb.tearDown()
sb._needs_tearDown = False
@pytest.mark.hookwrapper
@ -614,9 +631,36 @@ def pytest_runtest_makereport(item, call):
report = outcome.get_result()
if pytest_html and report.when == 'call':
try:
extra_report = item._testcase._html_report_extra
extra_report = None
if hasattr(item, "_testcase"):
extra_report = item._testcase._html_report_extra
elif hasattr(item.instance, "sb") or (
item.nodeid in sb_config._sb_node):
if not hasattr(item.instance, "sb"):
sb_node = sb_config._sb_node[item.nodeid]
else:
sb_node = item.instance.sb
test_id = item.nodeid
if not test_id:
test_id = "unidentified_TestCase"
test_id = test_id.replace(' ', '_')
if '[' in test_id:
import re
test_id_intro = test_id.split('[')[0]
parameter = test_id.split('[')[1]
parameter = re.sub(re.compile(r'\W'), '', parameter)
test_id = test_id_intro + "__" + parameter
test_id = test_id.replace('/', '.').replace('\\', '.')
test_id = test_id.replace('::', '.').replace('.py', '')
sb_node._sb_test_identifier = test_id
if sb_node._needs_tearDown:
sb_node.tearDown()
sb_node._needs_tearDown = False
extra_report = sb_node._html_report_extra
else:
return
extra = getattr(report, 'extra', [])
if extra_report[1]["content"]:
if len(extra_report) > 1 and extra_report[1]["content"]:
report.extra = extra + extra_report
except Exception:
pass