Also capture full pytest logs with --ptvsd-logs.

This commit is contained in:
Pavel Minaev 2019-09-29 21:51:22 -07:00 committed by Pavel Minaev
parent 897ffc566b
commit 4b9773e89d
3 changed files with 43 additions and 18 deletions

View file

@ -3,11 +3,9 @@ For example:
tox -e py37 -- --ptvsd-logs "tests/ptvsd/server/test_run.py::test_run[launch-file]"
A separate ptvsd-{pid}.log file will be created for every ptvsd process spawned by
the tests. However, because process IDs are reused by OS, logs may end up overwriting
earlier logs.
A separate directory will be created for every test. In that directory, a separate
subdirectory will be created for every debug.Session instance, containing ptvsd logs
for the processes that it spawns, and pydevd log.
All pydevd logs go into the same file named pydevd.log - and subsequent tests will
overwrite earlier logs.
Thus, it is best to use this when running a single test, or a small number of tests.
If the test has failed, an empty file called FAILED.log is additionally created in
the test log directory, to easily find all failed tests after a large run.

View file

@ -68,7 +68,33 @@ def test_wrapper(request, long_tmpdir):
try:
yield
finally:
log.info("Test {0} completed.", request.node.name)
failed = False
for report_attr in ("setup_report", "call_report", "teardown_report"):
try:
report = getattr(request.node, report_attr)
except AttributeError:
continue
failed |= report.failed
log.write_format(
"error" if report.failed else "info",
"{0} for test {1} {2}.",
report.when,
request.node.name,
report.outcome,
)
if options.log_dir is not None:
with open(os.path.join(options.log_dir, report_attr + ".log"), "w") as f:
f.write(report.longreprtext)
with open(os.path.join(options.log_dir, report_attr + ".stdout.log"), "w") as f:
f.write(report.capstdout)
with open(os.path.join(options.log_dir, report_attr + ".stderr.log"), "w") as f:
f.write(report.capstderr)
if failed and options.log_dir is not None:
with open(os.path.join(options.log_dir, "FAILED.log"), "w"):
pass
finally:
if original_log_dir is not None:
options.log_dir = original_log_dir
@ -85,10 +111,10 @@ def with_pydevd_log(request, tmpdir):
with pydevd_log.enabled(filename):
yield
if request.node.setup_result.passed:
if not request.node.call_result.failed:
if request.node.setup_report.passed:
if not request.node.call_report.failed:
return
elif not request.node.setup_result.failed:
elif not request.node.setup_report.failed:
return
pydevd_log.dump("failed")
@ -113,7 +139,7 @@ def daemon(request):
yield factory
try:
failed = request.node.call_result.failed
failed = request.node.call_report.failed
except AttributeError:
pass
else:

View file

@ -35,15 +35,16 @@ def pytest_report_header(config):
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
# Adds attributes such as setup_result, call_result etc to the item after the
# corresponding scope finished running its tests. This can be used in function-level
# fixtures to detect failures, e.g.:
# Adds attributes setup_report, call_report, and teardown_report to the item,
# referencing TestReport instances for the corresponding phases, after the scope
# finished running its tests. This can be used in function-level fixtures to
# detect test failures, e.g.:
#
# if request.node.call_result.failed: ...
# if request.node.call_report.failed: ...
outcome = yield
result = outcome.get_result()
setattr(item, result.when + "_result", result)
report = outcome.get_result()
setattr(item, report.when + "_report", report)
def pytest_make_parametrize_id(config, val):