resultlog: add missing type annotations

This commit is contained in:
Ran Benita 2020-08-01 10:11:24 +03:00
parent 303030c141
commit 62ddf7a0e5
2 changed files with 26 additions and 18 deletions

View File

@ -1,5 +1,7 @@
"""log machine-parseable test session result information to a plain text file.""" """log machine-parseable test session result information to a plain text file."""
import os import os
from typing import IO
from typing import Union
import py import py
@ -52,16 +54,18 @@ def pytest_unconfigure(config: Config) -> None:
class ResultLog: class ResultLog:
def __init__(self, config, logfile): def __init__(self, config: Config, logfile: IO[str]) -> None:
self.config = config self.config = config
self.logfile = logfile # preferably line buffered self.logfile = logfile # preferably line buffered
def write_log_entry(self, testpath, lettercode, longrepr): def write_log_entry(self, testpath: str, lettercode: str, longrepr: str) -> None:
print("{} {}".format(lettercode, testpath), file=self.logfile) print("{} {}".format(lettercode, testpath), file=self.logfile)
for line in longrepr.splitlines(): for line in longrepr.splitlines():
print(" %s" % line, file=self.logfile) print(" %s" % line, file=self.logfile)
def log_outcome(self, report, lettercode, longrepr): def log_outcome(
self, report: Union[TestReport, CollectReport], lettercode: str, longrepr: str
) -> None:
testpath = getattr(report, "nodeid", None) testpath = getattr(report, "nodeid", None)
if testpath is None: if testpath is None:
testpath = report.fspath testpath = report.fspath
@ -73,7 +77,7 @@ class ResultLog:
res = self.config.hook.pytest_report_teststatus( res = self.config.hook.pytest_report_teststatus(
report=report, config=self.config report=report, config=self.config
) )
code = res[1] code = res[1] # type: str
if code == "x": if code == "x":
longrepr = str(report.longrepr) longrepr = str(report.longrepr)
elif code == "X": elif code == "X":

View File

@ -1,18 +1,21 @@
import os import os
from io import StringIO from io import StringIO
from typing import List
import _pytest._code import _pytest._code
import pytest import pytest
from _pytest.pytester import Testdir
from _pytest.resultlog import pytest_configure from _pytest.resultlog import pytest_configure
from _pytest.resultlog import pytest_unconfigure from _pytest.resultlog import pytest_unconfigure
from _pytest.resultlog import ResultLog from _pytest.resultlog import ResultLog
from _pytest.resultlog import resultlog_key from _pytest.resultlog import resultlog_key
pytestmark = pytest.mark.filterwarnings("ignore:--result-log is deprecated") pytestmark = pytest.mark.filterwarnings("ignore:--result-log is deprecated")
def test_write_log_entry(): def test_write_log_entry() -> None:
reslog = ResultLog(None, None) reslog = ResultLog(None, None) # type: ignore[arg-type]
reslog.logfile = StringIO() reslog.logfile = StringIO()
reslog.write_log_entry("name", ".", "") reslog.write_log_entry("name", ".", "")
entry = reslog.logfile.getvalue() entry = reslog.logfile.getvalue()
@ -54,14 +57,14 @@ class TestWithFunctionIntegration:
# XXX (hpk) i think that the resultlog plugin should # XXX (hpk) i think that the resultlog plugin should
# provide a Parser object so that one can remain # provide a Parser object so that one can remain
# ignorant regarding formatting details. # ignorant regarding formatting details.
def getresultlog(self, testdir, arg): def getresultlog(self, testdir: Testdir, arg: str) -> List[str]:
resultlog = testdir.tmpdir.join("resultlog") resultlog = testdir.tmpdir.join("resultlog")
testdir.plugins.append("resultlog") testdir.plugins.append("resultlog")
args = ["--resultlog=%s" % resultlog] + [arg] args = ["--resultlog=%s" % resultlog] + [arg]
testdir.runpytest(*args) testdir.runpytest(*args)
return [x for x in resultlog.readlines(cr=0) if x] return [x for x in resultlog.readlines(cr=0) if x]
def test_collection_report(self, testdir): def test_collection_report(self, testdir: Testdir) -> None:
ok = testdir.makepyfile(test_collection_ok="") ok = testdir.makepyfile(test_collection_ok="")
fail = testdir.makepyfile(test_collection_fail="XXX") fail = testdir.makepyfile(test_collection_fail="XXX")
lines = self.getresultlog(testdir, ok) lines = self.getresultlog(testdir, ok)
@ -75,7 +78,7 @@ class TestWithFunctionIntegration:
assert x.startswith(" ") assert x.startswith(" ")
assert "XXX" in "".join(lines[1:]) assert "XXX" in "".join(lines[1:])
def test_log_test_outcomes(self, testdir): def test_log_test_outcomes(self, testdir: Testdir) -> None:
mod = testdir.makepyfile( mod = testdir.makepyfile(
test_mod=""" test_mod="""
import pytest import pytest
@ -111,16 +114,17 @@ class TestWithFunctionIntegration:
assert len(lines) == 15 assert len(lines) == 15
@pytest.mark.parametrize("style", ("native", "long", "short")) @pytest.mark.parametrize("style", ("native", "long", "short"))
def test_internal_exception(self, style): def test_internal_exception(self, style) -> None:
# they are produced for example by a teardown failing # they are produced for example by a teardown failing
# at the end of the run or a failing hook invocation # at the end of the run or a failing hook invocation
try: try:
raise ValueError raise ValueError
except ValueError: except ValueError:
excinfo = _pytest._code.ExceptionInfo.from_current() excinfo = _pytest._code.ExceptionInfo.from_current()
reslog = ResultLog(None, StringIO()) file = StringIO()
reslog = ResultLog(None, file) # type: ignore[arg-type]
reslog.pytest_internalerror(excinfo.getrepr(style=style)) reslog.pytest_internalerror(excinfo.getrepr(style=style))
entry = reslog.logfile.getvalue() entry = file.getvalue()
entry_lines = entry.splitlines() entry_lines = entry.splitlines()
assert entry_lines[0].startswith("! ") assert entry_lines[0].startswith("! ")
@ -130,7 +134,7 @@ class TestWithFunctionIntegration:
assert "ValueError" in entry assert "ValueError" in entry
def test_generic(testdir, LineMatcher): def test_generic(testdir: Testdir, LineMatcher) -> None:
testdir.plugins.append("resultlog") testdir.plugins.append("resultlog")
testdir.makepyfile( testdir.makepyfile(
""" """
@ -162,7 +166,7 @@ def test_generic(testdir, LineMatcher):
) )
def test_makedir_for_resultlog(testdir, LineMatcher): def test_makedir_for_resultlog(testdir: Testdir, LineMatcher) -> None:
"""--resultlog should automatically create directories for the log file""" """--resultlog should automatically create directories for the log file"""
testdir.plugins.append("resultlog") testdir.plugins.append("resultlog")
testdir.makepyfile( testdir.makepyfile(
@ -177,7 +181,7 @@ def test_makedir_for_resultlog(testdir, LineMatcher):
LineMatcher(lines).fnmatch_lines([". *:test_pass"]) LineMatcher(lines).fnmatch_lines([". *:test_pass"])
def test_no_resultlog_on_workers(testdir): def test_no_resultlog_on_workers(testdir: Testdir) -> None:
config = testdir.parseconfig("-p", "resultlog", "--resultlog=resultlog") config = testdir.parseconfig("-p", "resultlog", "--resultlog=resultlog")
assert resultlog_key not in config._store assert resultlog_key not in config._store
@ -186,14 +190,14 @@ def test_no_resultlog_on_workers(testdir):
pytest_unconfigure(config) pytest_unconfigure(config)
assert resultlog_key not in config._store assert resultlog_key not in config._store
config.workerinput = {} config.workerinput = {} # type: ignore[attr-defined]
pytest_configure(config) pytest_configure(config)
assert resultlog_key not in config._store assert resultlog_key not in config._store
pytest_unconfigure(config) pytest_unconfigure(config)
assert resultlog_key not in config._store assert resultlog_key not in config._store
def test_unknown_teststatus(testdir): def test_unknown_teststatus(testdir: Testdir) -> None:
"""Ensure resultlog correctly handles unknown status from pytest_report_teststatus """Ensure resultlog correctly handles unknown status from pytest_report_teststatus
Inspired on pytest-rerunfailures. Inspired on pytest-rerunfailures.
@ -229,7 +233,7 @@ def test_unknown_teststatus(testdir):
assert lines[0] == "r test_unknown_teststatus.py::test" assert lines[0] == "r test_unknown_teststatus.py::test"
def test_failure_issue380(testdir): def test_failure_issue380(testdir: Testdir) -> None:
testdir.makeconftest( testdir.makeconftest(
""" """
import pytest import pytest