Merge pull request #8168 from antonblr/testdir-to-pytester-incr2
tests: Migrate to pytester - final update
This commit is contained in:
commit
89dcfbf293
|
@ -528,7 +528,7 @@ class FSCollector(Collector):
|
|||
warnings.warn(FSCOLLECTOR_GETHOOKPROXY_ISINITPATH, stacklevel=2)
|
||||
return self.session.gethookproxy(fspath)
|
||||
|
||||
def isinitpath(self, path: py.path.local) -> bool:
|
||||
def isinitpath(self, path: Union[str, "os.PathLike[str]"]) -> bool:
|
||||
warnings.warn(FSCOLLECTOR_GETHOOKPROXY_ISINITPATH, stacklevel=2)
|
||||
return self.session.isinitpath(path)
|
||||
|
||||
|
|
|
@ -660,7 +660,7 @@ class Package(Module):
|
|||
warnings.warn(FSCOLLECTOR_GETHOOKPROXY_ISINITPATH, stacklevel=2)
|
||||
return self.session.gethookproxy(fspath)
|
||||
|
||||
def isinitpath(self, path: py.path.local) -> bool:
|
||||
def isinitpath(self, path: Union[str, "os.PathLike[str]"]) -> bool:
|
||||
warnings.warn(FSCOLLECTOR_GETHOOKPROXY_ISINITPATH, stacklevel=2)
|
||||
return self.session.isinitpath(path)
|
||||
|
||||
|
|
|
@ -5,24 +5,23 @@ from unittest import mock
|
|||
import pytest
|
||||
from _pytest import deprecated
|
||||
from _pytest.pytester import Pytester
|
||||
from _pytest.pytester import Testdir
|
||||
|
||||
|
||||
@pytest.mark.parametrize("attribute", pytest.collect.__all__) # type: ignore
|
||||
# false positive due to dynamic attribute
|
||||
def test_pytest_collect_module_deprecated(attribute):
|
||||
def test_pytest_collect_module_deprecated(attribute) -> None:
|
||||
with pytest.warns(DeprecationWarning, match=attribute):
|
||||
getattr(pytest.collect, attribute)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("plugin", sorted(deprecated.DEPRECATED_EXTERNAL_PLUGINS))
|
||||
@pytest.mark.filterwarnings("default")
|
||||
def test_external_plugins_integrated(testdir, plugin):
|
||||
testdir.syspathinsert()
|
||||
testdir.makepyfile(**{plugin: ""})
|
||||
def test_external_plugins_integrated(pytester: Pytester, plugin) -> None:
|
||||
pytester.syspathinsert()
|
||||
pytester.makepyfile(**{plugin: ""})
|
||||
|
||||
with pytest.warns(pytest.PytestConfigWarning):
|
||||
testdir.parseconfig("-p", plugin)
|
||||
pytester.parseconfig("-p", plugin)
|
||||
|
||||
|
||||
def test_fillfuncargs_is_deprecated() -> None:
|
||||
|
@ -49,32 +48,32 @@ def test_fillfixtures_is_deprecated() -> None:
|
|||
_pytest.fixtures.fillfixtures(mock.Mock())
|
||||
|
||||
|
||||
def test_minus_k_dash_is_deprecated(testdir) -> None:
|
||||
threepass = testdir.makepyfile(
|
||||
def test_minus_k_dash_is_deprecated(pytester: Pytester) -> None:
|
||||
threepass = pytester.makepyfile(
|
||||
test_threepass="""
|
||||
def test_one(): assert 1
|
||||
def test_two(): assert 1
|
||||
def test_three(): assert 1
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest("-k=-test_two", threepass)
|
||||
result = pytester.runpytest("-k=-test_two", threepass)
|
||||
result.stdout.fnmatch_lines(["*The `-k '-expr'` syntax*deprecated*"])
|
||||
|
||||
|
||||
def test_minus_k_colon_is_deprecated(testdir) -> None:
|
||||
threepass = testdir.makepyfile(
|
||||
def test_minus_k_colon_is_deprecated(pytester: Pytester) -> None:
|
||||
threepass = pytester.makepyfile(
|
||||
test_threepass="""
|
||||
def test_one(): assert 1
|
||||
def test_two(): assert 1
|
||||
def test_three(): assert 1
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest("-k", "test_two:", threepass)
|
||||
result = pytester.runpytest("-k", "test_two:", threepass)
|
||||
result.stdout.fnmatch_lines(["*The `-k 'expr:'` syntax*deprecated*"])
|
||||
|
||||
|
||||
def test_fscollector_gethookproxy_isinitpath(testdir: Testdir) -> None:
|
||||
module = testdir.getmodulecol(
|
||||
def test_fscollector_gethookproxy_isinitpath(pytester: Pytester) -> None:
|
||||
module = pytester.getmodulecol(
|
||||
"""
|
||||
def test_foo(): pass
|
||||
""",
|
||||
|
@ -85,16 +84,16 @@ def test_fscollector_gethookproxy_isinitpath(testdir: Testdir) -> None:
|
|||
assert isinstance(package, pytest.Package)
|
||||
|
||||
with pytest.warns(pytest.PytestDeprecationWarning, match="gethookproxy"):
|
||||
package.gethookproxy(testdir.tmpdir)
|
||||
package.gethookproxy(pytester.path)
|
||||
|
||||
with pytest.warns(pytest.PytestDeprecationWarning, match="isinitpath"):
|
||||
package.isinitpath(testdir.tmpdir)
|
||||
package.isinitpath(pytester.path)
|
||||
|
||||
# The methods on Session are *not* deprecated.
|
||||
session = module.session
|
||||
with warnings.catch_warnings(record=True) as rec:
|
||||
session.gethookproxy(testdir.tmpdir)
|
||||
session.isinitpath(testdir.tmpdir)
|
||||
session.gethookproxy(pytester.path)
|
||||
session.isinitpath(pytester.path)
|
||||
assert len(rec) == 0
|
||||
|
||||
|
||||
|
|
|
@ -1050,7 +1050,7 @@ class TestLastFailed:
|
|||
|
||||
|
||||
class TestNewFirst:
|
||||
def test_newfirst_usecase(self, pytester: Pytester, testdir) -> None:
|
||||
def test_newfirst_usecase(self, pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
**{
|
||||
"test_1/test_1.py": """
|
||||
|
|
|
@ -6,6 +6,8 @@ import textwrap
|
|||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
import py.path
|
||||
|
||||
import pytest
|
||||
from _pytest.config import ExitCode
|
||||
from _pytest.fixtures import FixtureRequest
|
||||
|
@ -16,7 +18,6 @@ from _pytest.nodes import Item
|
|||
from _pytest.pathlib import symlink_or_skip
|
||||
from _pytest.pytester import HookRecorder
|
||||
from _pytest.pytester import Pytester
|
||||
from _pytest.pytester import Testdir
|
||||
|
||||
|
||||
def ensure_file(file_path: Path) -> Path:
|
||||
|
@ -206,15 +207,17 @@ class TestCollectFS:
|
|||
"Activate.ps1",
|
||||
),
|
||||
)
|
||||
def test__in_venv(self, testdir: Testdir, fname: str) -> None:
|
||||
def test__in_venv(self, pytester: Pytester, fname: str) -> None:
|
||||
"""Directly test the virtual env detection function"""
|
||||
bindir = "Scripts" if sys.platform.startswith("win") else "bin"
|
||||
# no bin/activate, not a virtualenv
|
||||
base_path = testdir.tmpdir.mkdir("venv")
|
||||
assert _in_venv(base_path) is False
|
||||
base_path = pytester.mkdir("venv")
|
||||
assert _in_venv(py.path.local(base_path)) is False
|
||||
# with bin/activate, totally a virtualenv
|
||||
base_path.ensure(bindir, fname)
|
||||
assert _in_venv(base_path) is True
|
||||
bin_path = base_path.joinpath(bindir)
|
||||
bin_path.mkdir()
|
||||
bin_path.joinpath(fname).touch()
|
||||
assert _in_venv(py.path.local(base_path)) is True
|
||||
|
||||
def test_custom_norecursedirs(self, pytester: Pytester) -> None:
|
||||
pytester.makeini(
|
||||
|
@ -264,7 +267,7 @@ class TestCollectFS:
|
|||
|
||||
|
||||
class TestCollectPluginHookRelay:
|
||||
def test_pytest_collect_file(self, testdir: Testdir) -> None:
|
||||
def test_pytest_collect_file(self, pytester: Pytester) -> None:
|
||||
wascalled = []
|
||||
|
||||
class Plugin:
|
||||
|
@ -273,8 +276,8 @@ class TestCollectPluginHookRelay:
|
|||
# Ignore hidden files, e.g. .testmondata.
|
||||
wascalled.append(path)
|
||||
|
||||
testdir.makefile(".abc", "xyz")
|
||||
pytest.main(testdir.tmpdir, plugins=[Plugin()])
|
||||
pytester.makefile(".abc", "xyz")
|
||||
pytest.main(py.path.local(pytester.path), plugins=[Plugin()])
|
||||
assert len(wascalled) == 1
|
||||
assert wascalled[0].ext == ".abc"
|
||||
|
||||
|
@ -1336,7 +1339,7 @@ def test_does_not_put_src_on_path(pytester: Pytester) -> None:
|
|||
assert result.ret == ExitCode.OK
|
||||
|
||||
|
||||
def test_fscollector_from_parent(testdir: Testdir, request: FixtureRequest) -> None:
|
||||
def test_fscollector_from_parent(pytester: Pytester, request: FixtureRequest) -> None:
|
||||
"""Ensure File.from_parent can forward custom arguments to the constructor.
|
||||
|
||||
Context: https://github.com/pytest-dev/pytest-cpp/pull/47
|
||||
|
@ -1352,7 +1355,7 @@ def test_fscollector_from_parent(testdir: Testdir, request: FixtureRequest) -> N
|
|||
return super().from_parent(parent=parent, fspath=fspath, x=x)
|
||||
|
||||
collector = MyCollector.from_parent(
|
||||
parent=request.session, fspath=testdir.tmpdir / "foo", x=10
|
||||
parent=request.session, fspath=py.path.local(pytester.path) / "foo", x=10
|
||||
)
|
||||
assert collector.x == 10
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ _ENVIRON_PYTHONBREAKPOINT = os.environ.get("PYTHONBREAKPOINT", "")
|
|||
def pdb_env(request):
|
||||
if "pytester" in request.fixturenames:
|
||||
# Disable pdb++ with inner tests.
|
||||
pytester = request.getfixturevalue("testdir")
|
||||
pytester.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):
|
||||
|
|
|
@ -4,51 +4,62 @@ from datetime import datetime
|
|||
from pathlib import Path
|
||||
from typing import cast
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import Union
|
||||
from xml.dom import minidom
|
||||
|
||||
import py
|
||||
import xmlschema
|
||||
|
||||
import pytest
|
||||
from _pytest.config import Config
|
||||
from _pytest.junitxml import bin_xml_escape
|
||||
from _pytest.junitxml import LogXML
|
||||
from _pytest.monkeypatch import MonkeyPatch
|
||||
from _pytest.pytester import Pytester
|
||||
from _pytest.pytester import RunResult
|
||||
from _pytest.reports import BaseReport
|
||||
from _pytest.reports import TestReport
|
||||
from _pytest.store import Store
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def schema():
|
||||
def schema() -> xmlschema.XMLSchema:
|
||||
"""Return an xmlschema.XMLSchema object for the junit-10.xsd file."""
|
||||
fn = Path(__file__).parent / "example_scripts/junit-10.xsd"
|
||||
with fn.open() as f:
|
||||
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(testdir, schema):
|
||||
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, family="xunit1"):
|
||||
if family:
|
||||
args = ("-o", "junit_family=" + family) + args
|
||||
xml_path = testdir.tmpdir.join("junit.xml")
|
||||
result = testdir.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 run
|
||||
return RunAndParse(pytester, schema)
|
||||
|
||||
|
||||
def assert_attr(node, **kwargs):
|
||||
|
@ -130,8 +141,10 @@ parametrize_families = pytest.mark.parametrize("xunit_family", ["xunit1", "xunit
|
|||
|
||||
class TestPython:
|
||||
@parametrize_families
|
||||
def test_summing_simple(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_summing_simple(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
def test_pass():
|
||||
|
@ -154,8 +167,10 @@ class TestPython:
|
|||
node.assert_attr(name="pytest", errors=0, failures=1, skipped=2, tests=5)
|
||||
|
||||
@parametrize_families
|
||||
def test_summing_simple_with_errors(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_summing_simple_with_errors(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
@pytest.fixture
|
||||
|
@ -181,8 +196,10 @@ class TestPython:
|
|||
node.assert_attr(name="pytest", errors=1, failures=2, skipped=1, tests=5)
|
||||
|
||||
@parametrize_families
|
||||
def test_hostname_in_xml(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_hostname_in_xml(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_pass():
|
||||
pass
|
||||
|
@ -193,8 +210,10 @@ class TestPython:
|
|||
node.assert_attr(hostname=platform.node())
|
||||
|
||||
@parametrize_families
|
||||
def test_timestamp_in_xml(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_timestamp_in_xml(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_pass():
|
||||
pass
|
||||
|
@ -206,8 +225,10 @@ class TestPython:
|
|||
timestamp = datetime.strptime(node["timestamp"], "%Y-%m-%dT%H:%M:%S.%f")
|
||||
assert start_time <= timestamp < datetime.now()
|
||||
|
||||
def test_timing_function(self, testdir, run_and_parse, mock_timing):
|
||||
testdir.makepyfile(
|
||||
def test_timing_function(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, mock_timing
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
from _pytest import timing
|
||||
def setup_module():
|
||||
|
@ -226,8 +247,12 @@ class TestPython:
|
|||
|
||||
@pytest.mark.parametrize("duration_report", ["call", "total"])
|
||||
def test_junit_duration_report(
|
||||
self, testdir, monkeypatch, duration_report, run_and_parse
|
||||
):
|
||||
self,
|
||||
pytester: Pytester,
|
||||
monkeypatch: MonkeyPatch,
|
||||
duration_report: str,
|
||||
run_and_parse: RunAndParse,
|
||||
) -> None:
|
||||
|
||||
# mock LogXML.node_reporter so it always sets a known duration to each test report object
|
||||
original_node_reporter = LogXML.node_reporter
|
||||
|
@ -239,7 +264,7 @@ class TestPython:
|
|||
|
||||
monkeypatch.setattr(LogXML, "node_reporter", node_reporter_wrapper)
|
||||
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_foo():
|
||||
pass
|
||||
|
@ -256,8 +281,10 @@ class TestPython:
|
|||
assert val == 1.0
|
||||
|
||||
@parametrize_families
|
||||
def test_setup_error(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_setup_error(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
@ -279,8 +306,10 @@ class TestPython:
|
|||
assert "ValueError" in fnode.toxml()
|
||||
|
||||
@parametrize_families
|
||||
def test_teardown_error(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_teardown_error(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
@ -302,8 +331,10 @@ class TestPython:
|
|||
assert "ValueError" in fnode.toxml()
|
||||
|
||||
@parametrize_families
|
||||
def test_call_failure_teardown_error(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_call_failure_teardown_error(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
@ -331,8 +362,10 @@ class TestPython:
|
|||
)
|
||||
|
||||
@parametrize_families
|
||||
def test_skip_contains_name_reason(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_skip_contains_name_reason(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
def test_skip():
|
||||
|
@ -349,8 +382,10 @@ class TestPython:
|
|||
snode.assert_attr(type="pytest.skip", message="hello23")
|
||||
|
||||
@parametrize_families
|
||||
def test_mark_skip_contains_name_reason(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_mark_skip_contains_name_reason(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
@pytest.mark.skip(reason="hello24")
|
||||
|
@ -371,9 +406,9 @@ class TestPython:
|
|||
|
||||
@parametrize_families
|
||||
def test_mark_skipif_contains_name_reason(
|
||||
self, testdir, run_and_parse, xunit_family
|
||||
):
|
||||
testdir.makepyfile(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
GLOBAL_CONDITION = True
|
||||
|
@ -395,9 +430,9 @@ class TestPython:
|
|||
|
||||
@parametrize_families
|
||||
def test_mark_skip_doesnt_capture_output(
|
||||
self, testdir, run_and_parse, xunit_family
|
||||
):
|
||||
testdir.makepyfile(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
@pytest.mark.skip(reason="foo")
|
||||
|
@ -411,8 +446,10 @@ class TestPython:
|
|||
assert "bar!" not in node_xml
|
||||
|
||||
@parametrize_families
|
||||
def test_classname_instance(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_classname_instance(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
class TestClass(object):
|
||||
def test_method(self):
|
||||
|
@ -429,9 +466,11 @@ class TestPython:
|
|||
)
|
||||
|
||||
@parametrize_families
|
||||
def test_classname_nested_dir(self, testdir, run_and_parse, xunit_family):
|
||||
p = testdir.tmpdir.ensure("sub", "test_hello.py")
|
||||
p.write("def test_func(): 0/0")
|
||||
def test_classname_nested_dir(
|
||||
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")
|
||||
result, dom = run_and_parse(family=xunit_family)
|
||||
assert result.ret
|
||||
node = dom.find_first_by_tag("testsuite")
|
||||
|
@ -440,9 +479,11 @@ class TestPython:
|
|||
tnode.assert_attr(classname="sub.test_hello", name="test_func")
|
||||
|
||||
@parametrize_families
|
||||
def test_internal_error(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makeconftest("def pytest_runtest_protocol(): 0 / 0")
|
||||
testdir.makepyfile("def test_function(): pass")
|
||||
def test_internal_error(
|
||||
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")
|
||||
result, dom = run_and_parse(family=xunit_family)
|
||||
assert result.ret
|
||||
node = dom.find_first_by_tag("testsuite")
|
||||
|
@ -458,9 +499,13 @@ class TestPython:
|
|||
)
|
||||
@parametrize_families
|
||||
def test_failure_function(
|
||||
self, testdir, junit_logging, run_and_parse, xunit_family
|
||||
):
|
||||
testdir.makepyfile(
|
||||
self,
|
||||
pytester: Pytester,
|
||||
junit_logging,
|
||||
run_and_parse: RunAndParse,
|
||||
xunit_family,
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import logging
|
||||
import sys
|
||||
|
@ -521,8 +566,10 @@ class TestPython:
|
|||
), "Found unexpected content: system-err"
|
||||
|
||||
@parametrize_families
|
||||
def test_failure_verbose_message(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_failure_verbose_message(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import sys
|
||||
def test_fail():
|
||||
|
@ -536,8 +583,10 @@ class TestPython:
|
|||
fnode.assert_attr(message="AssertionError: An error\nassert 0")
|
||||
|
||||
@parametrize_families
|
||||
def test_failure_escape(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_failure_escape(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
@pytest.mark.parametrize('arg1', "<&'", ids="<&'")
|
||||
|
@ -564,8 +613,10 @@ class TestPython:
|
|||
assert "%s\n" % char in text
|
||||
|
||||
@parametrize_families
|
||||
def test_junit_prefixing(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_junit_prefixing(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_func():
|
||||
assert 0
|
||||
|
@ -586,8 +637,10 @@ class TestPython:
|
|||
)
|
||||
|
||||
@parametrize_families
|
||||
def test_xfailure_function(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_xfailure_function(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
def test_xfail():
|
||||
|
@ -604,8 +657,10 @@ class TestPython:
|
|||
fnode.assert_attr(type="pytest.xfail", message="42")
|
||||
|
||||
@parametrize_families
|
||||
def test_xfailure_marker(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_xfailure_marker(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
@pytest.mark.xfail(reason="42")
|
||||
|
@ -625,8 +680,10 @@ class TestPython:
|
|||
@pytest.mark.parametrize(
|
||||
"junit_logging", ["no", "log", "system-out", "system-err", "out-err", "all"]
|
||||
)
|
||||
def test_xfail_captures_output_once(self, testdir, junit_logging, run_and_parse):
|
||||
testdir.makepyfile(
|
||||
def test_xfail_captures_output_once(
|
||||
self, pytester: Pytester, junit_logging: str, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import sys
|
||||
import pytest
|
||||
|
@ -652,8 +709,10 @@ class TestPython:
|
|||
assert len(tnode.find_by_tag("system-out")) == 0
|
||||
|
||||
@parametrize_families
|
||||
def test_xfailure_xpass(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_xfailure_xpass(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
@pytest.mark.xfail
|
||||
|
@ -669,8 +728,10 @@ class TestPython:
|
|||
tnode.assert_attr(classname="test_xfailure_xpass", name="test_xpass")
|
||||
|
||||
@parametrize_families
|
||||
def test_xfailure_xpass_strict(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_xfailure_xpass_strict(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
@pytest.mark.xfail(strict=True, reason="This needs to fail!")
|
||||
|
@ -688,8 +749,10 @@ class TestPython:
|
|||
fnode.assert_attr(message="[XPASS(strict)] This needs to fail!")
|
||||
|
||||
@parametrize_families
|
||||
def test_collect_error(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile("syntax error")
|
||||
def test_collect_error(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile("syntax error")
|
||||
result, dom = run_and_parse(family=xunit_family)
|
||||
assert result.ret
|
||||
node = dom.find_first_by_tag("testsuite")
|
||||
|
@ -699,9 +762,9 @@ class TestPython:
|
|||
fnode.assert_attr(message="collection failure")
|
||||
assert "SyntaxError" in fnode.toxml()
|
||||
|
||||
def test_unicode(self, testdir, run_and_parse):
|
||||
def test_unicode(self, pytester: Pytester, run_and_parse: RunAndParse) -> None:
|
||||
value = "hx\xc4\x85\xc4\x87\n"
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
"""\
|
||||
# coding: latin1
|
||||
def test_hello():
|
||||
|
@ -716,9 +779,11 @@ class TestPython:
|
|||
fnode = tnode.find_first_by_tag("failure")
|
||||
assert "hx" in fnode.toxml()
|
||||
|
||||
def test_assertion_binchars(self, testdir, run_and_parse):
|
||||
def test_assertion_binchars(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
"""This test did fail when the escaping wasn't strict."""
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
|
||||
M1 = '\x01\x02\x03\x04'
|
||||
|
@ -732,8 +797,10 @@ class TestPython:
|
|||
print(dom.toxml())
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-out"])
|
||||
def test_pass_captures_stdout(self, testdir, run_and_parse, junit_logging):
|
||||
testdir.makepyfile(
|
||||
def test_pass_captures_stdout(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, junit_logging: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_pass():
|
||||
print('hello-stdout')
|
||||
|
@ -753,8 +820,10 @@ class TestPython:
|
|||
), "'hello-stdout' should be in system-out"
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-err"])
|
||||
def test_pass_captures_stderr(self, testdir, run_and_parse, junit_logging):
|
||||
testdir.makepyfile(
|
||||
def test_pass_captures_stderr(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, junit_logging: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import sys
|
||||
def test_pass():
|
||||
|
@ -775,8 +844,10 @@ class TestPython:
|
|||
), "'hello-stderr' should be in system-err"
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-out"])
|
||||
def test_setup_error_captures_stdout(self, testdir, run_and_parse, junit_logging):
|
||||
testdir.makepyfile(
|
||||
def test_setup_error_captures_stdout(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, junit_logging: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
@ -802,8 +873,10 @@ class TestPython:
|
|||
), "'hello-stdout' should be in system-out"
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-err"])
|
||||
def test_setup_error_captures_stderr(self, testdir, run_and_parse, junit_logging):
|
||||
testdir.makepyfile(
|
||||
def test_setup_error_captures_stderr(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, junit_logging: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import sys
|
||||
import pytest
|
||||
|
@ -830,8 +903,10 @@ class TestPython:
|
|||
), "'hello-stderr' should be in system-err"
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-out"])
|
||||
def test_avoid_double_stdout(self, testdir, run_and_parse, junit_logging):
|
||||
testdir.makepyfile(
|
||||
def test_avoid_double_stdout(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, junit_logging: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import sys
|
||||
import pytest
|
||||
|
@ -858,7 +933,7 @@ class TestPython:
|
|||
assert "hello-stdout teardown" in systemout.toxml()
|
||||
|
||||
|
||||
def test_mangle_test_address():
|
||||
def test_mangle_test_address() -> None:
|
||||
from _pytest.junitxml import mangle_test_address
|
||||
|
||||
address = "::".join(["a/my.py.thing.py", "Class", "()", "method", "[a-1-::]"])
|
||||
|
@ -866,7 +941,7 @@ def test_mangle_test_address():
|
|||
assert newnames == ["a.my.py.thing", "Class", "method", "[a-1-::]"]
|
||||
|
||||
|
||||
def test_dont_configure_on_workers(tmpdir) -> None:
|
||||
def test_dont_configure_on_workers(tmp_path: Path) -> None:
|
||||
gotten: List[object] = []
|
||||
|
||||
class FakeConfig:
|
||||
|
@ -882,8 +957,8 @@ def test_dont_configure_on_workers(tmpdir) -> None:
|
|||
return "pytest"
|
||||
|
||||
junitprefix = None
|
||||
# XXX: shouldn't need tmpdir ?
|
||||
xmlpath = str(tmpdir.join("junix.xml"))
|
||||
# XXX: shouldn't need tmp_path ?
|
||||
xmlpath = str(tmp_path.joinpath("junix.xml"))
|
||||
register = gotten.append
|
||||
|
||||
fake_config = cast(Config, FakeConfig())
|
||||
|
@ -898,8 +973,10 @@ def test_dont_configure_on_workers(tmpdir) -> None:
|
|||
|
||||
class TestNonPython:
|
||||
@parametrize_families
|
||||
def test_summing_simple(self, testdir, run_and_parse, xunit_family):
|
||||
testdir.makeconftest(
|
||||
def test_summing_simple(
|
||||
self, pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makeconftest(
|
||||
"""
|
||||
import pytest
|
||||
def pytest_collect_file(path, parent):
|
||||
|
@ -912,7 +989,7 @@ class TestNonPython:
|
|||
return "custom item runtest failed"
|
||||
"""
|
||||
)
|
||||
testdir.tmpdir.join("myfile.xyz").write("hello")
|
||||
pytester.path.joinpath("myfile.xyz").write_text("hello")
|
||||
result, dom = run_and_parse(family=xunit_family)
|
||||
assert result.ret
|
||||
node = dom.find_first_by_tag("testsuite")
|
||||
|
@ -925,9 +1002,9 @@ class TestNonPython:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-out"])
|
||||
def test_nullbyte(testdir, junit_logging):
|
||||
def test_nullbyte(pytester: Pytester, junit_logging: str) -> None:
|
||||
# A null byte can not occur in XML (see section 2.2 of the spec)
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import sys
|
||||
def test_print_nullbyte():
|
||||
|
@ -936,9 +1013,9 @@ def test_nullbyte(testdir, junit_logging):
|
|||
assert False
|
||||
"""
|
||||
)
|
||||
xmlf = testdir.tmpdir.join("junit.xml")
|
||||
testdir.runpytest("--junitxml=%s" % xmlf, "-o", "junit_logging=%s" % junit_logging)
|
||||
text = xmlf.read()
|
||||
xmlf = pytester.path.joinpath("junit.xml")
|
||||
pytester.runpytest("--junitxml=%s" % xmlf, "-o", "junit_logging=%s" % junit_logging)
|
||||
text = xmlf.read_text()
|
||||
assert "\x00" not in text
|
||||
if junit_logging == "system-out":
|
||||
assert "#x00" in text
|
||||
|
@ -947,9 +1024,9 @@ def test_nullbyte(testdir, junit_logging):
|
|||
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-out"])
|
||||
def test_nullbyte_replace(testdir, junit_logging):
|
||||
def test_nullbyte_replace(pytester: Pytester, junit_logging: str) -> None:
|
||||
# Check if the null byte gets replaced
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import sys
|
||||
def test_print_nullbyte():
|
||||
|
@ -958,16 +1035,16 @@ def test_nullbyte_replace(testdir, junit_logging):
|
|||
assert False
|
||||
"""
|
||||
)
|
||||
xmlf = testdir.tmpdir.join("junit.xml")
|
||||
testdir.runpytest("--junitxml=%s" % xmlf, "-o", "junit_logging=%s" % junit_logging)
|
||||
text = xmlf.read()
|
||||
xmlf = pytester.path.joinpath("junit.xml")
|
||||
pytester.runpytest("--junitxml=%s" % xmlf, "-o", "junit_logging=%s" % junit_logging)
|
||||
text = xmlf.read_text()
|
||||
if junit_logging == "system-out":
|
||||
assert "#x0" in text
|
||||
if junit_logging == "no":
|
||||
assert "#x0" not in text
|
||||
|
||||
|
||||
def test_invalid_xml_escape():
|
||||
def test_invalid_xml_escape() -> None:
|
||||
# Test some more invalid xml chars, the full range should be
|
||||
# tested really but let's just test the edges of the ranges
|
||||
# instead.
|
||||
|
@ -1003,52 +1080,54 @@ def test_invalid_xml_escape():
|
|||
assert chr(i) == bin_xml_escape(chr(i))
|
||||
|
||||
|
||||
def test_logxml_path_expansion(tmpdir, monkeypatch):
|
||||
home_tilde = py.path.local(os.path.expanduser("~")).join("test.xml")
|
||||
xml_tilde = LogXML("~%stest.xml" % tmpdir.sep, None)
|
||||
assert xml_tilde.logfile == home_tilde
|
||||
def test_logxml_path_expansion(tmp_path: Path, monkeypatch: MonkeyPatch) -> None:
|
||||
home_tilde = Path(os.path.expanduser("~")).joinpath("test.xml")
|
||||
xml_tilde = LogXML(Path("~", "test.xml"), None)
|
||||
assert xml_tilde.logfile == str(home_tilde)
|
||||
|
||||
monkeypatch.setenv("HOME", str(tmpdir))
|
||||
monkeypatch.setenv("HOME", str(tmp_path))
|
||||
home_var = os.path.normpath(os.path.expandvars("$HOME/test.xml"))
|
||||
xml_var = LogXML("$HOME%stest.xml" % tmpdir.sep, None)
|
||||
assert xml_var.logfile == home_var
|
||||
xml_var = LogXML(Path("$HOME", "test.xml"), None)
|
||||
assert xml_var.logfile == str(home_var)
|
||||
|
||||
|
||||
def test_logxml_changingdir(testdir):
|
||||
testdir.makepyfile(
|
||||
def test_logxml_changingdir(pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_func():
|
||||
import os
|
||||
os.chdir("a")
|
||||
"""
|
||||
)
|
||||
testdir.tmpdir.mkdir("a")
|
||||
result = testdir.runpytest("--junitxml=a/x.xml")
|
||||
pytester.mkdir("a")
|
||||
result = pytester.runpytest("--junitxml=a/x.xml")
|
||||
assert result.ret == 0
|
||||
assert testdir.tmpdir.join("a/x.xml").check()
|
||||
assert pytester.path.joinpath("a/x.xml").exists()
|
||||
|
||||
|
||||
def test_logxml_makedir(testdir):
|
||||
def test_logxml_makedir(pytester: Pytester) -> None:
|
||||
"""--junitxml should automatically create directories for the xml file"""
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_pass():
|
||||
pass
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest("--junitxml=path/to/results.xml")
|
||||
result = pytester.runpytest("--junitxml=path/to/results.xml")
|
||||
assert result.ret == 0
|
||||
assert testdir.tmpdir.join("path/to/results.xml").check()
|
||||
assert pytester.path.joinpath("path/to/results.xml").exists()
|
||||
|
||||
|
||||
def test_logxml_check_isdir(testdir):
|
||||
def test_logxml_check_isdir(pytester: Pytester) -> None:
|
||||
"""Give an error if --junit-xml is a directory (#2089)"""
|
||||
result = testdir.runpytest("--junit-xml=.")
|
||||
result = pytester.runpytest("--junit-xml=.")
|
||||
result.stderr.fnmatch_lines(["*--junitxml must be a filename*"])
|
||||
|
||||
|
||||
def test_escaped_parametrized_names_xml(testdir, run_and_parse):
|
||||
testdir.makepyfile(
|
||||
def test_escaped_parametrized_names_xml(
|
||||
pytester: Pytester, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""\
|
||||
import pytest
|
||||
@pytest.mark.parametrize('char', ["\\x00"])
|
||||
|
@ -1062,8 +1141,10 @@ def test_escaped_parametrized_names_xml(testdir, run_and_parse):
|
|||
node.assert_attr(name="test_func[\\x00]")
|
||||
|
||||
|
||||
def test_double_colon_split_function_issue469(testdir, run_and_parse):
|
||||
testdir.makepyfile(
|
||||
def test_double_colon_split_function_issue469(
|
||||
pytester: Pytester, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
@pytest.mark.parametrize('param', ["double::colon"])
|
||||
|
@ -1078,8 +1159,10 @@ def test_double_colon_split_function_issue469(testdir, run_and_parse):
|
|||
node.assert_attr(name="test_func[double::colon]")
|
||||
|
||||
|
||||
def test_double_colon_split_method_issue469(testdir, run_and_parse):
|
||||
testdir.makepyfile(
|
||||
def test_double_colon_split_method_issue469(
|
||||
pytester: Pytester, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
class TestClass(object):
|
||||
|
@ -1095,8 +1178,8 @@ def test_double_colon_split_method_issue469(testdir, run_and_parse):
|
|||
node.assert_attr(name="test_func[double::colon]")
|
||||
|
||||
|
||||
def test_unicode_issue368(testdir) -> None:
|
||||
path = testdir.tmpdir.join("test.xml")
|
||||
def test_unicode_issue368(pytester: Pytester) -> None:
|
||||
path = pytester.path.joinpath("test.xml")
|
||||
log = LogXML(str(path), None)
|
||||
ustr = "ВНИ!"
|
||||
|
||||
|
@ -1125,8 +1208,8 @@ def test_unicode_issue368(testdir) -> None:
|
|||
log.pytest_sessionfinish()
|
||||
|
||||
|
||||
def test_record_property(testdir, run_and_parse):
|
||||
testdir.makepyfile(
|
||||
def test_record_property(pytester: Pytester, run_and_parse: RunAndParse) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
@ -1147,8 +1230,10 @@ def test_record_property(testdir, run_and_parse):
|
|||
result.stdout.fnmatch_lines(["*= 1 passed in *"])
|
||||
|
||||
|
||||
def test_record_property_same_name(testdir, run_and_parse):
|
||||
testdir.makepyfile(
|
||||
def test_record_property_same_name(
|
||||
pytester: Pytester, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_record_with_same_name(record_property):
|
||||
record_property("foo", "bar")
|
||||
|
@ -1165,8 +1250,10 @@ def test_record_property_same_name(testdir, run_and_parse):
|
|||
|
||||
|
||||
@pytest.mark.parametrize("fixture_name", ["record_property", "record_xml_attribute"])
|
||||
def test_record_fixtures_without_junitxml(testdir, fixture_name):
|
||||
testdir.makepyfile(
|
||||
def test_record_fixtures_without_junitxml(
|
||||
pytester: Pytester, fixture_name: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_record({fixture_name}):
|
||||
{fixture_name}("foo", "bar")
|
||||
|
@ -1174,19 +1261,19 @@ def test_record_fixtures_without_junitxml(testdir, fixture_name):
|
|||
fixture_name=fixture_name
|
||||
)
|
||||
)
|
||||
result = testdir.runpytest()
|
||||
result = pytester.runpytest()
|
||||
assert result.ret == 0
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("default")
|
||||
def test_record_attribute(testdir, run_and_parse):
|
||||
testdir.makeini(
|
||||
def test_record_attribute(pytester: Pytester, run_and_parse: RunAndParse) -> None:
|
||||
pytester.makeini(
|
||||
"""
|
||||
[pytest]
|
||||
junit_family = xunit1
|
||||
"""
|
||||
)
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
@ -1209,15 +1296,17 @@ def test_record_attribute(testdir, run_and_parse):
|
|||
|
||||
@pytest.mark.filterwarnings("default")
|
||||
@pytest.mark.parametrize("fixture_name", ["record_xml_attribute", "record_property"])
|
||||
def test_record_fixtures_xunit2(testdir, fixture_name, run_and_parse):
|
||||
def test_record_fixtures_xunit2(
|
||||
pytester: Pytester, fixture_name: str, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
"""Ensure record_xml_attribute and record_property drop values when outside of legacy family."""
|
||||
testdir.makeini(
|
||||
pytester.makeini(
|
||||
"""
|
||||
[pytest]
|
||||
junit_family = xunit2
|
||||
"""
|
||||
)
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
@ -1246,13 +1335,15 @@ def test_record_fixtures_xunit2(testdir, fixture_name, run_and_parse):
|
|||
result.stdout.fnmatch_lines(expected_lines)
|
||||
|
||||
|
||||
def test_random_report_log_xdist(testdir, monkeypatch, run_and_parse):
|
||||
def test_random_report_log_xdist(
|
||||
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
|
||||
to produce correct reports (#1064)."""
|
||||
pytest.importorskip("xdist")
|
||||
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest, time
|
||||
@pytest.mark.parametrize('i', list(range(30)))
|
||||
|
@ -1271,8 +1362,10 @@ def test_random_report_log_xdist(testdir, monkeypatch, run_and_parse):
|
|||
|
||||
|
||||
@parametrize_families
|
||||
def test_root_testsuites_tag(testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_root_testsuites_tag(
|
||||
pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_x():
|
||||
pass
|
||||
|
@ -1285,8 +1378,8 @@ def test_root_testsuites_tag(testdir, run_and_parse, xunit_family):
|
|||
assert suite_node.tag == "testsuite"
|
||||
|
||||
|
||||
def test_runs_twice(testdir, run_and_parse):
|
||||
f = testdir.makepyfile(
|
||||
def test_runs_twice(pytester: Pytester, run_and_parse: RunAndParse) -> None:
|
||||
f = pytester.makepyfile(
|
||||
"""
|
||||
def test_pass():
|
||||
pass
|
||||
|
@ -1299,10 +1392,12 @@ def test_runs_twice(testdir, run_and_parse):
|
|||
assert first == second
|
||||
|
||||
|
||||
def test_runs_twice_xdist(testdir, run_and_parse):
|
||||
def test_runs_twice_xdist(
|
||||
pytester: Pytester, monkeypatch: MonkeyPatch, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytest.importorskip("xdist")
|
||||
testdir.monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD")
|
||||
f = testdir.makepyfile(
|
||||
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD")
|
||||
f = pytester.makepyfile(
|
||||
"""
|
||||
def test_pass():
|
||||
pass
|
||||
|
@ -1315,9 +1410,9 @@ def test_runs_twice_xdist(testdir, run_and_parse):
|
|||
assert first == second
|
||||
|
||||
|
||||
def test_fancy_items_regression(testdir, run_and_parse):
|
||||
def test_fancy_items_regression(pytester: Pytester, run_and_parse: RunAndParse) -> None:
|
||||
# issue 1259
|
||||
testdir.makeconftest(
|
||||
pytester.makeconftest(
|
||||
"""
|
||||
import pytest
|
||||
class FunItem(pytest.Item):
|
||||
|
@ -1341,7 +1436,7 @@ def test_fancy_items_regression(testdir, run_and_parse):
|
|||
"""
|
||||
)
|
||||
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_pass():
|
||||
pass
|
||||
|
@ -1368,8 +1463,8 @@ def test_fancy_items_regression(testdir, run_and_parse):
|
|||
|
||||
|
||||
@parametrize_families
|
||||
def test_global_properties(testdir, xunit_family) -> None:
|
||||
path = testdir.tmpdir.join("test_global_properties.xml")
|
||||
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)
|
||||
|
||||
class Report(BaseReport):
|
||||
|
@ -1402,9 +1497,9 @@ def test_global_properties(testdir, xunit_family) -> None:
|
|||
assert actual == expected
|
||||
|
||||
|
||||
def test_url_property(testdir) -> None:
|
||||
def test_url_property(pytester: Pytester) -> None:
|
||||
test_url = "http://www.github.com/pytest-dev"
|
||||
path = testdir.tmpdir.join("test_url_property.xml")
|
||||
path = pytester.path.joinpath("test_url_property.xml")
|
||||
log = LogXML(str(path), None)
|
||||
|
||||
class Report(BaseReport):
|
||||
|
@ -1429,8 +1524,10 @@ def test_url_property(testdir) -> None:
|
|||
|
||||
|
||||
@parametrize_families
|
||||
def test_record_testsuite_property(testdir, run_and_parse, xunit_family):
|
||||
testdir.makepyfile(
|
||||
def test_record_testsuite_property(
|
||||
pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_func1(record_testsuite_property):
|
||||
record_testsuite_property("stats", "all good")
|
||||
|
@ -1449,27 +1546,29 @@ def test_record_testsuite_property(testdir, run_and_parse, xunit_family):
|
|||
p2_node.assert_attr(name="stats", value="10")
|
||||
|
||||
|
||||
def test_record_testsuite_property_junit_disabled(testdir):
|
||||
testdir.makepyfile(
|
||||
def test_record_testsuite_property_junit_disabled(pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_func1(record_testsuite_property):
|
||||
record_testsuite_property("stats", "all good")
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest()
|
||||
result = pytester.runpytest()
|
||||
assert result.ret == 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize("junit", [True, False])
|
||||
def test_record_testsuite_property_type_checking(testdir, junit):
|
||||
testdir.makepyfile(
|
||||
def test_record_testsuite_property_type_checking(
|
||||
pytester: Pytester, junit: bool
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_func1(record_testsuite_property):
|
||||
record_testsuite_property(1, 2)
|
||||
"""
|
||||
)
|
||||
args = ("--junitxml=tests.xml",) if junit else ()
|
||||
result = testdir.runpytest(*args)
|
||||
result = pytester.runpytest(*args)
|
||||
assert result.ret == 1
|
||||
result.stdout.fnmatch_lines(
|
||||
["*TypeError: name parameter needs to be a string, but int given"]
|
||||
|
@ -1478,9 +1577,11 @@ def test_record_testsuite_property_type_checking(testdir, junit):
|
|||
|
||||
@pytest.mark.parametrize("suite_name", ["my_suite", ""])
|
||||
@parametrize_families
|
||||
def test_set_suite_name(testdir, suite_name, run_and_parse, xunit_family):
|
||||
def test_set_suite_name(
|
||||
pytester: Pytester, suite_name: str, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
if suite_name:
|
||||
testdir.makeini(
|
||||
pytester.makeini(
|
||||
"""
|
||||
[pytest]
|
||||
junit_suite_name={suite_name}
|
||||
|
@ -1492,7 +1593,7 @@ def test_set_suite_name(testdir, suite_name, run_and_parse, xunit_family):
|
|||
expected = suite_name
|
||||
else:
|
||||
expected = "pytest"
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
@ -1506,8 +1607,10 @@ def test_set_suite_name(testdir, suite_name, run_and_parse, xunit_family):
|
|||
node.assert_attr(name=expected)
|
||||
|
||||
|
||||
def test_escaped_skipreason_issue3533(testdir, run_and_parse):
|
||||
testdir.makepyfile(
|
||||
def test_escaped_skipreason_issue3533(
|
||||
pytester: Pytester, run_and_parse: RunAndParse
|
||||
) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
@pytest.mark.skip(reason='1 <> 2')
|
||||
|
@ -1524,9 +1627,9 @@ def test_escaped_skipreason_issue3533(testdir, run_and_parse):
|
|||
|
||||
@parametrize_families
|
||||
def test_logging_passing_tests_disabled_does_not_log_test_output(
|
||||
testdir, run_and_parse, xunit_family
|
||||
):
|
||||
testdir.makeini(
|
||||
pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||
) -> None:
|
||||
pytester.makeini(
|
||||
"""
|
||||
[pytest]
|
||||
junit_log_passing_tests=False
|
||||
|
@ -1536,7 +1639,7 @@ def test_logging_passing_tests_disabled_does_not_log_test_output(
|
|||
family=xunit_family
|
||||
)
|
||||
)
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
import logging
|
||||
|
@ -1558,9 +1661,12 @@ 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(
|
||||
testdir, junit_logging, run_and_parse, xunit_family
|
||||
):
|
||||
testdir.makeini(
|
||||
pytester: Pytester,
|
||||
junit_logging: str,
|
||||
run_and_parse: RunAndParse,
|
||||
xunit_family: str,
|
||||
) -> None:
|
||||
pytester.makeini(
|
||||
"""
|
||||
[pytest]
|
||||
junit_log_passing_tests=False
|
||||
|
@ -1569,7 +1675,7 @@ def test_logging_passing_tests_disabled_logs_output_for_failing_test_issue5430(
|
|||
family=xunit_family
|
||||
)
|
||||
)
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
import logging
|
||||
|
|
|
@ -3,15 +3,14 @@ import subprocess
|
|||
import sys
|
||||
import textwrap
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
from string import ascii_lowercase
|
||||
|
||||
import py.path
|
||||
|
||||
from _pytest import pytester
|
||||
from _pytest.pytester import Pytester
|
||||
|
||||
|
||||
@contextmanager
|
||||
def subst_path_windows(filename):
|
||||
def subst_path_windows(filepath: Path):
|
||||
for c in ascii_lowercase[7:]: # Create a subst drive from H-Z.
|
||||
c += ":"
|
||||
if not os.path.exists(c):
|
||||
|
@ -20,14 +19,14 @@ def subst_path_windows(filename):
|
|||
else:
|
||||
raise AssertionError("Unable to find suitable drive letter for subst.")
|
||||
|
||||
directory = filename.dirpath()
|
||||
basename = filename.basename
|
||||
directory = filepath.parent
|
||||
basename = filepath.name
|
||||
|
||||
args = ["subst", drive, str(directory)]
|
||||
subprocess.check_call(args)
|
||||
assert os.path.exists(drive)
|
||||
try:
|
||||
filename = py.path.local(drive) / basename
|
||||
filename = Path(drive, os.sep, basename)
|
||||
yield filename
|
||||
finally:
|
||||
args = ["subst", "/D", drive]
|
||||
|
@ -35,9 +34,9 @@ def subst_path_windows(filename):
|
|||
|
||||
|
||||
@contextmanager
|
||||
def subst_path_linux(filename):
|
||||
directory = filename.dirpath()
|
||||
basename = filename.basename
|
||||
def subst_path_linux(filepath: Path):
|
||||
directory = filepath.parent
|
||||
basename = filepath.name
|
||||
|
||||
target = directory / ".." / "sub2"
|
||||
os.symlink(str(directory), str(target), target_is_directory=True)
|
||||
|
@ -49,11 +48,11 @@ def subst_path_linux(filename):
|
|||
pass
|
||||
|
||||
|
||||
def test_link_resolve(testdir: pytester.Testdir) -> None:
|
||||
def test_link_resolve(pytester: Pytester) -> None:
|
||||
"""See: https://github.com/pytest-dev/pytest/issues/5965."""
|
||||
sub1 = testdir.mkpydir("sub1")
|
||||
p = sub1.join("test_foo.py")
|
||||
p.write(
|
||||
sub1 = pytester.mkpydir("sub1")
|
||||
p = sub1.joinpath("test_foo.py")
|
||||
p.write_text(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
import pytest
|
||||
|
@ -68,7 +67,7 @@ def test_link_resolve(testdir: pytester.Testdir) -> None:
|
|||
subst = subst_path_windows
|
||||
|
||||
with subst(p) as subst_p:
|
||||
result = testdir.runpytest(str(subst_p), "-v")
|
||||
result = pytester.runpytest(str(subst_p), "-v")
|
||||
# i.e.: Make sure that the error is reported as a relative path, not as a
|
||||
# resolved path.
|
||||
# See: https://github.com/pytest-dev/pytest/issues/5965
|
||||
|
|
|
@ -10,7 +10,6 @@ from _pytest.config import UsageError
|
|||
from _pytest.main import resolve_collection_argument
|
||||
from _pytest.main import validate_basetemp
|
||||
from _pytest.pytester import Pytester
|
||||
from _pytest.pytester import Testdir
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -21,9 +20,9 @@ from _pytest.pytester import Testdir
|
|||
pytest.param((False, SystemExit)),
|
||||
),
|
||||
)
|
||||
def test_wrap_session_notify_exception(ret_exc, testdir):
|
||||
def test_wrap_session_notify_exception(ret_exc, pytester: Pytester) -> None:
|
||||
returncode, exc = ret_exc
|
||||
c1 = testdir.makeconftest(
|
||||
c1 = pytester.makeconftest(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
@ -38,7 +37,7 @@ def test_wrap_session_notify_exception(ret_exc, testdir):
|
|||
returncode=returncode, exc=exc.__name__
|
||||
)
|
||||
)
|
||||
result = testdir.runpytest()
|
||||
result = pytester.runpytest()
|
||||
if returncode:
|
||||
assert result.ret == returncode
|
||||
else:
|
||||
|
@ -65,9 +64,9 @@ def test_wrap_session_notify_exception(ret_exc, testdir):
|
|||
|
||||
@pytest.mark.parametrize("returncode", (None, 42))
|
||||
def test_wrap_session_exit_sessionfinish(
|
||||
returncode: Optional[int], testdir: Testdir
|
||||
returncode: Optional[int], pytester: Pytester
|
||||
) -> None:
|
||||
testdir.makeconftest(
|
||||
pytester.makeconftest(
|
||||
"""
|
||||
import pytest
|
||||
def pytest_sessionfinish():
|
||||
|
@ -76,7 +75,7 @@ def test_wrap_session_exit_sessionfinish(
|
|||
returncode=returncode
|
||||
)
|
||||
)
|
||||
result = testdir.runpytest()
|
||||
result = pytester.runpytest()
|
||||
if returncode:
|
||||
assert result.ret == returncode
|
||||
else:
|
||||
|
@ -101,8 +100,8 @@ def test_validate_basetemp_fails(tmp_path, basetemp, monkeypatch):
|
|||
validate_basetemp(basetemp)
|
||||
|
||||
|
||||
def test_validate_basetemp_integration(testdir):
|
||||
result = testdir.runpytest("--basetemp=.")
|
||||
def test_validate_basetemp_integration(pytester: Pytester) -> None:
|
||||
result = pytester.runpytest("--basetemp=.")
|
||||
result.stderr.fnmatch_lines("*basetemp must not be*")
|
||||
|
||||
|
||||
|
@ -203,14 +202,14 @@ class TestResolveCollectionArgument:
|
|||
) == (Path(os.path.abspath("src")), [])
|
||||
|
||||
|
||||
def test_module_full_path_without_drive(testdir):
|
||||
def test_module_full_path_without_drive(pytester: Pytester) -> None:
|
||||
"""Collect and run test using full path except for the drive letter (#7628).
|
||||
|
||||
Passing a full path without a drive letter would trigger a bug in py.path.local
|
||||
where it would keep the full path without the drive letter around, instead of resolving
|
||||
to the full path, resulting in fixtures node ids not matching against test node ids correctly.
|
||||
"""
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
**{
|
||||
"project/conftest.py": """
|
||||
import pytest
|
||||
|
@ -220,7 +219,7 @@ def test_module_full_path_without_drive(testdir):
|
|||
}
|
||||
)
|
||||
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
**{
|
||||
"project/tests/dummy_test.py": """
|
||||
def test(fix):
|
||||
|
@ -228,12 +227,12 @@ def test_module_full_path_without_drive(testdir):
|
|||
"""
|
||||
}
|
||||
)
|
||||
fn = testdir.tmpdir.join("project/tests/dummy_test.py")
|
||||
assert fn.isfile()
|
||||
fn = pytester.path.joinpath("project/tests/dummy_test.py")
|
||||
assert fn.is_file()
|
||||
|
||||
drive, path = os.path.splitdrive(str(fn))
|
||||
|
||||
result = testdir.runpytest(path, "-v")
|
||||
result = pytester.runpytest(path, "-v")
|
||||
result.stdout.fnmatch_lines(
|
||||
[
|
||||
os.path.join("project", "tests", "dummy_test.py") + "::test PASSED *",
|
||||
|
|
|
@ -315,7 +315,7 @@ def test_argcomplete(pytester: Pytester, monkeypatch: MonkeyPatch) -> None:
|
|||
shlex.quote(sys.executable)
|
||||
)
|
||||
)
|
||||
# alternative would be extended Testdir.{run(),_run(),popen()} to be able
|
||||
# alternative would be extended Pytester.{run(),_run(),popen()} to be able
|
||||
# to handle a keyword argument env that replaces os.environ in popen or
|
||||
# extends the copy, advantage: could not forget to restore
|
||||
monkeypatch.setenv("_ARGCOMPLETE", "1")
|
||||
|
|
|
@ -2,26 +2,26 @@ import os
|
|||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
from types import ModuleType
|
||||
from typing import List
|
||||
|
||||
import py.path
|
||||
|
||||
import _pytest.pytester as pytester
|
||||
import _pytest.pytester as pytester_mod
|
||||
import pytest
|
||||
from _pytest.config import ExitCode
|
||||
from _pytest.config import PytestPluginManager
|
||||
from _pytest.monkeypatch import MonkeyPatch
|
||||
from _pytest.pytester import CwdSnapshot
|
||||
from _pytest.pytester import HookRecorder
|
||||
from _pytest.pytester import LineMatcher
|
||||
from _pytest.pytester import Pytester
|
||||
from _pytest.pytester import SysModulesSnapshot
|
||||
from _pytest.pytester import SysPathsSnapshot
|
||||
from _pytest.pytester import Testdir
|
||||
|
||||
|
||||
def test_make_hook_recorder(testdir) -> None:
|
||||
item = testdir.getitem("def test_func(): pass")
|
||||
recorder = testdir.make_hook_recorder(item.config.pluginmanager)
|
||||
def test_make_hook_recorder(pytester: Pytester) -> None:
|
||||
item = pytester.getitem("def test_func(): pass")
|
||||
recorder = pytester.make_hook_recorder(item.config.pluginmanager)
|
||||
assert not recorder.getfailures()
|
||||
|
||||
# (The silly condition is to fool mypy that the code below this is reachable)
|
||||
|
@ -35,11 +35,11 @@ def test_make_hook_recorder(testdir) -> None:
|
|||
skipped = False
|
||||
when = "call"
|
||||
|
||||
recorder.hook.pytest_runtest_logreport(report=rep)
|
||||
recorder.hook.pytest_runtest_logreport(report=rep) # type: ignore[attr-defined]
|
||||
failures = recorder.getfailures()
|
||||
assert failures == [rep]
|
||||
assert failures == [rep] # type: ignore[comparison-overlap]
|
||||
failures = recorder.getfailures()
|
||||
assert failures == [rep]
|
||||
assert failures == [rep] # type: ignore[comparison-overlap]
|
||||
|
||||
class rep2:
|
||||
excinfo = None
|
||||
|
@ -50,14 +50,14 @@ def test_make_hook_recorder(testdir) -> None:
|
|||
|
||||
rep2.passed = False
|
||||
rep2.skipped = True
|
||||
recorder.hook.pytest_runtest_logreport(report=rep2)
|
||||
recorder.hook.pytest_runtest_logreport(report=rep2) # type: ignore[attr-defined]
|
||||
|
||||
modcol = testdir.getmodulecol("")
|
||||
modcol = pytester.getmodulecol("")
|
||||
rep3 = modcol.config.hook.pytest_make_collect_report(collector=modcol)
|
||||
rep3.passed = False
|
||||
rep3.failed = True
|
||||
rep3.skipped = False
|
||||
recorder.hook.pytest_collectreport(report=rep3)
|
||||
recorder.hook.pytest_collectreport(report=rep3) # type: ignore[attr-defined]
|
||||
|
||||
passed, skipped, failed = recorder.listoutcomes()
|
||||
assert not passed and skipped and failed
|
||||
|
@ -68,55 +68,55 @@ def test_make_hook_recorder(testdir) -> None:
|
|||
assert numfailed == 1
|
||||
assert len(recorder.getfailedcollections()) == 1
|
||||
|
||||
recorder.unregister()
|
||||
recorder.unregister() # type: ignore[attr-defined]
|
||||
recorder.clear()
|
||||
recorder.hook.pytest_runtest_logreport(report=rep3)
|
||||
recorder.hook.pytest_runtest_logreport(report=rep3) # type: ignore[attr-defined]
|
||||
pytest.raises(ValueError, recorder.getfailures)
|
||||
|
||||
|
||||
def test_parseconfig(testdir) -> None:
|
||||
config1 = testdir.parseconfig()
|
||||
config2 = testdir.parseconfig()
|
||||
def test_parseconfig(pytester: Pytester) -> None:
|
||||
config1 = pytester.parseconfig()
|
||||
config2 = pytester.parseconfig()
|
||||
assert config2 is not config1
|
||||
|
||||
|
||||
def test_testdir_runs_with_plugin(testdir) -> None:
|
||||
testdir.makepyfile(
|
||||
def test_pytester_runs_with_plugin(pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
pytest_plugins = "pytester"
|
||||
def test_hello(testdir):
|
||||
def test_hello(pytester):
|
||||
assert 1
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest()
|
||||
result = pytester.runpytest()
|
||||
result.assert_outcomes(passed=1)
|
||||
|
||||
|
||||
def test_testdir_with_doctest(testdir):
|
||||
"""Check that testdir can be used within doctests.
|
||||
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."""
|
||||
testdir.makepyfile(
|
||||
pytester.makepyfile(
|
||||
**{
|
||||
"sub/t-doctest.py": """
|
||||
'''
|
||||
>>> import os
|
||||
>>> testdir = getfixture("testdir")
|
||||
>>> str(testdir.makepyfile("content")).replace(os.sep, '/')
|
||||
>>> pytester = getfixture("pytester")
|
||||
>>> str(pytester.makepyfile("content")).replace(os.sep, '/')
|
||||
'.../basetemp/sub.t-doctest0/sub.py'
|
||||
'''
|
||||
""",
|
||||
"sub/__init__.py": "",
|
||||
}
|
||||
)
|
||||
result = testdir.runpytest(
|
||||
result = pytester.runpytest(
|
||||
"-p", "pytester", "--doctest-modules", "sub/t-doctest.py"
|
||||
)
|
||||
assert result.ret == 0
|
||||
|
||||
|
||||
def test_runresult_assertion_on_xfail(testdir) -> None:
|
||||
testdir.makepyfile(
|
||||
def test_runresult_assertion_on_xfail(pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
@ -127,13 +127,13 @@ def test_runresult_assertion_on_xfail(testdir) -> None:
|
|||
assert False
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest()
|
||||
result = pytester.runpytest()
|
||||
result.assert_outcomes(xfailed=1)
|
||||
assert result.ret == 0
|
||||
|
||||
|
||||
def test_runresult_assertion_on_xpassed(testdir) -> None:
|
||||
testdir.makepyfile(
|
||||
def test_runresult_assertion_on_xpassed(pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
@ -144,13 +144,13 @@ def test_runresult_assertion_on_xpassed(testdir) -> None:
|
|||
assert True
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest()
|
||||
result = pytester.runpytest()
|
||||
result.assert_outcomes(xpassed=1)
|
||||
assert result.ret == 0
|
||||
|
||||
|
||||
def test_xpassed_with_strict_is_considered_a_failure(testdir) -> None:
|
||||
testdir.makepyfile(
|
||||
def test_xpassed_with_strict_is_considered_a_failure(pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
@ -161,7 +161,7 @@ def test_xpassed_with_strict_is_considered_a_failure(testdir) -> None:
|
|||
assert True
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest()
|
||||
result = pytester.runpytest()
|
||||
result.assert_outcomes(failed=1)
|
||||
assert result.ret != 0
|
||||
|
||||
|
@ -202,28 +202,28 @@ def test_hookrecorder_basic(holder) -> None:
|
|||
assert call._name == "pytest_xyz_noarg"
|
||||
|
||||
|
||||
def test_makepyfile_unicode(testdir) -> None:
|
||||
testdir.makepyfile(chr(0xFFFD))
|
||||
def test_makepyfile_unicode(pytester: Pytester) -> None:
|
||||
pytester.makepyfile(chr(0xFFFD))
|
||||
|
||||
|
||||
def test_makepyfile_utf8(testdir) -> None:
|
||||
def test_makepyfile_utf8(pytester: Pytester) -> None:
|
||||
"""Ensure makepyfile accepts utf-8 bytes as input (#2738)"""
|
||||
utf8_contents = """
|
||||
def setup_function(function):
|
||||
mixed_encoding = 'São Paulo'
|
||||
""".encode()
|
||||
p = testdir.makepyfile(utf8_contents)
|
||||
assert "mixed_encoding = 'São Paulo'".encode() in p.read("rb")
|
||||
p = pytester.makepyfile(utf8_contents)
|
||||
assert "mixed_encoding = 'São Paulo'".encode() in p.read_bytes()
|
||||
|
||||
|
||||
class TestInlineRunModulesCleanup:
|
||||
def test_inline_run_test_module_not_cleaned_up(self, testdir) -> None:
|
||||
test_mod = testdir.makepyfile("def test_foo(): assert True")
|
||||
result = testdir.inline_run(str(test_mod))
|
||||
def test_inline_run_test_module_not_cleaned_up(self, pytester: Pytester) -> None:
|
||||
test_mod = pytester.makepyfile("def test_foo(): assert True")
|
||||
result = pytester.inline_run(str(test_mod))
|
||||
assert result.ret == ExitCode.OK
|
||||
# rewrite module, now test should fail if module was re-imported
|
||||
test_mod.write("def test_foo(): assert False")
|
||||
result2 = testdir.inline_run(str(test_mod))
|
||||
test_mod.write_text("def test_foo(): assert False")
|
||||
result2 = pytester.inline_run(str(test_mod))
|
||||
assert result2.ret == ExitCode.TESTS_FAILED
|
||||
|
||||
def spy_factory(self):
|
||||
|
@ -243,20 +243,20 @@ class TestInlineRunModulesCleanup:
|
|||
return SysModulesSnapshotSpy
|
||||
|
||||
def test_inline_run_taking_and_restoring_a_sys_modules_snapshot(
|
||||
self, testdir, monkeypatch
|
||||
self, pytester: Pytester, monkeypatch: MonkeyPatch
|
||||
) -> None:
|
||||
spy_factory = self.spy_factory()
|
||||
monkeypatch.setattr(pytester, "SysModulesSnapshot", spy_factory)
|
||||
testdir.syspathinsert()
|
||||
monkeypatch.setattr(pytester_mod, "SysModulesSnapshot", spy_factory)
|
||||
pytester.syspathinsert()
|
||||
original = dict(sys.modules)
|
||||
testdir.makepyfile(import1="# you son of a silly person")
|
||||
testdir.makepyfile(import2="# my hovercraft is full of eels")
|
||||
test_mod = testdir.makepyfile(
|
||||
pytester.makepyfile(import1="# you son of a silly person")
|
||||
pytester.makepyfile(import2="# my hovercraft is full of eels")
|
||||
test_mod = pytester.makepyfile(
|
||||
"""
|
||||
import import1
|
||||
def test_foo(): import import2"""
|
||||
)
|
||||
testdir.inline_run(str(test_mod))
|
||||
pytester.inline_run(str(test_mod))
|
||||
assert len(spy_factory.instances) == 1
|
||||
spy = spy_factory.instances[0]
|
||||
assert spy._spy_restore_count == 1
|
||||
|
@ -264,51 +264,52 @@ class TestInlineRunModulesCleanup:
|
|||
assert all(sys.modules[x] is original[x] for x in sys.modules)
|
||||
|
||||
def test_inline_run_sys_modules_snapshot_restore_preserving_modules(
|
||||
self, testdir, monkeypatch
|
||||
self, pytester: Pytester, monkeypatch: MonkeyPatch
|
||||
) -> None:
|
||||
spy_factory = self.spy_factory()
|
||||
monkeypatch.setattr(pytester, "SysModulesSnapshot", spy_factory)
|
||||
test_mod = testdir.makepyfile("def test_foo(): pass")
|
||||
testdir.inline_run(str(test_mod))
|
||||
monkeypatch.setattr(pytester_mod, "SysModulesSnapshot", spy_factory)
|
||||
test_mod = pytester.makepyfile("def test_foo(): pass")
|
||||
pytester.inline_run(str(test_mod))
|
||||
spy = spy_factory.instances[0]
|
||||
assert not spy._spy_preserve("black_knight")
|
||||
assert spy._spy_preserve("zope")
|
||||
assert spy._spy_preserve("zope.interface")
|
||||
assert spy._spy_preserve("zopelicious")
|
||||
|
||||
def test_external_test_module_imports_not_cleaned_up(self, testdir) -> None:
|
||||
testdir.syspathinsert()
|
||||
testdir.makepyfile(imported="data = 'you son of a silly person'")
|
||||
def test_external_test_module_imports_not_cleaned_up(
|
||||
self, pytester: Pytester
|
||||
) -> None:
|
||||
pytester.syspathinsert()
|
||||
pytester.makepyfile(imported="data = 'you son of a silly person'")
|
||||
import imported
|
||||
|
||||
test_mod = testdir.makepyfile(
|
||||
test_mod = pytester.makepyfile(
|
||||
"""
|
||||
def test_foo():
|
||||
import imported
|
||||
imported.data = 42"""
|
||||
)
|
||||
testdir.inline_run(str(test_mod))
|
||||
pytester.inline_run(str(test_mod))
|
||||
assert imported.data == 42
|
||||
|
||||
|
||||
def test_assert_outcomes_after_pytest_error(testdir) -> None:
|
||||
testdir.makepyfile("def test_foo(): assert True")
|
||||
def test_assert_outcomes_after_pytest_error(pytester: Pytester) -> None:
|
||||
pytester.makepyfile("def test_foo(): assert True")
|
||||
|
||||
result = testdir.runpytest("--unexpected-argument")
|
||||
result = pytester.runpytest("--unexpected-argument")
|
||||
with pytest.raises(ValueError, match="Pytest terminal summary report not found"):
|
||||
result.assert_outcomes(passed=0)
|
||||
|
||||
|
||||
def test_cwd_snapshot(testdir: Testdir) -> None:
|
||||
tmpdir = testdir.tmpdir
|
||||
foo = tmpdir.ensure("foo", dir=1)
|
||||
bar = tmpdir.ensure("bar", dir=1)
|
||||
foo.chdir()
|
||||
def test_cwd_snapshot(pytester: Pytester) -> None:
|
||||
foo = pytester.mkdir("foo")
|
||||
bar = pytester.mkdir("bar")
|
||||
os.chdir(foo)
|
||||
snapshot = CwdSnapshot()
|
||||
bar.chdir()
|
||||
assert py.path.local() == bar
|
||||
os.chdir(bar)
|
||||
assert Path().absolute() == bar
|
||||
snapshot.restore()
|
||||
assert py.path.local() == foo
|
||||
assert Path().absolute() == foo
|
||||
|
||||
|
||||
class TestSysModulesSnapshot:
|
||||
|
@ -318,14 +319,14 @@ class TestSysModulesSnapshot:
|
|||
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) -> None:
|
||||
def test_add_removed(self, monkeypatch: MonkeyPatch) -> None:
|
||||
assert self.key not in sys.modules
|
||||
monkeypatch.setitem(sys.modules, self.key, "something")
|
||||
monkeypatch.setitem(sys.modules, self.key, ModuleType("something"))
|
||||
assert self.key in sys.modules
|
||||
original = dict(sys.modules)
|
||||
snapshot = SysModulesSnapshot()
|
||||
|
@ -334,38 +335,39 @@ class TestSysModulesSnapshot:
|
|||
snapshot.restore()
|
||||
assert sys.modules == original
|
||||
|
||||
def test_restore_reloaded(self, monkeypatch) -> None:
|
||||
def test_restore_reloaded(self, monkeypatch: MonkeyPatch) -> None:
|
||||
assert self.key not in sys.modules
|
||||
monkeypatch.setitem(sys.modules, self.key, "something")
|
||||
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
|
||||
|
||||
def test_preserve_modules(self, monkeypatch) -> None:
|
||||
def test_preserve_modules(self, monkeypatch: MonkeyPatch) -> None:
|
||||
key = [self.key + str(i) for i in range(3)]
|
||||
assert not any(k in sys.modules for k in key)
|
||||
for i, k in enumerate(key):
|
||||
monkeypatch.setitem(sys.modules, k, "something" + str(i))
|
||||
mod = ModuleType("something" + str(i))
|
||||
monkeypatch.setitem(sys.modules, k, mod)
|
||||
original = dict(sys.modules)
|
||||
|
||||
def preserve(name):
|
||||
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
|
||||
|
||||
def test_preserve_container(self, monkeypatch) -> None:
|
||||
def test_preserve_container(self, monkeypatch: MonkeyPatch) -> None:
|
||||
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()
|
||||
|
@ -381,7 +383,7 @@ class TestSysPathsSnapshot:
|
|||
def path(n: int) -> str:
|
||||
return "my-dirty-little-secret-" + str(n)
|
||||
|
||||
def test_restore(self, monkeypatch, path_type) -> None:
|
||||
def test_restore(self, monkeypatch: MonkeyPatch, path_type) -> None:
|
||||
other_path_type = self.other_path[path_type]
|
||||
for i in range(10):
|
||||
assert self.path(i) not in getattr(sys, path_type)
|
||||
|
@ -404,7 +406,7 @@ class TestSysPathsSnapshot:
|
|||
assert getattr(sys, path_type) == original
|
||||
assert getattr(sys, other_path_type) == original_other
|
||||
|
||||
def test_preserve_container(self, monkeypatch, path_type) -> None:
|
||||
def test_preserve_container(self, monkeypatch: MonkeyPatch, path_type) -> None:
|
||||
other_path_type = self.other_path[path_type]
|
||||
original_data = list(getattr(sys, path_type))
|
||||
original_other = getattr(sys, other_path_type)
|
||||
|
@ -419,49 +421,49 @@ class TestSysPathsSnapshot:
|
|||
assert getattr(sys, other_path_type) == original_other_data
|
||||
|
||||
|
||||
def test_testdir_subprocess(testdir) -> None:
|
||||
testfile = testdir.makepyfile("def test_one(): pass")
|
||||
assert testdir.runpytest_subprocess(testfile).ret == 0
|
||||
def test_pytester_subprocess(pytester: Pytester) -> None:
|
||||
testfile = pytester.makepyfile("def test_one(): pass")
|
||||
assert pytester.runpytest_subprocess(testfile).ret == 0
|
||||
|
||||
|
||||
def test_testdir_subprocess_via_runpytest_arg(testdir) -> None:
|
||||
testfile = testdir.makepyfile(
|
||||
def test_pytester_subprocess_via_runpytest_arg(pytester: Pytester) -> None:
|
||||
testfile = pytester.makepyfile(
|
||||
"""
|
||||
def test_testdir_subprocess(testdir):
|
||||
def test_pytester_subprocess(pytester):
|
||||
import os
|
||||
testfile = testdir.makepyfile(
|
||||
testfile = pytester.makepyfile(
|
||||
\"""
|
||||
import os
|
||||
def test_one():
|
||||
assert {} != os.getpid()
|
||||
\""".format(os.getpid())
|
||||
)
|
||||
assert testdir.runpytest(testfile).ret == 0
|
||||
assert pytester.runpytest(testfile).ret == 0
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest_subprocess(
|
||||
result = pytester.runpytest_inprocess(
|
||||
"-p", "pytester", "--runpytest", "subprocess", testfile
|
||||
)
|
||||
assert result.ret == 0
|
||||
|
||||
|
||||
def test_unicode_args(testdir) -> None:
|
||||
result = testdir.runpytest("-k", "אבג")
|
||||
def test_unicode_args(pytester: Pytester) -> None:
|
||||
result = pytester.runpytest("-k", "אבג")
|
||||
assert result.ret == ExitCode.NO_TESTS_COLLECTED
|
||||
|
||||
|
||||
def test_testdir_run_no_timeout(testdir) -> None:
|
||||
testfile = testdir.makepyfile("def test_no_timeout(): pass")
|
||||
assert testdir.runpytest_subprocess(testfile).ret == ExitCode.OK
|
||||
def test_pytester_run_no_timeout(pytester: Pytester) -> None:
|
||||
testfile = pytester.makepyfile("def test_no_timeout(): pass")
|
||||
assert pytester.runpytest_subprocess(testfile).ret == ExitCode.OK
|
||||
|
||||
|
||||
def test_testdir_run_with_timeout(testdir) -> None:
|
||||
testfile = testdir.makepyfile("def test_no_timeout(): pass")
|
||||
def test_pytester_run_with_timeout(pytester: Pytester) -> None:
|
||||
testfile = pytester.makepyfile("def test_no_timeout(): pass")
|
||||
|
||||
timeout = 120
|
||||
|
||||
start = time.time()
|
||||
result = testdir.runpytest_subprocess(testfile, timeout=timeout)
|
||||
result = pytester.runpytest_subprocess(testfile, timeout=timeout)
|
||||
end = time.time()
|
||||
duration = end - start
|
||||
|
||||
|
@ -469,16 +471,16 @@ def test_testdir_run_with_timeout(testdir) -> None:
|
|||
assert duration < timeout
|
||||
|
||||
|
||||
def test_testdir_run_timeout_expires(testdir) -> None:
|
||||
testfile = testdir.makepyfile(
|
||||
def test_pytester_run_timeout_expires(pytester: Pytester) -> None:
|
||||
testfile = pytester.makepyfile(
|
||||
"""
|
||||
import time
|
||||
|
||||
def test_timeout():
|
||||
time.sleep(10)"""
|
||||
)
|
||||
with pytest.raises(testdir.TimeoutExpired):
|
||||
testdir.runpytest_subprocess(testfile, timeout=1)
|
||||
with pytest.raises(pytester.TimeoutExpired):
|
||||
pytester.runpytest_subprocess(testfile, timeout=1)
|
||||
|
||||
|
||||
def test_linematcher_with_nonlist() -> None:
|
||||
|
@ -533,7 +535,7 @@ def test_linematcher_match_failure() -> None:
|
|||
]
|
||||
|
||||
|
||||
def test_linematcher_consecutive():
|
||||
def test_linematcher_consecutive() -> None:
|
||||
lm = LineMatcher(["1", "", "2"])
|
||||
with pytest.raises(pytest.fail.Exception) as excinfo:
|
||||
lm.fnmatch_lines(["1", "2"], consecutive=True)
|
||||
|
@ -554,7 +556,7 @@ def test_linematcher_consecutive():
|
|||
|
||||
|
||||
@pytest.mark.parametrize("function", ["no_fnmatch_line", "no_re_match_line"])
|
||||
def test_linematcher_no_matching(function) -> None:
|
||||
def test_linematcher_no_matching(function: str) -> None:
|
||||
if function == "no_fnmatch_line":
|
||||
good_pattern = "*.py OK*"
|
||||
bad_pattern = "*X.py OK*"
|
||||
|
@ -615,7 +617,7 @@ def test_linematcher_string_api() -> None:
|
|||
assert str(lm) == "foo\nbar"
|
||||
|
||||
|
||||
def test_pytester_addopts_before_testdir(request, monkeypatch) -> None:
|
||||
def test_pytester_addopts_before_testdir(request, monkeypatch: MonkeyPatch) -> None:
|
||||
orig = os.environ.get("PYTEST_ADDOPTS", None)
|
||||
monkeypatch.setenv("PYTEST_ADDOPTS", "--orig-unused")
|
||||
testdir = request.getfixturevalue("testdir")
|
||||
|
@ -626,9 +628,9 @@ def test_pytester_addopts_before_testdir(request, monkeypatch) -> None:
|
|||
assert os.environ.get("PYTEST_ADDOPTS") == orig
|
||||
|
||||
|
||||
def test_run_stdin(testdir) -> None:
|
||||
with pytest.raises(testdir.TimeoutExpired):
|
||||
testdir.run(
|
||||
def test_run_stdin(pytester: Pytester) -> None:
|
||||
with pytest.raises(pytester.TimeoutExpired):
|
||||
pytester.run(
|
||||
sys.executable,
|
||||
"-c",
|
||||
"import sys, time; time.sleep(1); print(sys.stdin.read())",
|
||||
|
@ -636,8 +638,8 @@ def test_run_stdin(testdir) -> None:
|
|||
timeout=0.1,
|
||||
)
|
||||
|
||||
with pytest.raises(testdir.TimeoutExpired):
|
||||
result = testdir.run(
|
||||
with pytest.raises(pytester.TimeoutExpired):
|
||||
result = pytester.run(
|
||||
sys.executable,
|
||||
"-c",
|
||||
"import sys, time; time.sleep(1); print(sys.stdin.read())",
|
||||
|
@ -645,7 +647,7 @@ def test_run_stdin(testdir) -> None:
|
|||
timeout=0.1,
|
||||
)
|
||||
|
||||
result = testdir.run(
|
||||
result = pytester.run(
|
||||
sys.executable,
|
||||
"-c",
|
||||
"import sys; print(sys.stdin.read())",
|
||||
|
@ -656,8 +658,8 @@ def test_run_stdin(testdir) -> None:
|
|||
assert result.ret == 0
|
||||
|
||||
|
||||
def test_popen_stdin_pipe(testdir) -> None:
|
||||
proc = testdir.popen(
|
||||
def test_popen_stdin_pipe(pytester: Pytester) -> None:
|
||||
proc = pytester.popen(
|
||||
[sys.executable, "-c", "import sys; print(sys.stdin.read())"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
|
@ -670,8 +672,8 @@ def test_popen_stdin_pipe(testdir) -> None:
|
|||
assert proc.returncode == 0
|
||||
|
||||
|
||||
def test_popen_stdin_bytes(testdir) -> None:
|
||||
proc = testdir.popen(
|
||||
def test_popen_stdin_bytes(pytester: Pytester) -> None:
|
||||
proc = pytester.popen(
|
||||
[sys.executable, "-c", "import sys; print(sys.stdin.read())"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
|
@ -683,18 +685,18 @@ def test_popen_stdin_bytes(testdir) -> None:
|
|||
assert proc.returncode == 0
|
||||
|
||||
|
||||
def test_popen_default_stdin_stderr_and_stdin_None(testdir) -> None:
|
||||
def test_popen_default_stdin_stderr_and_stdin_None(pytester: Pytester) -> None:
|
||||
# stdout, stderr default to pipes,
|
||||
# stdin can be None to not close the pipe, avoiding
|
||||
# "ValueError: flush of closed file" with `communicate()`.
|
||||
#
|
||||
# Wraps the test to make it not hang when run with "-s".
|
||||
p1 = testdir.makepyfile(
|
||||
p1 = pytester.makepyfile(
|
||||
'''
|
||||
import sys
|
||||
|
||||
def test_inner(testdir):
|
||||
p1 = testdir.makepyfile(
|
||||
def test_inner(pytester):
|
||||
p1 = pytester.makepyfile(
|
||||
"""
|
||||
import sys
|
||||
print(sys.stdin.read()) # empty
|
||||
|
@ -702,14 +704,14 @@ def test_popen_default_stdin_stderr_and_stdin_None(testdir) -> None:
|
|||
sys.stderr.write('stderr')
|
||||
"""
|
||||
)
|
||||
proc = testdir.popen([sys.executable, str(p1)], stdin=None)
|
||||
proc = pytester.popen([sys.executable, str(p1)], stdin=None)
|
||||
stdout, stderr = proc.communicate(b"ignored")
|
||||
assert stdout.splitlines() == [b"", b"stdout"]
|
||||
assert stderr.splitlines() == [b"stderr"]
|
||||
assert proc.returncode == 0
|
||||
'''
|
||||
)
|
||||
result = testdir.runpytest("-p", "pytester", str(p1))
|
||||
result = pytester.runpytest("-p", "pytester", str(p1))
|
||||
assert result.ret == 0
|
||||
|
||||
|
||||
|
@ -740,22 +742,22 @@ def test_run_result_repr() -> None:
|
|||
errlines = ["some", "nasty", "errors", "happened"]
|
||||
|
||||
# known exit code
|
||||
r = pytester.RunResult(1, outlines, errlines, duration=0.5)
|
||||
r = pytester_mod.RunResult(1, outlines, errlines, duration=0.5)
|
||||
assert (
|
||||
repr(r) == "<RunResult ret=ExitCode.TESTS_FAILED len(stdout.lines)=3"
|
||||
" len(stderr.lines)=4 duration=0.50s>"
|
||||
)
|
||||
|
||||
# unknown exit code: just the number
|
||||
r = pytester.RunResult(99, outlines, errlines, duration=0.5)
|
||||
r = pytester_mod.RunResult(99, outlines, errlines, duration=0.5)
|
||||
assert (
|
||||
repr(r) == "<RunResult ret=99 len(stdout.lines)=3"
|
||||
" len(stderr.lines)=4 duration=0.50s>"
|
||||
)
|
||||
|
||||
|
||||
def test_testdir_outcomes_with_multiple_errors(testdir):
|
||||
p1 = testdir.makepyfile(
|
||||
def test_pytester_outcomes_with_multiple_errors(pytester: Pytester) -> None:
|
||||
p1 = pytester.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
@ -770,13 +772,13 @@ def test_testdir_outcomes_with_multiple_errors(testdir):
|
|||
pass
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest(str(p1))
|
||||
result = pytester.runpytest(str(p1))
|
||||
result.assert_outcomes(errors=2)
|
||||
|
||||
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",
|
||||
|
@ -784,7 +786,7 @@ def test_parse_summary_line_always_plural():
|
|||
"======= 1 failed, 1 passed, 1 warning, 1 error in 0.13s ====",
|
||||
"done.",
|
||||
]
|
||||
assert pytester.RunResult.parse_summary_nouns(lines) == {
|
||||
assert pytester_mod.RunResult.parse_summary_nouns(lines) == {
|
||||
"errors": 1,
|
||||
"failed": 1,
|
||||
"passed": 1,
|
||||
|
@ -797,7 +799,7 @@ def test_parse_summary_line_always_plural():
|
|||
"======= 1 failed, 1 passed, 2 warnings, 2 errors in 0.13s ====",
|
||||
"done.",
|
||||
]
|
||||
assert pytester.RunResult.parse_summary_nouns(lines) == {
|
||||
assert pytester_mod.RunResult.parse_summary_nouns(lines) == {
|
||||
"errors": 2,
|
||||
"failed": 1,
|
||||
"passed": 1,
|
||||
|
@ -805,12 +807,12 @@ def test_parse_summary_line_always_plural():
|
|||
}
|
||||
|
||||
|
||||
def test_makefile_joins_absolute_path(testdir: Testdir) -> None:
|
||||
absfile = testdir.tmpdir / "absfile"
|
||||
p1 = testdir.makepyfile(**{str(absfile): ""})
|
||||
assert str(p1) == str(testdir.tmpdir / "absfile.py")
|
||||
def test_makefile_joins_absolute_path(pytester: Pytester) -> None:
|
||||
absfile = pytester.path / "absfile"
|
||||
p1 = pytester.makepyfile(**{str(absfile): ""})
|
||||
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)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue