address comments
This commit is contained in:
@@ -21,10 +21,11 @@ _ENVIRON_PYTHONBREAKPOINT = os.environ.get("PYTHONBREAKPOINT", "")
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def pdb_env(request, monkeypatch: MonkeyPatch):
|
||||
def pdb_env(request):
|
||||
if "pytester" in request.fixturenames:
|
||||
# Disable pdb++ with inner tests.
|
||||
monkeypatch.setenv("PDBPP_HIJACK_PDB", "0")
|
||||
pytester = request.getfixturevalue("pytester")
|
||||
pytester._monkeypatch.setenv("PDBPP_HIJACK_PDB", "0")
|
||||
|
||||
|
||||
def runpdb_and_get_report(pytester: Pytester, source: str):
|
||||
|
||||
@@ -7,7 +7,6 @@ from typing import List
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TypeVar
|
||||
from typing import Union
|
||||
from xml.dom import minidom
|
||||
|
||||
@@ -24,8 +23,6 @@ from _pytest.reports import BaseReport
|
||||
from _pytest.reports import TestReport
|
||||
from _pytest.store import Store
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def schema() -> xmlschema.XMLSchema:
|
||||
@@ -35,29 +32,34 @@ def schema() -> xmlschema.XMLSchema:
|
||||
return xmlschema.XMLSchema(f)
|
||||
|
||||
|
||||
class RunAndParse:
|
||||
def __init__(self, pytester: Pytester, schema: xmlschema.XMLSchema) -> None:
|
||||
self.pytester = pytester
|
||||
self.schema = schema
|
||||
|
||||
def __call__(
|
||||
self, *args: Union[str, "os.PathLike[str]"], family: Optional[str] = "xunit1"
|
||||
) -> Tuple[RunResult, "DomNode"]:
|
||||
if family:
|
||||
args = ("-o", "junit_family=" + family) + args
|
||||
xml_path = self.pytester.path.joinpath("junit.xml")
|
||||
result = self.pytester.runpytest("--junitxml=%s" % xml_path, *args)
|
||||
if family == "xunit2":
|
||||
with xml_path.open() as f:
|
||||
self.schema.validate(f)
|
||||
xmldoc = minidom.parse(str(xml_path))
|
||||
return result, DomNode(xmldoc)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def run_and_parse(pytester: Pytester, schema: xmlschema.XMLSchema) -> T:
|
||||
def run_and_parse(pytester: Pytester, schema: xmlschema.XMLSchema) -> RunAndParse:
|
||||
"""Fixture that returns a function that can be used to execute pytest and
|
||||
return the parsed ``DomNode`` of the root xml node.
|
||||
|
||||
The ``family`` parameter is used to configure the ``junit_family`` of the written report.
|
||||
"xunit2" is also automatically validated against the schema.
|
||||
"""
|
||||
|
||||
def run(
|
||||
*args: Union[str, "os.PathLike[str]"], family: Optional[str] = "xunit1",
|
||||
) -> Tuple[RunResult, "DomNode"]:
|
||||
if family:
|
||||
args = ("-o", "junit_family=" + family) + args
|
||||
xml_path = pytester.path.joinpath("junit.xml")
|
||||
result = pytester.runpytest("--junitxml=%s" % xml_path, *args)
|
||||
if family == "xunit2":
|
||||
with xml_path.open() as f:
|
||||
schema.validate(f)
|
||||
xmldoc = minidom.parse(str(xml_path))
|
||||
return result, DomNode(xmldoc)
|
||||
|
||||
return cast(T, run)
|
||||
return RunAndParse(pytester, schema)
|
||||
|
||||
|
||||
def assert_attr(node, **kwargs):
|
||||
@@ -140,7 +142,7 @@ parametrize_families = pytest.mark.parametrize("xunit_family", ["xunit1", "xunit
|
||||
class TestPython:
|
||||
@parametrize_families
|
||||
def test_summing_simple(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -166,7 +168,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_summing_simple_with_errors(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -195,7 +197,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_hostname_in_xml(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -209,7 +211,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_timestamp_in_xml(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -224,7 +226,7 @@ class TestPython:
|
||||
assert start_time <= timestamp < datetime.now()
|
||||
|
||||
def test_timing_function(
|
||||
self, pytester: Pytester, run_and_parse, mock_timing
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, mock_timing
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -248,8 +250,8 @@ class TestPython:
|
||||
self,
|
||||
pytester: Pytester,
|
||||
monkeypatch: MonkeyPatch,
|
||||
duration_report,
|
||||
run_and_parse,
|
||||
duration_report: str,
|
||||
run_and_parse: RunAndParse,
|
||||
) -> None:
|
||||
|
||||
# mock LogXML.node_reporter so it always sets a known duration to each test report object
|
||||
@@ -279,7 +281,9 @@ class TestPython:
|
||||
assert val == 1.0
|
||||
|
||||
@parametrize_families
|
||||
def test_setup_error(self, pytester: Pytester, run_and_parse, xunit_family) -> None:
|
||||
def test_setup_error(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
@@ -303,7 +307,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_teardown_error(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -328,7 +332,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_call_failure_teardown_error(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -359,7 +363,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_skip_contains_name_reason(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -379,7 +383,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_mark_skip_contains_name_reason(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -402,7 +406,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_mark_skipif_contains_name_reason(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -426,7 +430,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_mark_skip_doesnt_capture_output(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -443,7 +447,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_classname_instance(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -463,7 +467,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_classname_nested_dir(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
p = pytester.mkdir("sub").joinpath("test_hello.py")
|
||||
p.write_text("def test_func(): 0/0")
|
||||
@@ -476,7 +480,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_internal_error(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makeconftest("def pytest_runtest_protocol(): 0 / 0")
|
||||
pytester.makepyfile("def test_function(): pass")
|
||||
@@ -495,7 +499,11 @@ class TestPython:
|
||||
)
|
||||
@parametrize_families
|
||||
def test_failure_function(
|
||||
self, pytester: Pytester, junit_logging, run_and_parse, xunit_family
|
||||
self,
|
||||
pytester: Pytester,
|
||||
junit_logging,
|
||||
run_and_parse: RunAndParse,
|
||||
xunit_family,
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -559,7 +567,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_failure_verbose_message(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -576,7 +584,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_failure_escape(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -606,7 +614,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_junit_prefixing(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -630,7 +638,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_xfailure_function(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -650,7 +658,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_xfailure_marker(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -673,7 +681,7 @@ class TestPython:
|
||||
"junit_logging", ["no", "log", "system-out", "system-err", "out-err", "all"]
|
||||
)
|
||||
def test_xfail_captures_output_once(
|
||||
self, pytester: Pytester, junit_logging, run_and_parse
|
||||
self, pytester: Pytester, junit_logging: str, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -702,7 +710,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_xfailure_xpass(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -721,7 +729,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_xfailure_xpass_strict(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -742,7 +750,7 @@ class TestPython:
|
||||
|
||||
@parametrize_families
|
||||
def test_collect_error(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile("syntax error")
|
||||
result, dom = run_and_parse(family=xunit_family)
|
||||
@@ -754,7 +762,7 @@ class TestPython:
|
||||
fnode.assert_attr(message="collection failure")
|
||||
assert "SyntaxError" in fnode.toxml()
|
||||
|
||||
def test_unicode(self, pytester: Pytester, run_and_parse) -> None:
|
||||
def test_unicode(self, pytester: Pytester, run_and_parse: RunAndParse) -> None:
|
||||
value = "hx\xc4\x85\xc4\x87\n"
|
||||
pytester.makepyfile(
|
||||
"""\
|
||||
@@ -771,7 +779,9 @@ class TestPython:
|
||||
fnode = tnode.find_first_by_tag("failure")
|
||||
assert "hx" in fnode.toxml()
|
||||
|
||||
def test_assertion_binchars(self, pytester: Pytester, run_and_parse) -> None:
|
||||
def test_assertion_binchars(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
"""This test did fail when the escaping wasn't strict."""
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -788,7 +798,7 @@ class TestPython:
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-out"])
|
||||
def test_pass_captures_stdout(
|
||||
self, pytester: Pytester, run_and_parse, junit_logging
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, junit_logging: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -811,7 +821,7 @@ class TestPython:
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-err"])
|
||||
def test_pass_captures_stderr(
|
||||
self, pytester: Pytester, run_and_parse, junit_logging
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, junit_logging: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -835,7 +845,7 @@ class TestPython:
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-out"])
|
||||
def test_setup_error_captures_stdout(
|
||||
self, pytester: Pytester, run_and_parse, junit_logging
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, junit_logging: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -864,7 +874,7 @@ class TestPython:
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-err"])
|
||||
def test_setup_error_captures_stderr(
|
||||
self, pytester: Pytester, run_and_parse, junit_logging
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, junit_logging: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -894,7 +904,7 @@ class TestPython:
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-out"])
|
||||
def test_avoid_double_stdout(
|
||||
self, pytester: Pytester, run_and_parse, junit_logging
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, junit_logging: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -964,7 +974,7 @@ def test_dont_configure_on_workers(tmp_path: Path) -> None:
|
||||
class TestNonPython:
|
||||
@parametrize_families
|
||||
def test_summing_simple(
|
||||
self, pytester: Pytester, run_and_parse, xunit_family
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makeconftest(
|
||||
"""
|
||||
@@ -992,7 +1002,7 @@ class TestNonPython:
|
||||
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-out"])
|
||||
def test_nullbyte(pytester: Pytester, junit_logging) -> None:
|
||||
def test_nullbyte(pytester: Pytester, junit_logging: str) -> None:
|
||||
# A null byte can not occur in XML (see section 2.2 of the spec)
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -1014,7 +1024,7 @@ def test_nullbyte(pytester: Pytester, junit_logging) -> None:
|
||||
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-out"])
|
||||
def test_nullbyte_replace(pytester: Pytester, junit_logging) -> None:
|
||||
def test_nullbyte_replace(pytester: Pytester, junit_logging: str) -> None:
|
||||
# Check if the null byte gets replaced
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -1114,7 +1124,9 @@ def test_logxml_check_isdir(pytester: Pytester) -> None:
|
||||
result.stderr.fnmatch_lines(["*--junitxml must be a filename*"])
|
||||
|
||||
|
||||
def test_escaped_parametrized_names_xml(pytester: Pytester, run_and_parse) -> None:
|
||||
def test_escaped_parametrized_names_xml(
|
||||
pytester: Pytester, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""\
|
||||
import pytest
|
||||
@@ -1130,7 +1142,7 @@ def test_escaped_parametrized_names_xml(pytester: Pytester, run_and_parse) -> No
|
||||
|
||||
|
||||
def test_double_colon_split_function_issue469(
|
||||
pytester: Pytester, run_and_parse
|
||||
pytester: Pytester, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -1147,7 +1159,9 @@ def test_double_colon_split_function_issue469(
|
||||
node.assert_attr(name="test_func[double::colon]")
|
||||
|
||||
|
||||
def test_double_colon_split_method_issue469(pytester: Pytester, run_and_parse) -> None:
|
||||
def test_double_colon_split_method_issue469(
|
||||
pytester: Pytester, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
@@ -1194,7 +1208,7 @@ def test_unicode_issue368(pytester: Pytester) -> None:
|
||||
log.pytest_sessionfinish()
|
||||
|
||||
|
||||
def test_record_property(pytester: Pytester, run_and_parse) -> None:
|
||||
def test_record_property(pytester: Pytester, run_and_parse: RunAndParse) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
@@ -1216,7 +1230,9 @@ def test_record_property(pytester: Pytester, run_and_parse) -> None:
|
||||
result.stdout.fnmatch_lines(["*= 1 passed in *"])
|
||||
|
||||
|
||||
def test_record_property_same_name(pytester: Pytester, run_and_parse) -> None:
|
||||
def test_record_property_same_name(
|
||||
pytester: Pytester, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_record_with_same_name(record_property):
|
||||
@@ -1234,7 +1250,9 @@ def test_record_property_same_name(pytester: Pytester, run_and_parse) -> None:
|
||||
|
||||
|
||||
@pytest.mark.parametrize("fixture_name", ["record_property", "record_xml_attribute"])
|
||||
def test_record_fixtures_without_junitxml(pytester: Pytester, fixture_name) -> None:
|
||||
def test_record_fixtures_without_junitxml(
|
||||
pytester: Pytester, fixture_name: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_record({fixture_name}):
|
||||
@@ -1248,7 +1266,7 @@ def test_record_fixtures_without_junitxml(pytester: Pytester, fixture_name) -> N
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("default")
|
||||
def test_record_attribute(pytester: Pytester, run_and_parse) -> None:
|
||||
def test_record_attribute(pytester: Pytester, run_and_parse: RunAndParse) -> None:
|
||||
pytester.makeini(
|
||||
"""
|
||||
[pytest]
|
||||
@@ -1279,7 +1297,7 @@ def test_record_attribute(pytester: Pytester, run_and_parse) -> None:
|
||||
@pytest.mark.filterwarnings("default")
|
||||
@pytest.mark.parametrize("fixture_name", ["record_xml_attribute", "record_property"])
|
||||
def test_record_fixtures_xunit2(
|
||||
pytester: Pytester, fixture_name, run_and_parse
|
||||
pytester: Pytester, fixture_name: str, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
"""Ensure record_xml_attribute and record_property drop values when outside of legacy family."""
|
||||
pytester.makeini(
|
||||
@@ -1318,7 +1336,7 @@ def test_record_fixtures_xunit2(
|
||||
|
||||
|
||||
def test_random_report_log_xdist(
|
||||
pytester: Pytester, monkeypatch: MonkeyPatch, run_and_parse
|
||||
pytester: Pytester, monkeypatch: MonkeyPatch, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
"""`xdist` calls pytest_runtest_logreport as they are executed by the workers,
|
||||
with nodes from several nodes overlapping, so junitxml must cope with that
|
||||
@@ -1344,7 +1362,9 @@ def test_random_report_log_xdist(
|
||||
|
||||
|
||||
@parametrize_families
|
||||
def test_root_testsuites_tag(pytester: Pytester, run_and_parse, xunit_family) -> None:
|
||||
def test_root_testsuites_tag(
|
||||
pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_x():
|
||||
@@ -1358,7 +1378,7 @@ def test_root_testsuites_tag(pytester: Pytester, run_and_parse, xunit_family) ->
|
||||
assert suite_node.tag == "testsuite"
|
||||
|
||||
|
||||
def test_runs_twice(pytester: Pytester, run_and_parse) -> None:
|
||||
def test_runs_twice(pytester: Pytester, run_and_parse: RunAndParse) -> None:
|
||||
f = pytester.makepyfile(
|
||||
"""
|
||||
def test_pass():
|
||||
@@ -1373,7 +1393,7 @@ def test_runs_twice(pytester: Pytester, run_and_parse) -> None:
|
||||
|
||||
|
||||
def test_runs_twice_xdist(
|
||||
pytester: Pytester, monkeypatch: MonkeyPatch, run_and_parse
|
||||
pytester: Pytester, monkeypatch: MonkeyPatch, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytest.importorskip("xdist")
|
||||
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD")
|
||||
@@ -1390,7 +1410,7 @@ def test_runs_twice_xdist(
|
||||
assert first == second
|
||||
|
||||
|
||||
def test_fancy_items_regression(pytester: Pytester, run_and_parse) -> None:
|
||||
def test_fancy_items_regression(pytester: Pytester, run_and_parse: RunAndParse) -> None:
|
||||
# issue 1259
|
||||
pytester.makeconftest(
|
||||
"""
|
||||
@@ -1443,7 +1463,7 @@ def test_fancy_items_regression(pytester: Pytester, run_and_parse) -> None:
|
||||
|
||||
|
||||
@parametrize_families
|
||||
def test_global_properties(pytester: Pytester, xunit_family) -> None:
|
||||
def test_global_properties(pytester: Pytester, xunit_family: str) -> None:
|
||||
path = pytester.path.joinpath("test_global_properties.xml")
|
||||
log = LogXML(str(path), None, family=xunit_family)
|
||||
|
||||
@@ -1505,7 +1525,7 @@ def test_url_property(pytester: Pytester) -> None:
|
||||
|
||||
@parametrize_families
|
||||
def test_record_testsuite_property(
|
||||
pytester: Pytester, run_and_parse, xunit_family
|
||||
pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
@@ -1538,7 +1558,9 @@ def test_record_testsuite_property_junit_disabled(pytester: Pytester) -> None:
|
||||
|
||||
|
||||
@pytest.mark.parametrize("junit", [True, False])
|
||||
def test_record_testsuite_property_type_checking(pytester: Pytester, junit) -> None:
|
||||
def test_record_testsuite_property_type_checking(
|
||||
pytester: Pytester, junit: bool
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_func1(record_testsuite_property):
|
||||
@@ -1556,7 +1578,7 @@ def test_record_testsuite_property_type_checking(pytester: Pytester, junit) -> N
|
||||
@pytest.mark.parametrize("suite_name", ["my_suite", ""])
|
||||
@parametrize_families
|
||||
def test_set_suite_name(
|
||||
pytester: Pytester, suite_name, run_and_parse, xunit_family
|
||||
pytester: Pytester, suite_name: str, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
if suite_name:
|
||||
pytester.makeini(
|
||||
@@ -1585,7 +1607,9 @@ def test_set_suite_name(
|
||||
node.assert_attr(name=expected)
|
||||
|
||||
|
||||
def test_escaped_skipreason_issue3533(pytester: Pytester, run_and_parse) -> None:
|
||||
def test_escaped_skipreason_issue3533(
|
||||
pytester: Pytester, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
@@ -1603,7 +1627,7 @@ def test_escaped_skipreason_issue3533(pytester: Pytester, run_and_parse) -> None
|
||||
|
||||
@parametrize_families
|
||||
def test_logging_passing_tests_disabled_does_not_log_test_output(
|
||||
pytester: Pytester, run_and_parse, xunit_family
|
||||
pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makeini(
|
||||
"""
|
||||
@@ -1637,7 +1661,10 @@ def test_logging_passing_tests_disabled_does_not_log_test_output(
|
||||
@parametrize_families
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-out", "system-err"])
|
||||
def test_logging_passing_tests_disabled_logs_output_for_failing_test_issue5430(
|
||||
pytester: Pytester, junit_logging, run_and_parse, xunit_family
|
||||
pytester: Pytester,
|
||||
junit_logging: str,
|
||||
run_and_parse: RunAndParse,
|
||||
xunit_family: str,
|
||||
) -> None:
|
||||
pytester.makeini(
|
||||
"""
|
||||
|
||||
@@ -92,7 +92,7 @@ def test_pytester_runs_with_plugin(pytester: Pytester) -> None:
|
||||
result.assert_outcomes(passed=1)
|
||||
|
||||
|
||||
def test_pytester_with_doctest(pytester: Pytester):
|
||||
def test_pytester_with_doctest(pytester: Pytester) -> None:
|
||||
"""Check that pytester can be used within doctests.
|
||||
|
||||
It used to use `request.function`, which is `None` with doctests."""
|
||||
@@ -314,20 +314,19 @@ def test_cwd_snapshot(pytester: Pytester) -> None:
|
||||
|
||||
class TestSysModulesSnapshot:
|
||||
key = "my-test-module"
|
||||
mod = ModuleType("something")
|
||||
|
||||
def test_remove_added(self) -> None:
|
||||
original = dict(sys.modules)
|
||||
assert self.key not in sys.modules
|
||||
snapshot = SysModulesSnapshot()
|
||||
sys.modules[self.key] = "something" # type: ignore
|
||||
sys.modules[self.key] = ModuleType("something")
|
||||
assert self.key in sys.modules
|
||||
snapshot.restore()
|
||||
assert sys.modules == original
|
||||
|
||||
def test_add_removed(self, monkeypatch: MonkeyPatch) -> None:
|
||||
assert self.key not in sys.modules
|
||||
monkeypatch.setitem(sys.modules, self.key, self.mod)
|
||||
monkeypatch.setitem(sys.modules, self.key, ModuleType("something"))
|
||||
assert self.key in sys.modules
|
||||
original = dict(sys.modules)
|
||||
snapshot = SysModulesSnapshot()
|
||||
@@ -338,11 +337,11 @@ class TestSysModulesSnapshot:
|
||||
|
||||
def test_restore_reloaded(self, monkeypatch: MonkeyPatch) -> None:
|
||||
assert self.key not in sys.modules
|
||||
monkeypatch.setitem(sys.modules, self.key, self.mod)
|
||||
monkeypatch.setitem(sys.modules, self.key, ModuleType("something"))
|
||||
assert self.key in sys.modules
|
||||
original = dict(sys.modules)
|
||||
snapshot = SysModulesSnapshot()
|
||||
sys.modules[self.key] = "something else" # type: ignore
|
||||
sys.modules[self.key] = ModuleType("something else")
|
||||
snapshot.restore()
|
||||
assert sys.modules == original
|
||||
|
||||
@@ -358,9 +357,9 @@ class TestSysModulesSnapshot:
|
||||
return name in (key[0], key[1], "some-other-key")
|
||||
|
||||
snapshot = SysModulesSnapshot(preserve=preserve)
|
||||
sys.modules[key[0]] = original[key[0]] = "something else0" # type: ignore
|
||||
sys.modules[key[1]] = original[key[1]] = "something else1" # type: ignore
|
||||
sys.modules[key[2]] = "something else2" # type: ignore
|
||||
sys.modules[key[0]] = original[key[0]] = ModuleType("something else0")
|
||||
sys.modules[key[1]] = original[key[1]] = ModuleType("something else1")
|
||||
sys.modules[key[2]] = ModuleType("something else2")
|
||||
snapshot.restore()
|
||||
assert sys.modules == original
|
||||
|
||||
@@ -368,7 +367,7 @@ class TestSysModulesSnapshot:
|
||||
original = dict(sys.modules)
|
||||
assert self.key not in original
|
||||
replacement = dict(sys.modules)
|
||||
replacement[self.key] = "life of brian" # type: ignore
|
||||
replacement[self.key] = ModuleType("life of brian")
|
||||
snapshot = SysModulesSnapshot()
|
||||
monkeypatch.setattr(sys, "modules", replacement)
|
||||
snapshot.restore()
|
||||
@@ -442,7 +441,9 @@ def test_pytester_subprocess_via_runpytest_arg(pytester: Pytester) -> None:
|
||||
assert pytester.runpytest(testfile).ret == 0
|
||||
"""
|
||||
)
|
||||
result = pytester.runpytest("-p", "pytester", "--runpytest", "subprocess", testfile)
|
||||
result = pytester.runpytest_inprocess(
|
||||
"-p", "pytester", "--runpytest", "subprocess", testfile
|
||||
)
|
||||
assert result.ret == 0
|
||||
|
||||
|
||||
@@ -777,7 +778,7 @@ def test_pytester_outcomes_with_multiple_errors(pytester: Pytester) -> None:
|
||||
assert result.parseoutcomes() == {"errors": 2}
|
||||
|
||||
|
||||
def test_parse_summary_line_always_plural():
|
||||
def test_parse_summary_line_always_plural() -> None:
|
||||
"""Parsing summaries always returns plural nouns (#6505)"""
|
||||
lines = [
|
||||
"some output 1",
|
||||
@@ -812,6 +813,6 @@ def test_makefile_joins_absolute_path(pytester: Pytester) -> None:
|
||||
assert str(p1) == str(pytester.path / "absfile.py")
|
||||
|
||||
|
||||
def test_testtmproot(testdir):
|
||||
def test_testtmproot(testdir) -> None:
|
||||
"""Check test_tmproot is a py.path attribute for backward compatibility."""
|
||||
assert testdir.test_tmproot.check(dir=1)
|
||||
|
||||
Reference in New Issue
Block a user