summaryrefslogtreecommitdiff
path: root/testing
diff options
context:
space:
mode:
authorAnton <44246099+antonblr@users.noreply.github.com>2020-12-08 12:20:02 -0800
committerGitHub <noreply@github.com>2020-12-08 22:20:02 +0200
commit810b878ef8eac6f39cfff35705a6a10083ace0bc (patch)
treedad0171e466d9883ed4d7e9f629bcc353d33edaa /testing
parent059f6ff31588dd574d6fb6af419773a1c9979070 (diff)
downloadpytest-810b878ef8eac6f39cfff35705a6a10083ace0bc.tar.gz
Migrate to pytester: test_capture.py, test_terminal.py, approx.py (#8108)
* Migrate to pytester: test_capture.py, test_config.py, approx.py * migrate test_terminal.py * revert test_config.py * more typing in test_terminal.py * try-out 'tr' fixture update * revert 'tr' fixture, update test_config.py
Diffstat (limited to 'testing')
-rw-r--r--testing/python/approx.py7
-rw-r--r--testing/test_capture.py388
-rw-r--r--testing/test_config.py654
-rw-r--r--testing/test_terminal.py701
4 files changed, 928 insertions, 822 deletions
diff --git a/testing/python/approx.py b/testing/python/approx.py
index b37c9f757..91c1f3f85 100644
--- a/testing/python/approx.py
+++ b/testing/python/approx.py
@@ -7,6 +7,7 @@ from operator import ne
from typing import Optional
import pytest
+from _pytest.pytester import Pytester
from pytest import approx
inf, nan = float("inf"), float("nan")
@@ -456,12 +457,12 @@ class TestApprox:
)
mocked_doctest_runner.run(test)
- def test_unicode_plus_minus(self, testdir):
+ def test_unicode_plus_minus(self, pytester: Pytester) -> None:
"""
Comparing approx instances inside lists should not produce an error in the detailed diff.
Integration test for issue #2111.
"""
- testdir.makepyfile(
+ pytester.makepyfile(
"""
import pytest
def test_foo():
@@ -469,7 +470,7 @@ class TestApprox:
"""
)
expected = "4.0e-06"
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(
[f"*At index 0 diff: 3 != 4 ± {expected}", "=* 1 failed in *="]
)
diff --git a/testing/test_capture.py b/testing/test_capture.py
index e6bbc9a5d..3a5c617fe 100644
--- a/testing/test_capture.py
+++ b/testing/test_capture.py
@@ -13,11 +13,13 @@ from typing import TextIO
import pytest
from _pytest import capture
from _pytest.capture import _get_multicapture
+from _pytest.capture import CaptureFixture
from _pytest.capture import CaptureManager
from _pytest.capture import CaptureResult
from _pytest.capture import MultiCapture
from _pytest.config import ExitCode
-from _pytest.pytester import Testdir
+from _pytest.monkeypatch import MonkeyPatch
+from _pytest.pytester import Pytester
# note: py.io capture tests where copied from
# pylib 1.4.20.dev2 (rev 13d9af95547e)
@@ -55,7 +57,7 @@ def TeeStdCapture(
class TestCaptureManager:
@pytest.mark.parametrize("method", ["no", "sys", "fd"])
- def test_capturing_basic_api(self, method):
+ def test_capturing_basic_api(self, method) -> None:
capouter = StdCaptureFD()
old = sys.stdout, sys.stderr, sys.stdin
try:
@@ -96,9 +98,9 @@ class TestCaptureManager:
@pytest.mark.parametrize("method", ["fd", "sys"])
-def test_capturing_unicode(testdir, method):
+def test_capturing_unicode(pytester: Pytester, method: str) -> None:
obj = "'b\u00f6y'"
- testdir.makepyfile(
+ pytester.makepyfile(
"""\
# taken from issue 227 from nosetests
def test_unicode():
@@ -108,24 +110,24 @@ def test_capturing_unicode(testdir, method):
"""
% obj
)
- result = testdir.runpytest("--capture=%s" % method)
+ result = pytester.runpytest("--capture=%s" % method)
result.stdout.fnmatch_lines(["*1 passed*"])
@pytest.mark.parametrize("method", ["fd", "sys"])
-def test_capturing_bytes_in_utf8_encoding(testdir, method):
- testdir.makepyfile(
+def test_capturing_bytes_in_utf8_encoding(pytester: Pytester, method: str) -> None:
+ pytester.makepyfile(
"""\
def test_unicode():
print('b\\u00f6y')
"""
)
- result = testdir.runpytest("--capture=%s" % method)
+ result = pytester.runpytest("--capture=%s" % method)
result.stdout.fnmatch_lines(["*1 passed*"])
-def test_collect_capturing(testdir):
- p = testdir.makepyfile(
+def test_collect_capturing(pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""
import sys
@@ -134,7 +136,7 @@ def test_collect_capturing(testdir):
import xyz42123
"""
)
- result = testdir.runpytest(p)
+ result = pytester.runpytest(p)
result.stdout.fnmatch_lines(
[
"*Captured stdout*",
@@ -146,8 +148,8 @@ def test_collect_capturing(testdir):
class TestPerTestCapturing:
- def test_capture_and_fixtures(self, testdir):
- p = testdir.makepyfile(
+ def test_capture_and_fixtures(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""
def setup_module(mod):
print("setup module")
@@ -161,7 +163,7 @@ class TestPerTestCapturing:
assert 0
"""
)
- result = testdir.runpytest(p)
+ result = pytester.runpytest(p)
result.stdout.fnmatch_lines(
[
"setup module*",
@@ -173,8 +175,8 @@ class TestPerTestCapturing:
)
@pytest.mark.xfail(reason="unimplemented feature")
- def test_capture_scope_cache(self, testdir):
- p = testdir.makepyfile(
+ def test_capture_scope_cache(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""
import sys
def setup_module(func):
@@ -188,7 +190,7 @@ class TestPerTestCapturing:
print("in teardown")
"""
)
- result = testdir.runpytest(p)
+ result = pytester.runpytest(p)
result.stdout.fnmatch_lines(
[
"*test_func():*",
@@ -200,8 +202,8 @@ class TestPerTestCapturing:
]
)
- def test_no_carry_over(self, testdir):
- p = testdir.makepyfile(
+ def test_no_carry_over(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""
def test_func1():
print("in func1")
@@ -210,13 +212,13 @@ class TestPerTestCapturing:
assert 0
"""
)
- result = testdir.runpytest(p)
+ result = pytester.runpytest(p)
s = result.stdout.str()
assert "in func1" not in s
assert "in func2" in s
- def test_teardown_capturing(self, testdir):
- p = testdir.makepyfile(
+ def test_teardown_capturing(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""
def setup_function(function):
print("setup func1")
@@ -228,7 +230,7 @@ class TestPerTestCapturing:
pass
"""
)
- result = testdir.runpytest(p)
+ result = pytester.runpytest(p)
result.stdout.fnmatch_lines(
[
"*teardown_function*",
@@ -240,8 +242,8 @@ class TestPerTestCapturing:
]
)
- def test_teardown_capturing_final(self, testdir):
- p = testdir.makepyfile(
+ def test_teardown_capturing_final(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""
def teardown_module(mod):
print("teardown module")
@@ -250,7 +252,7 @@ class TestPerTestCapturing:
pass
"""
)
- result = testdir.runpytest(p)
+ result = pytester.runpytest(p)
result.stdout.fnmatch_lines(
[
"*def teardown_module(mod):*",
@@ -260,8 +262,8 @@ class TestPerTestCapturing:
]
)
- def test_capturing_outerr(self, testdir):
- p1 = testdir.makepyfile(
+ def test_capturing_outerr(self, pytester: Pytester) -> None:
+ p1 = pytester.makepyfile(
"""\
import sys
def test_capturing():
@@ -273,7 +275,7 @@ class TestPerTestCapturing:
raise ValueError
"""
)
- result = testdir.runpytest(p1)
+ result = pytester.runpytest(p1)
result.stdout.fnmatch_lines(
[
"*test_capturing_outerr.py .F*",
@@ -289,8 +291,8 @@ class TestPerTestCapturing:
class TestLoggingInteraction:
- def test_logging_stream_ownership(self, testdir):
- p = testdir.makepyfile(
+ def test_logging_stream_ownership(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""\
def test_logging():
import logging
@@ -300,11 +302,11 @@ class TestLoggingInteraction:
stream.close() # to free memory/release resources
"""
)
- result = testdir.runpytest_subprocess(p)
+ result = pytester.runpytest_subprocess(p)
assert result.stderr.str().find("atexit") == -1
- def test_logging_and_immediate_setupteardown(self, testdir):
- p = testdir.makepyfile(
+ def test_logging_and_immediate_setupteardown(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""\
import logging
def setup_function(function):
@@ -321,7 +323,7 @@ class TestLoggingInteraction:
)
for optargs in (("--capture=sys",), ("--capture=fd",)):
print(optargs)
- result = testdir.runpytest_subprocess(p, *optargs)
+ result = pytester.runpytest_subprocess(p, *optargs)
s = result.stdout.str()
result.stdout.fnmatch_lines(
["*WARN*hello3", "*WARN*hello1", "*WARN*hello2"] # errors show first!
@@ -329,8 +331,8 @@ class TestLoggingInteraction:
# verify proper termination
assert "closed" not in s
- def test_logging_and_crossscope_fixtures(self, testdir):
- p = testdir.makepyfile(
+ def test_logging_and_crossscope_fixtures(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""\
import logging
def setup_module(function):
@@ -347,7 +349,7 @@ class TestLoggingInteraction:
)
for optargs in (("--capture=sys",), ("--capture=fd",)):
print(optargs)
- result = testdir.runpytest_subprocess(p, *optargs)
+ result = pytester.runpytest_subprocess(p, *optargs)
s = result.stdout.str()
result.stdout.fnmatch_lines(
["*WARN*hello3", "*WARN*hello1", "*WARN*hello2"] # errors come first
@@ -355,8 +357,8 @@ class TestLoggingInteraction:
# verify proper termination
assert "closed" not in s
- def test_conftestlogging_is_shown(self, testdir):
- testdir.makeconftest(
+ def test_conftestlogging_is_shown(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""\
import logging
logging.basicConfig()
@@ -364,20 +366,20 @@ class TestLoggingInteraction:
"""
)
# make sure that logging is still captured in tests
- result = testdir.runpytest_subprocess("-s", "-p", "no:capturelog")
+ result = pytester.runpytest_subprocess("-s", "-p", "no:capturelog")
assert result.ret == ExitCode.NO_TESTS_COLLECTED
result.stderr.fnmatch_lines(["WARNING*hello435*"])
assert "operation on closed file" not in result.stderr.str()
- def test_conftestlogging_and_test_logging(self, testdir):
- testdir.makeconftest(
+ def test_conftestlogging_and_test_logging(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""\
import logging
logging.basicConfig()
"""
)
# make sure that logging is still captured in tests
- p = testdir.makepyfile(
+ p = pytester.makepyfile(
"""\
def test_hello():
import logging
@@ -385,14 +387,14 @@ class TestLoggingInteraction:
assert 0
"""
)
- result = testdir.runpytest_subprocess(p, "-p", "no:capturelog")
+ result = pytester.runpytest_subprocess(p, "-p", "no:capturelog")
assert result.ret != 0
result.stdout.fnmatch_lines(["WARNING*hello433*"])
assert "something" not in result.stderr.str()
assert "operation on closed file" not in result.stderr.str()
- def test_logging_after_cap_stopped(self, testdir):
- testdir.makeconftest(
+ def test_logging_after_cap_stopped(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""\
import pytest
import logging
@@ -406,7 +408,7 @@ class TestLoggingInteraction:
"""
)
# make sure that logging is still captured in tests
- p = testdir.makepyfile(
+ p = pytester.makepyfile(
"""\
def test_hello(log_on_teardown):
import logging
@@ -415,7 +417,7 @@ class TestLoggingInteraction:
raise KeyboardInterrupt()
"""
)
- result = testdir.runpytest_subprocess(p, "--log-cli-level", "info")
+ result = pytester.runpytest_subprocess(p, "--log-cli-level", "info")
assert result.ret != 0
result.stdout.fnmatch_lines(
["*WARNING*hello433*", "*WARNING*Logging on teardown*"]
@@ -428,8 +430,8 @@ class TestLoggingInteraction:
class TestCaptureFixture:
@pytest.mark.parametrize("opt", [[], ["-s"]])
- def test_std_functional(self, testdir, opt):
- reprec = testdir.inline_runsource(
+ def test_std_functional(self, pytester: Pytester, opt) -> None:
+ reprec = pytester.inline_runsource(
"""\
def test_hello(capsys):
print(42)
@@ -440,8 +442,8 @@ class TestCaptureFixture:
)
reprec.assertoutcome(passed=1)
- def test_capsyscapfd(self, testdir):
- p = testdir.makepyfile(
+ def test_capsyscapfd(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""\
def test_one(capsys, capfd):
pass
@@ -449,7 +451,7 @@ class TestCaptureFixture:
pass
"""
)
- result = testdir.runpytest(p)
+ result = pytester.runpytest(p)
result.stdout.fnmatch_lines(
[
"*ERROR*setup*test_one*",
@@ -460,11 +462,11 @@ class TestCaptureFixture:
]
)
- def test_capturing_getfixturevalue(self, testdir):
+ def test_capturing_getfixturevalue(self, pytester: Pytester) -> None:
"""Test that asking for "capfd" and "capsys" using request.getfixturevalue
in the same test is an error.
"""
- testdir.makepyfile(
+ pytester.makepyfile(
"""\
def test_one(capsys, request):
request.getfixturevalue("capfd")
@@ -472,7 +474,7 @@ class TestCaptureFixture:
request.getfixturevalue("capsys")
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(
[
"*test_one*",
@@ -483,21 +485,23 @@ class TestCaptureFixture:
]
)
- def test_capsyscapfdbinary(self, testdir):
- p = testdir.makepyfile(
+ def test_capsyscapfdbinary(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""\
def test_one(capsys, capfdbinary):
pass
"""
)
- result = testdir.runpytest(p)
+ result = pytester.runpytest(p)
result.stdout.fnmatch_lines(
["*ERROR*setup*test_one*", "E*capfdbinary*capsys*same*time*", "*1 error*"]
)
@pytest.mark.parametrize("method", ["sys", "fd"])
- def test_capture_is_represented_on_failure_issue128(self, testdir, method):
- p = testdir.makepyfile(
+ def test_capture_is_represented_on_failure_issue128(
+ self, pytester: Pytester, method
+ ) -> None:
+ p = pytester.makepyfile(
"""\
def test_hello(cap{}):
print("xxx42xxx")
@@ -506,11 +510,11 @@ class TestCaptureFixture:
method
)
)
- result = testdir.runpytest(p)
+ result = pytester.runpytest(p)
result.stdout.fnmatch_lines(["xxx42xxx"])
- def test_stdfd_functional(self, testdir):
- reprec = testdir.inline_runsource(
+ def test_stdfd_functional(self, pytester: Pytester) -> None:
+ reprec = pytester.inline_runsource(
"""\
def test_hello(capfd):
import os
@@ -523,13 +527,13 @@ class TestCaptureFixture:
reprec.assertoutcome(passed=1)
@pytest.mark.parametrize("nl", ("\n", "\r\n", "\r"))
- def test_cafd_preserves_newlines(self, capfd, nl):
+ def test_cafd_preserves_newlines(self, capfd, nl) -> None:
print("test", end=nl)
out, err = capfd.readouterr()
assert out.endswith(nl)
- def test_capfdbinary(self, testdir):
- reprec = testdir.inline_runsource(
+ def test_capfdbinary(self, pytester: Pytester) -> None:
+ reprec = pytester.inline_runsource(
"""\
def test_hello(capfdbinary):
import os
@@ -542,8 +546,8 @@ class TestCaptureFixture:
)
reprec.assertoutcome(passed=1)
- def test_capsysbinary(self, testdir):
- p1 = testdir.makepyfile(
+ def test_capsysbinary(self, pytester: Pytester) -> None:
+ p1 = pytester.makepyfile(
r"""
def test_hello(capsysbinary):
import sys
@@ -567,7 +571,7 @@ class TestCaptureFixture:
print("stderr after", file=sys.stderr)
"""
)
- result = testdir.runpytest(str(p1), "-rA")
+ result = pytester.runpytest(str(p1), "-rA")
result.stdout.fnmatch_lines(
[
"*- Captured stdout call -*",
@@ -578,18 +582,18 @@ class TestCaptureFixture:
]
)
- def test_partial_setup_failure(self, testdir):
- p = testdir.makepyfile(
+ def test_partial_setup_failure(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""\
def test_hello(capsys, missingarg):
pass
"""
)
- result = testdir.runpytest(p)
+ result = pytester.runpytest(p)
result.stdout.fnmatch_lines(["*test_partial_setup_failure*", "*1 error*"])
- def test_keyboardinterrupt_disables_capturing(self, testdir):
- p = testdir.makepyfile(
+ def test_keyboardinterrupt_disables_capturing(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""\
def test_hello(capfd):
import os
@@ -597,26 +601,28 @@ class TestCaptureFixture:
raise KeyboardInterrupt()
"""
)
- result = testdir.runpytest_subprocess(p)
+ result = pytester.runpytest_subprocess(p)
result.stdout.fnmatch_lines(["*KeyboardInterrupt*"])
assert result.ret == 2
- def test_capture_and_logging(self, testdir):
+ def test_capture_and_logging(self, pytester: Pytester) -> None:
"""#14"""
- p = testdir.makepyfile(
+ p = pytester.makepyfile(
"""\
import logging
def test_log(capsys):
logging.error('x')
"""
)
- result = testdir.runpytest_subprocess(p)
+ result = pytester.runpytest_subprocess(p)
assert "closed" not in result.stderr.str()
@pytest.mark.parametrize("fixture", ["capsys", "capfd"])
@pytest.mark.parametrize("no_capture", [True, False])
- def test_disabled_capture_fixture(self, testdir, fixture, no_capture):
- testdir.makepyfile(
+ def test_disabled_capture_fixture(
+ self, pytester: Pytester, fixture: str, no_capture: bool
+ ) -> None:
+ pytester.makepyfile(
"""\
def test_disabled({fixture}):
print('captured before')
@@ -632,7 +638,7 @@ class TestCaptureFixture:
)
)
args = ("-s",) if no_capture else ()
- result = testdir.runpytest_subprocess(*args)
+ result = pytester.runpytest_subprocess(*args)
result.stdout.fnmatch_lines(["*while capture is disabled*", "*= 2 passed in *"])
result.stdout.no_fnmatch_line("*captured before*")
result.stdout.no_fnmatch_line("*captured after*")
@@ -641,12 +647,12 @@ class TestCaptureFixture:
else:
result.stdout.no_fnmatch_line("*test_normal executed*")
- def test_disabled_capture_fixture_twice(self, testdir: Testdir) -> None:
+ def test_disabled_capture_fixture_twice(self, pytester: Pytester) -> None:
"""Test that an inner disabled() exit doesn't undo an outer disabled().
Issue #7148.
"""
- testdir.makepyfile(
+ pytester.makepyfile(
"""
def test_disabled(capfd):
print('captured before')
@@ -659,7 +665,7 @@ class TestCaptureFixture:
assert capfd.readouterr() == ('captured before\\ncaptured after\\n', '')
"""
)
- result = testdir.runpytest_subprocess()
+ result = pytester.runpytest_subprocess()
result.stdout.fnmatch_lines(
[
"*while capture is disabled 1",
@@ -670,10 +676,10 @@ class TestCaptureFixture:
)
@pytest.mark.parametrize("fixture", ["capsys", "capfd"])
- def test_fixture_use_by_other_fixtures(self, testdir, fixture):
+ def test_fixture_use_by_other_fixtures(self, pytester: Pytester, fixture) -> None:
"""Ensure that capsys and capfd can be used by other fixtures during
setup and teardown."""
- testdir.makepyfile(
+ pytester.makepyfile(
"""\
import sys
import pytest
@@ -700,15 +706,17 @@ class TestCaptureFixture:
fixture=fixture
)
)
- result = testdir.runpytest_subprocess()
+ result = pytester.runpytest_subprocess()
result.stdout.fnmatch_lines(["*1 passed*"])
result.stdout.no_fnmatch_line("*stdout contents begin*")
result.stdout.no_fnmatch_line("*stderr contents begin*")
@pytest.mark.parametrize("cap", ["capsys", "capfd"])
- def test_fixture_use_by_other_fixtures_teardown(self, testdir, cap):
+ def test_fixture_use_by_other_fixtures_teardown(
+ self, pytester: Pytester, cap
+ ) -> None:
"""Ensure we can access setup and teardown buffers from teardown when using capsys/capfd (##3033)"""
- testdir.makepyfile(
+ pytester.makepyfile(
"""\
import sys
import pytest
@@ -730,13 +738,13 @@ class TestCaptureFixture:
cap=cap
)
)
- reprec = testdir.inline_run()
+ reprec = pytester.inline_run()
reprec.assertoutcome(passed=1)
-def test_setup_failure_does_not_kill_capturing(testdir):
- sub1 = testdir.mkpydir("sub1")
- sub1.join("conftest.py").write(
+def test_setup_failure_does_not_kill_capturing(pytester: Pytester) -> None:
+ sub1 = pytester.mkpydir("sub1")
+ sub1.joinpath("conftest.py").write_text(
textwrap.dedent(
"""\
def pytest_runtest_setup(item):
@@ -744,26 +752,26 @@ def test_setup_failure_does_not_kill_capturing(testdir):
"""
)
)
- sub1.join("test_mod.py").write("def test_func1(): pass")
- result = testdir.runpytest(testdir.tmpdir, "--traceconfig")
+ sub1.joinpath("test_mod.py").write_text("def test_func1(): pass")
+ result = pytester.runpytest(pytester.path, "--traceconfig")
result.stdout.fnmatch_lines(["*ValueError(42)*", "*1 error*"])
-def test_capture_conftest_runtest_setup(testdir):
- testdir.makeconftest(
+def test_capture_conftest_runtest_setup(pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_runtest_setup():
print("hello19")
"""
)
- testdir.makepyfile("def test_func(): pass")
- result = testdir.runpytest()
+ pytester.makepyfile("def test_func(): pass")
+ result = pytester.runpytest()
assert result.ret == 0
result.stdout.no_fnmatch_line("*hello19*")
-def test_capture_badoutput_issue412(testdir):
- testdir.makepyfile(
+def test_capture_badoutput_issue412(pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
import os
@@ -773,7 +781,7 @@ def test_capture_badoutput_issue412(testdir):
assert 0
"""
)
- result = testdir.runpytest("--capture=fd")
+ result = pytester.runpytest("--capture=fd")
result.stdout.fnmatch_lines(
"""
*def test_func*
@@ -784,21 +792,21 @@ def test_capture_badoutput_issue412(testdir):
)
-def test_capture_early_option_parsing(testdir):
- testdir.makeconftest(
+def test_capture_early_option_parsing(pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_runtest_setup():
print("hello19")
"""
)
- testdir.makepyfile("def test_func(): pass")
- result = testdir.runpytest("-vs")
+ pytester.makepyfile("def test_func(): pass")
+ result = pytester.runpytest("-vs")
assert result.ret == 0
assert "hello19" in result.stdout.str()
-def test_capture_binary_output(testdir):
- testdir.makepyfile(
+def test_capture_binary_output(pytester: Pytester) -> None:
+ pytester.makepyfile(
r"""
import pytest
@@ -814,13 +822,13 @@ def test_capture_binary_output(testdir):
test_foo()
"""
)
- result = testdir.runpytest("--assert=plain")
+ result = pytester.runpytest("--assert=plain")
result.assert_outcomes(passed=2)
-def test_error_during_readouterr(testdir):
+def test_error_during_readouterr(pytester: Pytester) -> None:
"""Make sure we suspend capturing if errors occur during readouterr"""
- testdir.makepyfile(
+ pytester.makepyfile(
pytest_xyz="""
from _pytest.capture import FDCapture
@@ -831,26 +839,26 @@ def test_error_during_readouterr(testdir):
FDCapture.snap = bad_snap
"""
)
- result = testdir.runpytest_subprocess("-p", "pytest_xyz", "--version")
+ result = pytester.runpytest_subprocess("-p", "pytest_xyz", "--version")
result.stderr.fnmatch_lines(
["*in bad_snap", " raise Exception('boom')", "Exception: boom"]
)
class TestCaptureIO:
- def test_text(self):
+ def test_text(self) -> None:
f = capture.CaptureIO()
f.write("hello")
s = f.getvalue()
assert s == "hello"
f.close()
- def test_unicode_and_str_mixture(self):
+ def test_unicode_and_str_mixture(self) -> None:
f = capture.CaptureIO()
f.write("\u00f6")
pytest.raises(TypeError, f.write, b"hello")
- def test_write_bytes_to_buffer(self):
+ def test_write_bytes_to_buffer(self) -> None:
"""In python3, stdout / stderr are text io wrappers (exposing a buffer
property of the underlying bytestream). See issue #1407
"""
@@ -860,7 +868,7 @@ class TestCaptureIO:
class TestTeeCaptureIO(TestCaptureIO):
- def test_text(self):
+ def test_text(self) -> None:
sio = io.StringIO()
f = capture.TeeCaptureIO(sio)
f.write("hello")
@@ -871,14 +879,14 @@ class TestTeeCaptureIO(TestCaptureIO):
f.close()
sio.close()
- def test_unicode_and_str_mixture(self):
+ def test_unicode_and_str_mixture(self) -> None:
sio = io.StringIO()
f = capture.TeeCaptureIO(sio)
f.write("\u00f6")
pytest.raises(TypeError, f.write, b"hello")
-def test_dontreadfrominput():
+def test_dontreadfrominput() -> None:
from _pytest.capture import DontReadFromInput
f = DontReadFromInput()
@@ -923,8 +931,8 @@ def test_captureresult() -> None:
@pytest.fixture
-def tmpfile(testdir) -> Generator[BinaryIO, None, None]:
- f = testdir.makepyfile("").open("wb+")
+def tmpfile(pytester: Pytester) -> Generator[BinaryIO, None, None]:
+ f = pytester.makepyfile("").open("wb+")
yield f
if not f.closed:
f.close()
@@ -946,7 +954,7 @@ def lsof_check():
class TestFDCapture:
- def test_simple(self, tmpfile):
+ def test_simple(self, tmpfile: BinaryIO) -> None:
fd = tmpfile.fileno()
cap = capture.FDCapture(fd)
data = b"hello"
@@ -960,22 +968,22 @@ class TestFDCapture:
cap.done()
assert s == "hello"
- def test_simple_many(self, tmpfile):
+ def test_simple_many(self, tmpfile: BinaryIO) -> None:
for i in range(10):
self.test_simple(tmpfile)
- def test_simple_many_check_open_files(self, testdir):
+ def test_simple_many_check_open_files(self, pytester: Pytester) -> None:
with lsof_check():
- with testdir.makepyfile("").open("wb+") as tmpfile:
+ with pytester.makepyfile("").open("wb+") as tmpfile:
self.test_simple_many(tmpfile)
- def test_simple_fail_second_start(self, tmpfile):
+ def test_simple_fail_second_start(self, tmpfile: BinaryIO) -> None:
fd = tmpfile.fileno()
cap = capture.FDCapture(fd)
cap.done()
pytest.raises(AssertionError, cap.start)
- def test_stderr(self):
+ def test_stderr(self) -> None:
cap = capture.FDCapture(2)
cap.start()
print("hello", file=sys.stderr)
@@ -983,14 +991,14 @@ class TestFDCapture:
cap.done()
assert s == "hello\n"
- def test_stdin(self):
+ def test_stdin(self) -> None:
cap = capture.FDCapture(0)
cap.start()
x = os.read(0, 100).strip()
cap.done()
assert x == b""
- def test_writeorg(self, tmpfile):
+ def test_writeorg(self, tmpfile: BinaryIO) -> None:
data1, data2 = b"foo", b"bar"
cap = capture.FDCapture(tmpfile.fileno())
cap.start()
@@ -1004,7 +1012,7 @@ class TestFDCapture:
stmp = stmp_file.read()
assert stmp == data2
- def test_simple_resume_suspend(self):
+ def test_simple_resume_suspend(self) -> None:
with saved_fd(1):
cap = capture.FDCapture(1)
cap.start()
@@ -1038,7 +1046,7 @@ class TestFDCapture:
)
)
- def test_capfd_sys_stdout_mode(self, capfd):
+ def test_capfd_sys_stdout_mode(self, capfd) -> None:
assert "b" not in sys.stdout.mode
@@ -1064,7 +1072,7 @@ class TestStdCapture:
finally:
cap.stop_capturing()
- def test_capturing_done_simple(self):
+ def test_capturing_done_simple(self) -> None:
with self.getcapture() as cap:
sys.stdout.write("hello")
sys.stderr.write("world")
@@ -1072,7 +1080,7 @@ class TestStdCapture:
assert out == "hello"
assert err == "world"
- def test_capturing_reset_simple(self):
+ def test_capturing_reset_simple(self) -> None:
with self.getcapture() as cap:
print("hello world")
sys.stderr.write("hello error\n")
@@ -1080,7 +1088,7 @@ class TestStdCapture:
assert out == "hello world\n"
assert err == "hello error\n"
- def test_capturing_readouterr(self):
+ def test_capturing_readouterr(self) -> None:
with self.getcapture() as cap:
print("hello world")
sys.stderr.write("hello error\n")
@@ -1091,7 +1099,7 @@ class TestStdCapture:
out, err = cap.readouterr()
assert err == "error2"
- def test_capture_results_accessible_by_attribute(self):
+ def test_capture_results_accessible_by_attribute(self) -> None:
with self.getcapture() as cap:
sys.stdout.write("hello")
sys.stderr.write("world")
@@ -1099,13 +1107,13 @@ class TestStdCapture:
assert capture_result.out == "hello"
assert capture_result.err == "world"
- def test_capturing_readouterr_unicode(self):
+ def test_capturing_readouterr_unicode(self) -> None:
with self.getcapture() as cap:
print("hxąć")
out, err = cap.readouterr()
assert out == "hxąć\n"
- def test_reset_twice_error(self):
+ def test_reset_twice_error(self) -> None:
with self.getcapture() as cap:
print("hello")
out, err = cap.readouterr()
@@ -1113,7 +1121,7 @@ class TestStdCapture:
assert out == "hello\n"
assert not err
- def test_capturing_modify_sysouterr_in_between(self):
+ def test_capturing_modify_sysouterr_in_between(self) -> None:
oldout = sys.stdout
olderr = sys.stderr
with self.getcapture() as cap:
@@ -1129,7 +1137,7 @@ class TestStdCapture:
assert sys.stdout == oldout
assert sys.stderr == olderr
- def test_capturing_error_recursive(self):
+ def test_capturing_error_recursive(self) -> None:
with self.getcapture() as cap1:
print("cap1")
with self.getcapture() as cap2:
@@ -1139,7 +1147,7 @@ class TestStdCapture:
assert out1 == "cap1\n"
assert out2 == "cap2\n"
- def test_just_out_capture(self):
+ def test_just_out_capture(self) -> None:
with self.getcapture(out=True, err=False) as cap:
sys.stdout.write("hello")
sys.stderr.write("world")
@@ -1147,7 +1155,7 @@ class TestStdCapture:
assert out == "hello"
assert not err
- def test_just_err_capture(self):
+ def test_just_err_capture(self) -> None:
with self.getcapture(out=False, err=True) as cap:
sys.stdout.write("hello")
sys.stderr.write("world")
@@ -1155,14 +1163,14 @@ class TestStdCapture:
assert err == "world"
assert not out
- def test_stdin_restored(self):
+ def test_stdin_restored(self) -> None:
old = sys.stdin
with self.getcapture(in_=True):
newstdin = sys.stdin
assert newstdin != sys.stdin
assert sys.stdin is old
- def test_stdin_nulled_by_default(self):
+ def test_stdin_nulled_by_default(self) -> None:
print("XXX this test may well hang instead of crashing")
print("XXX which indicates an error in the underlying capturing")
print("XXX mechanisms")
@@ -1173,7 +1181,7 @@ class TestStdCapture:
class TestTeeStdCapture(TestStdCapture):
captureclass = staticmethod(TeeStdCapture)
- def test_capturing_error_recursive(self):
+ def test_capturing_error_recursive(self) -> None:
r"""For TeeStdCapture since we passthrough stderr/stdout, cap1
should get all output, while cap2 should only get "cap2\n"."""
@@ -1190,8 +1198,8 @@ class TestTeeStdCapture(TestStdCapture):
class TestStdCaptureFD(TestStdCapture):
captureclass = staticmethod(StdCaptureFD)
- def test_simple_only_fd(self, testdir):
- testdir.makepyfile(
+ def test_simple_only_fd(self, pytester: Pytester) -> None:
+ pytester.makepyfile(
"""\
import os
def test_x():
@@ -1199,7 +1207,7 @@ class TestStdCaptureFD(TestStdCapture):
assert 0
"""
)
- result = testdir.runpytest_subprocess()
+ result = pytester.runpytest_subprocess()
result.stdout.fnmatch_lines(
"""
*test_x*
@@ -1231,8 +1239,8 @@ class TestStdCaptureFD(TestStdCapture):
class TestStdCaptureFDinvalidFD:
- def test_stdcapture_fd_invalid_fd(self, testdir):
- testdir.makepyfile(
+ def test_stdcapture_fd_invalid_fd(self, pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
import os
from fnmatch import fnmatch
@@ -1270,11 +1278,11 @@ class TestStdCaptureFDinvalidFD:
cap.stop_capturing()
"""
)
- result = testdir.runpytest_subprocess("--capture=fd")
+ result = pytester.runpytest_subprocess("--capture=fd")
assert result.ret == 0
assert result.parseoutcomes()["passed"] == 3
- def test_fdcapture_invalid_fd_with_fd_reuse(self, testdir):
+ def test_fdcapture_invalid_fd_with_fd_reuse(self, pytester: Pytester) -> None:
with saved_fd(1):
os.close(1)
cap = capture.FDCaptureBinary(1)
@@ -1289,7 +1297,7 @@ class TestStdCaptureFDinvalidFD:
with pytest.raises(OSError):
os.write(1, b"done")
- def test_fdcapture_invalid_fd_without_fd_reuse(self, testdir):
+ def test_fdcapture_invalid_fd_without_fd_reuse(self, pytester: Pytester) -> None:
with saved_fd(1), saved_fd(2):
os.close(1)
os.close(2)
@@ -1306,12 +1314,14 @@ class TestStdCaptureFDinvalidFD:
os.write(2, b"done")
-def test_capture_not_started_but_reset():
+def test_capture_not_started_but_reset() -> None:
capsys = StdCapture()
capsys.stop_capturing()
-def test_using_capsys_fixture_works_with_sys_stdout_encoding(capsys):
+def test_using_capsys_fixture_works_with_sys_stdout_encoding(
+ capsys: CaptureFixture[str],
+) -> None:
test_text = "test text"
print(test_text.encode(sys.stdout.encoding, "replace"))
@@ -1320,7 +1330,7 @@ def test_using_capsys_fixture_works_with_sys_stdout_encoding(capsys):
assert err == ""
-def test_capsys_results_accessible_by_attribute(capsys):
+def test_capsys_results_accessible_by_attribute(capsys: CaptureFixture[str]) -> None:
sys.stdout.write("spam")
sys.stderr.write("eggs")
capture_result = capsys.readouterr()
@@ -1340,8 +1350,8 @@ def test_fdcapture_tmpfile_remains_the_same() -> None:
assert capfile2 == capfile
-def test_close_and_capture_again(testdir):
- testdir.makepyfile(
+def test_close_and_capture_again(pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
import os
def test_close():
@@ -1351,7 +1361,7 @@ def test_close_and_capture_again(testdir):
assert 0
"""
)
- result = testdir.runpytest_subprocess()
+ result = pytester.runpytest_subprocess()
result.stdout.fnmatch_lines(
"""
*test_capture_again*
@@ -1365,9 +1375,9 @@ def test_close_and_capture_again(testdir):
@pytest.mark.parametrize(
"method", ["SysCapture(2)", "SysCapture(2, tee=True)", "FDCapture(2)"]
)
-def test_capturing_and_logging_fundamentals(testdir, method: str) -> None:
+def test_capturing_and_logging_fundamentals(pytester: Pytester, method: str) -> None:
# here we check a fundamental feature
- p = testdir.makepyfile(
+ p = pytester.makepyfile(
"""
import sys, os
import py, logging
@@ -1392,7 +1402,7 @@ def test_capturing_and_logging_fundamentals(testdir, method: str) -> None:
"""
% (method,)
)
- result = testdir.runpython(p)
+ result = pytester.runpython(p)
result.stdout.fnmatch_lines(
"""
suspend, captured*hello1*
@@ -1407,8 +1417,8 @@ def test_capturing_and_logging_fundamentals(testdir, method: str) -> None:
assert "atexit" not in result.stderr.str()
-def test_error_attribute_issue555(testdir):
- testdir.makepyfile(
+def test_error_attribute_issue555(pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
import sys
def test_capattr():
@@ -1416,7 +1426,7 @@ def test_error_attribute_issue555(testdir):
assert sys.stderr.errors == "replace"
"""
)
- reprec = testdir.inline_run()
+ reprec = pytester.inline_run()
reprec.assertoutcome(passed=1)
@@ -1438,8 +1448,8 @@ def test_py36_windowsconsoleio_workaround_non_standard_streams() -> None:
_py36_windowsconsoleio_workaround(stream)
-def test_dontreadfrominput_has_encoding(testdir):
- testdir.makepyfile(
+def test_dontreadfrominput_has_encoding(pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
import sys
def test_capattr():
@@ -1448,12 +1458,14 @@ def test_dontreadfrominput_has_encoding(testdir):
assert sys.stderr.encoding
"""
)
- reprec = testdir.inline_run()
+ reprec = pytester.inline_run()
reprec.assertoutcome(passed=1)
-def test_crash_on_closing_tmpfile_py27(testdir):
- p = testdir.makepyfile(
+def test_crash_on_closing_tmpfile_py27(
+ pytester: Pytester, monkeypatch: MonkeyPatch
+) -> None:
+ p = pytester.makepyfile(
"""
import threading
import sys
@@ -1480,19 +1492,19 @@ def test_crash_on_closing_tmpfile_py27(testdir):
"""
)
# Do not consider plugins like hypothesis, which might output to stderr.
- testdir.monkeypatch.setenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", "1")
- result = testdir.runpytest_subprocess(str(p))
+ monkeypatch.setenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", "1")
+ result = pytester.runpytest_subprocess(str(p))
assert result.ret == 0
assert result.stderr.str() == ""
result.stdout.no_fnmatch_line("*OSError*")
-def test_global_capture_with_live_logging(testdir):
+def test_global_capture_with_live_logging(pytester: Pytester) -> None:
# Issue 3819
# capture should work with live cli logging
# Teardown report seems to have the capture for the whole process (setup, capture, teardown)
- testdir.makeconftest(
+ pytester.makeconftest(
"""
def pytest_runtest_logreport(report):
if "test_global" in report.nodeid:
@@ -1504,7 +1516,7 @@ def test_global_capture_with_live_logging(testdir):
"""
)
- testdir.makepyfile(
+ pytester.makepyfile(
"""
import logging
import sys
@@ -1526,7 +1538,7 @@ def test_global_capture_with_live_logging(testdir):
print("end test")
"""
)
- result = testdir.runpytest_subprocess("--log-cli-level=INFO")
+ result = pytester.runpytest_subprocess("--log-cli-level=INFO")
assert result.ret == 0
with open("caplog") as f:
@@ -1546,11 +1558,13 @@ def test_global_capture_with_live_logging(testdir):
@pytest.mark.parametrize("capture_fixture", ["capsys", "capfd"])
-def test_capture_with_live_logging(testdir, capture_fixture):
+def test_capture_with_live_logging(
+ pytester: Pytester, capture_fixture: CaptureFixture[str]
+) -> None:
# Issue 3819
# capture should work with live cli logging
- testdir.makepyfile(
+ pytester.makepyfile(
"""
import logging
import sys
@@ -1575,21 +1589,21 @@ def test_capture_with_live_logging(testdir, capture_fixture):
)
)
- result = testdir.runpytest_subprocess("--log-cli-level=INFO")
+ result = pytester.runpytest_subprocess("--log-cli-level=INFO")
assert result.ret == 0
-def test_typeerror_encodedfile_write(testdir):
+def test_typeerror_encodedfile_write(pytester: Pytester) -> None:
"""It should behave the same with and without output capturing (#4861)."""
- p = testdir.makepyfile(
+ p = pytester.makepyfile(
"""
def test_fails():
import sys
sys.stdout.write(b"foo")
"""
)
- result_without_capture = testdir.runpytest("-s", str(p))
- result_with_capture = testdir.runpytest(str(p))
+ result_without_capture = pytester.runpytest("-s", str(p))
+ result_with_capture = pytester.runpytest(str(p))
assert result_with_capture.ret == result_without_capture.ret
out = result_with_capture.stdout.str()
@@ -1598,7 +1612,7 @@ def test_typeerror_encodedfile_write(testdir):
)
-def test_stderr_write_returns_len(capsys):
+def test_stderr_write_returns_len(capsys: CaptureFixture[str]) -> None:
"""Write on Encoded files, namely captured stderr, should return number of characters written."""
assert sys.stderr.write("Foo") == 3
@@ -1623,9 +1637,9 @@ def test__get_multicapture() -> None:
)
-def test_logging_while_collecting(testdir):
+def test_logging_while_collecting(pytester: Pytester) -> None:
"""Issue #6240: Calls to logging.xxx() during collection causes all logging calls to be duplicated to stderr"""
- p = testdir.makepyfile(
+ p = pytester.makepyfile(
"""\
import logging
@@ -1636,7 +1650,7 @@ def test_logging_while_collecting(testdir):
assert False
"""
)
- result = testdir.runpytest_subprocess(p)
+ result = pytester.runpytest_subprocess(p)
assert result.ret == ExitCode.TESTS_FAILED
result.stdout.fnmatch_lines(
[
diff --git a/testing/test_config.py b/testing/test_config.py
index f3fa64372..b931797d4 100644
--- a/testing/test_config.py
+++ b/testing/test_config.py
@@ -8,6 +8,7 @@ from typing import List
from typing import Sequence
from typing import Tuple
from typing import Type
+from typing import Union
import attr
import py.path
@@ -27,7 +28,7 @@ from _pytest.config.findpaths import determine_setup
from _pytest.config.findpaths import get_common_ancestor
from _pytest.config.findpaths import locate_config
from _pytest.monkeypatch import MonkeyPatch
-from _pytest.pytester import Testdir
+from _pytest.pytester import Pytester
class TestParseIni:
@@ -36,7 +37,7 @@ class TestParseIni:
)
def test_getcfg_and_config(
self,
- testdir: Testdir,
+ pytester: Pytester,
tmp_path: Path,
section: str,
filename: str,
@@ -58,12 +59,12 @@ class TestParseIni:
)
_, _, cfg = locate_config([sub])
assert cfg["name"] == "value"
- config = testdir.parseconfigure(str(sub))
+ config = pytester.parseconfigure(str(sub))
assert config.inicfg["name"] == "value"
- def test_setupcfg_uses_toolpytest_with_pytest(self, testdir):
- p1 = testdir.makepyfile("def test(): pass")
- testdir.makefile(
+ def test_setupcfg_uses_toolpytest_with_pytest(self, pytester: Pytester) -> None:
+ p1 = pytester.makepyfile("def test(): pass")
+ pytester.makefile(
".cfg",
setup="""
[tool:pytest]
@@ -71,15 +72,17 @@ class TestParseIni:
[pytest]
testpaths=ignored
"""
- % p1.basename,
+ % p1.name,
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(["*, configfile: setup.cfg, *", "* 1 passed in *"])
assert result.ret == 0
- def test_append_parse_args(self, testdir, tmpdir, monkeypatch):
+ def test_append_parse_args(
+ self, pytester: Pytester, tmp_path: Path, monkeypatch: MonkeyPatch
+ ) -> None:
monkeypatch.setenv("PYTEST_ADDOPTS", '--color no -rs --tb="short"')
- tmpdir.join("pytest.ini").write(
+ tmp_path.joinpath("pytest.ini").write_text(
textwrap.dedent(
"""\
[pytest]
@@ -87,21 +90,21 @@ class TestParseIni:
"""
)
)
- config = testdir.parseconfig(tmpdir)
+ config = pytester.parseconfig(tmp_path)
assert config.option.color == "no"
assert config.option.reportchars == "s"
assert config.option.tbstyle == "short"
assert config.option.verbose
- def test_tox_ini_wrong_version(self, testdir):
- testdir.makefile(
+ def test_tox_ini_wrong_version(self, pytester: Pytester) -> None:
+ pytester.makefile(
".ini",
tox="""
[pytest]
minversion=999.0
""",
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
assert result.ret != 0
result.stderr.fnmatch_lines(
["*tox.ini: 'minversion' requires pytest-999.0, actual pytest-*"]
@@ -111,8 +114,8 @@ class TestParseIni:
"section, name",
[("tool:pytest", "setup.cfg"), ("pytest", "tox.ini"), ("pytest", "pytest.ini")],
)
- def test_ini_names(self, testdir, name, section):
- testdir.tmpdir.join(name).write(
+ def test_ini_names(self, pytester: Pytester, name, section) -> None:
+ pytester.path.joinpath(name).write_text(
textwrap.dedent(
"""
[{section}]
@@ -122,22 +125,22 @@ class TestParseIni:
)
)
)
- config = testdir.parseconfig()
+ config = pytester.parseconfig()
assert config.getini("minversion") == "1.0"
- def test_pyproject_toml(self, testdir):
- testdir.makepyprojecttoml(
+ def test_pyproject_toml(self, pytester: Pytester) -> None:
+ pytester.makepyprojecttoml(
"""
[tool.pytest.ini_options]
minversion = "1.0"
"""
)
- config = testdir.parseconfig()
+ config = pytester.parseconfig()
assert config.getini("minversion") == "1.0"
- def test_toxini_before_lower_pytestini(self, testdir):
- sub = testdir.tmpdir.mkdir("sub")
- sub.join("tox.ini").write(
+ def test_toxini_before_lower_pytestini(self, pytester: Pytester) -> None:
+ sub = pytester.mkdir("sub")
+ sub.joinpath("tox.ini").write_text(
textwrap.dedent(
"""
[pytest]
@@ -145,7 +148,7 @@ class TestParseIni:
"""
)
)
- testdir.tmpdir.join("pytest.ini").write(
+ pytester.path.joinpath("pytest.ini").write_text(
textwrap.dedent(
"""
[pytest]
@@ -153,26 +156,26 @@ class TestParseIni:
"""
)
)
- config = testdir.parseconfigure(sub)
+ config = pytester.parseconfigure(sub)
assert config.getini("minversion") == "2.0"
- def test_ini_parse_error(self, testdir):
- testdir.tmpdir.join("pytest.ini").write("addopts = -x")
- result = testdir.runpytest()
+ def test_ini_parse_error(self, pytester: Pytester) -> None:
+ pytester.path.joinpath("pytest.ini").write_text("addopts = -x")
+ result = pytester.runpytest()
assert result.ret != 0
result.stderr.fnmatch_lines(["ERROR: *pytest.ini:1: no section header defined"])
@pytest.mark.xfail(reason="probably not needed")
- def test_confcutdir(self, testdir):
- sub = testdir.mkdir("sub")
- sub.chdir()
- testdir.makeini(
+ def test_confcutdir(self, pytester: Pytester) -> None:
+ sub = pytester.mkdir("sub")
+ os.chdir(sub)
+ pytester.makeini(
"""
[pytest]
addopts = --qwe
"""
)
- result = testdir.inline_run("--confcutdir=.")
+ result = pytester.inline_run("--confcutdir=.")
assert result.ret == 0
@pytest.mark.parametrize(
@@ -243,24 +246,29 @@ class TestParseIni:
)
@pytest.mark.filterwarnings("default")
def test_invalid_config_options(
- self, testdir, ini_file_text, invalid_keys, warning_output, exception_text
- ):
- testdir.makeconftest(
+ self,
+ pytester: Pytester,
+ ini_file_text,
+ invalid_keys,
+ warning_output,
+ exception_text,
+ ) -> None:
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addini("conftest_ini_key", "")
"""
)
- testdir.makepyfile("def test(): pass")
- testdir.makeini(ini_file_text)
+ pytester.makepyfile("def test(): pass")
+ pytester.makeini(ini_file_text)
- config = testdir.parseconfig()
+ config = pytester.parseconfig()
assert sorted(config._get_unknown_ini_keys()) == sorted(invalid_keys)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(warning_output)
- result = testdir.runpytest("--strict-config")
+ result = pytester.runpytest("--strict-config")
if exception_text:
result.stderr.fnmatch_lines("ERROR: " + exception_text)
assert result.ret == pytest.ExitCode.USAGE_ERROR
@@ -269,9 +277,9 @@ class TestParseIni:
assert result.ret == pytest.ExitCode.OK
@pytest.mark.filterwarnings("default")
- def test_silence_unknown_key_warning(self, testdir: Testdir) -> None:
+ def test_silence_unknown_key_warning(self, pytester: Pytester) -> None:
"""Unknown config key warnings can be silenced using filterwarnings (#7620)"""
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
filterwarnings =
@@ -279,15 +287,15 @@ class TestParseIni:
foobar=1
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.no_fnmatch_line("*PytestConfigWarning*")
@pytest.mark.filterwarnings("default")
def test_disable_warnings_plugin_disables_config_warnings(
- self, testdir: Testdir
+ self, pytester: Pytester
) -> None:
"""Disabling 'warnings' plugin also disables config time warnings"""
- testdir.makeconftest(
+ pytester.makeconftest(
"""
import pytest
def pytest_configure(config):
@@ -297,7 +305,7 @@ class TestParseIni:
)
"""
)
- result = testdir.runpytest("-pno:warnings")
+ result = pytester.runpytest("-pno:warnings")
result.stdout.no_fnmatch_line("*PytestConfigWarning*")
@pytest.mark.parametrize(
@@ -371,8 +379,12 @@ class TestParseIni:
],
)
def test_missing_required_plugins(
- self, testdir, monkeypatch, ini_file_text, exception_text
- ):
+ self,
+ pytester: Pytester,
+ monkeypatch: MonkeyPatch,
+ ini_file_text: str,
+ exception_text: str,
+ ) -> None:
"""Check 'required_plugins' option with various settings.
This test installs a mock "myplugin-1.5" which is used in the parametrized test cases.
@@ -405,26 +417,28 @@ class TestParseIni:
def my_dists():
return [DummyDist(entry_points)]
- testdir.makepyfile(myplugin1_module="# my plugin module")
- testdir.syspathinsert()
+ pytester.makepyfile(myplugin1_module="# my plugin module")
+ pytester.syspathinsert()
monkeypatch.setattr(importlib_metadata, "distributions", my_dists)
- testdir.monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
+ monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
- testdir.makeini(ini_file_text)
+ pytester.makeini(ini_file_text)
if exception_text:
with pytest.raises(pytest.UsageError, match=exception_text):
- testdir.parseconfig()
+ pytester.parseconfig()
else:
- testdir.parseconfig()
+ pytester.parseconfig()
- def test_early_config_cmdline(self, testdir, monkeypatch):
+ def test_early_config_cmdline(
+ self, pytester: Pytester, monkeypatch: MonkeyPatch
+ ) -> None:
"""early_config contains options registered by third-party plugins.
This is a regression involving pytest-cov (and possibly others) introduced in #7700.
"""
- testdir.makepyfile(
+ pytester.makepyfile(
myplugin="""
def pytest_addoption(parser):
parser.addoption('--foo', default=None, dest='foo')
@@ -434,50 +448,52 @@ class TestParseIni:
"""
)
monkeypatch.setenv("PYTEST_PLUGINS", "myplugin")
- testdir.syspathinsert()
- result = testdir.runpytest("--foo=1")
+ pytester.syspathinsert()
+ result = pytester.runpytest("--foo=1")
result.stdout.fnmatch_lines("* no tests ran in *")
class TestConfigCmdlineParsing:
- def test_parsing_again_fails(self, testdir):
- config = testdir.parseconfig()
+ def test_parsing_again_fails(self, pytester: Pytester) -> None:
+ config = pytester.parseconfig()
pytest.raises(AssertionError, lambda: config.parse([]))
- def test_explicitly_specified_config_file_is_loaded(self, testdir):
- testdir.makeconftest(
+ def test_explicitly_specified_config_file_is_loaded(
+ self, pytester: Pytester
+ ) -> None:
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addini("custom", "")
"""
)
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
custom = 0
"""
)
- testdir.makefile(
+ pytester.makefile(
".ini",
custom="""
[pytest]
custom = 1
""",
)
- config = testdir.parseconfig("-c", "custom.ini")
+ config = pytester.parseconfig("-c", "custom.ini")
assert config.getini("custom") == "1"
- testdir.makefile(
+ pytester.makefile(
".cfg",
custom_tool_pytest_section="""
[tool:pytest]
custom = 1
""",
)
- config = testdir.parseconfig("-c", "custom_tool_pytest_section.cfg")
+ config = pytester.parseconfig("-c", "custom_tool_pytest_section.cfg")
assert config.getini("custom") == "1"
- testdir.makefile(
+ pytester.makefile(
".toml",
custom="""
[tool.pytest.ini_options]
@@ -486,11 +502,11 @@ class TestConfigCmdlineParsing:
] # this is here on purpose, as it makes this an invalid '.ini' file
""",
)
- config = testdir.parseconfig("-c", "custom.toml")
+ config = pytester.parseconfig("-c", "custom.toml")
assert config.getini("custom") == "1"
- def test_absolute_win32_path(self, testdir):
- temp_ini_file = testdir.makefile(
+ def test_absolute_win32_path(self, pytester: Pytester) -> None:
+ temp_ini_file = pytester.makefile(
".ini",
custom="""
[pytest]
@@ -499,103 +515,103 @@ class TestConfigCmdlineParsing:
)
from os.path import normpath
- temp_ini_file = normpath(str(temp_ini_file))
- ret = pytest.main(["-c", temp_ini_file])
+ temp_ini_file_norm = normpath(str(temp_ini_file))
+ ret = pytest.main(["-c", temp_ini_file_norm])
assert ret == ExitCode.OK
class TestConfigAPI:
- def test_config_trace(self, testdir) -> None:
- config = testdir.parseconfig()
+ def test_config_trace(self, pytester: Pytester) -> None:
+ config = pytester.parseconfig()
values: List[str] = []
config.trace.root.setwriter(values.append)
config.trace("hello")
assert len(values) == 1
assert values[0] == "hello [config]\n"
- def test_config_getoption(self, testdir):
- testdir.makeconftest(
+ def test_config_getoption(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addoption("--hello", "-X", dest="hello")
"""
)
- config = testdir.parseconfig("--hello=this")
+ config = pytester.parseconfig("--hello=this")
for x in ("hello", "--hello", "-X"):
assert config.getoption(x) == "this"
pytest.raises(ValueError, config.getoption, "qweqwe")
- def test_config_getoption_unicode(self, testdir):
- testdir.makeconftest(
+ def test_config_getoption_unicode(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addoption('--hello', type=str)
"""
)
- config = testdir.parseconfig("--hello=this")
+ config = pytester.parseconfig("--hello=this")
assert config.getoption("hello") == "this"
- def test_config_getvalueorskip(self, testdir):
- config = testdir.parseconfig()
+ def test_config_getvalueorskip(self, pytester: Pytester) -> None:
+ config = pytester.parseconfig()
pytest.raises(pytest.skip.Exception, config.getvalueorskip, "hello")
verbose = config.getvalueorskip("verbose")
assert verbose == config.option.verbose
- def test_config_getvalueorskip_None(self, testdir):
- testdir.makeconftest(
+ def test_config_getvalueorskip_None(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addoption("--hello")
"""
)
- config = testdir.parseconfig()
+ config = pytester.parseconfig()
with pytest.raises(pytest.skip.Exception):
config.getvalueorskip("hello")
- def test_getoption(self, testdir):
- config = testdir.parseconfig()
+ def test_getoption(self, pytester: Pytester) -> None:
+ config = pytester.parseconfig()
with pytest.raises(ValueError):
config.getvalue("x")
assert config.getoption("x", 1) == 1
- def test_getconftest_pathlist(self, testdir, tmpdir):
+ def test_getconftest_pathlist(self, pytester: Pytester, tmpdir) -> None:
somepath = tmpdir.join("x", "y", "z")
p = tmpdir.join("conftest.py")
p.write("pathlist = ['.', %r]" % str(somepath))
- config = testdir.parseconfigure(p)
+ config = pytester.parseconfigure(p)
assert config._getconftest_pathlist("notexist", path=tmpdir) is None
- pl = config._getconftest_pathlist("pathlist", path=tmpdir)
+ pl = config._getconftest_pathlist("pathlist", path=tmpdir) or []
print(pl)
assert len(pl) == 2
assert pl[0] == tmpdir
assert pl[1] == somepath
@pytest.mark.parametrize("maybe_type", ["not passed", "None", '"string"'])
- def test_addini(self, testdir, maybe_type):
+ def test_addini(self, pytester: Pytester, maybe_type: str) -> None:
if maybe_type == "not passed":
type_string = ""
else:
type_string = f", {maybe_type}"
- testdir.makeconftest(
+ pytester.makeconftest(
f"""
def pytest_addoption(parser):
parser.addini("myname", "my new ini value"{type_string})
"""
)
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
myname=hello
"""
)
- config = testdir.parseconfig()
+ config = pytester.parseconfig()
val = config.getini("myname")
assert val == "hello"
pytest.raises(ValueError, config.getini, "other")
- def make_conftest_for_pathlist(self, testdir):
- testdir.makeconftest(
+ def make_conftest_for_pathlist(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addini("paths", "my new ini value", type="pathlist")
@@ -603,36 +619,36 @@ class TestConfigAPI:
"""
)
- def test_addini_pathlist_ini_files(self, testdir):
- self.make_conftest_for_pathlist(testdir)
- p = testdir.makeini(
+ def test_addini_pathlist_ini_files(self, pytester: Pytester) -> None:
+ self.make_conftest_for_pathlist(pytester)
+ p = pytester.makeini(
"""
[pytest]
paths=hello world/sub.py
"""
)
- self.check_config_pathlist(testdir, p)
+ self.check_config_pathlist(pytester, p)
- def test_addini_pathlist_pyproject_toml(self, testdir):
- self.make_conftest_for_pathlist(testdir)
- p = testdir.makepyprojecttoml(
+ def test_addini_pathlist_pyproject_toml(self, pytester: Pytester) -> None:
+ self.make_conftest_for_pathlist(pytester)
+ p = pytester.makepyprojecttoml(
"""
[tool.pytest.ini_options]
paths=["hello", "world/sub.py"]
"""
)
- self.check_config_pathlist(testdir, p)
+ self.check_config_pathlist(pytester, p)
- def check_config_pathlist(self, testdir, config_path):
- config = testdir.parseconfig()
+ def check_config_pathlist(self, pytester: Pytester, config_path: Path) -> None:
+ config = pytester.parseconfig()
values = config.getini("paths")
assert len(values) == 2
- assert values[0] == config_path.dirpath("hello")
- assert values[1] == config_path.dirpath("world/sub.py")
+ assert values[0] == config_path.parent.joinpath("hello")
+ assert values[1] == config_path.parent.joinpath("world/sub.py")
pytest.raises(ValueError, config.getini, "other")
- def make_conftest_for_args(self, testdir):
- testdir.makeconftest(
+ def make_conftest_for_args(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addini("args", "new args", type="args")
@@ -640,35 +656,35 @@ class TestConfigAPI:
"""
)
- def test_addini_args_ini_files(self, testdir):
- self.make_conftest_for_args(testdir)
- testdir.makeini(
+ def test_addini_args_ini_files(self, pytester: Pytester) -> None:
+ self.make_conftest_for_args(pytester)
+ pytester.makeini(
"""
[pytest]
args=123 "123 hello" "this"
"""
)
- self.check_config_args(testdir)
+ self.check_config_args(pytester)
- def test_addini_args_pyproject_toml(self, testdir):
- self.make_conftest_for_args(testdir)
- testdir.makepyprojecttoml(
+ def test_addini_args_pyproject_toml(self, pytester: Pytester) -> None:
+ self.make_conftest_for_args(pytester)
+ pytester.makepyprojecttoml(
"""
[tool.pytest.ini_options]
args = ["123", "123 hello", "this"]
"""
)
- self.check_config_args(testdir)
+ self.check_config_args(pytester)
- def check_config_args(self, testdir):
- config = testdir.parseconfig()
+ def check_config_args(self, pytester: Pytester) -> None:
+ config = pytester.parseconfig()
values = config.getini("args")
assert values == ["123", "123 hello", "this"]
values = config.getini("a2")
assert values == list("123")
- def make_conftest_for_linelist(self, testdir):
- testdir.makeconftest(
+ def make_conftest_for_linelist(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addini("xy", "", type="linelist")
@@ -676,29 +692,29 @@ class TestConfigAPI:
"""
)
- def test_addini_linelist_ini_files(self, testdir):
- self.make_conftest_for_linelist(testdir)
- testdir.makeini(
+ def test_addini_linelist_ini_files(self, pytester: Pytester) -> None:
+ self.make_conftest_for_linelist(pytester)
+ pytester.makeini(
"""
[pytest]
xy= 123 345
second line
"""
)
- self.check_config_linelist(testdir)
+ self.check_config_linelist(pytester)
- def test_addini_linelist_pprojecttoml(self, testdir):
- self.make_conftest_for_linelist(testdir)
- testdir.makepyprojecttoml(
+ def test_addini_linelist_pprojecttoml(self, pytester: Pytester) -> None:
+ self.make_conftest_for_linelist(pytester)
+ pytester.makepyprojecttoml(
"""
[tool.pytest.ini_options]
xy = ["123 345", "second line"]
"""
)
- self.check_config_linelist(testdir)
+ self.check_config_linelist(pytester)
- def check_config_linelist(self, testdir):
- config = testdir.parseconfig()
+ def check_config_linelist(self, pytester: Pytester) -> None:
+ config = pytester.parseconfig()
values = config.getini("xy")
assert len(values) == 2
assert values == ["123 345", "second line"]
@@ -708,38 +724,40 @@ class TestConfigAPI:
@pytest.mark.parametrize(
"str_val, bool_val", [("True", True), ("no", False), ("no-ini", True)]
)
- def test_addini_bool(self, testdir, str_val, bool_val):
- testdir.makeconftest(
+ def test_addini_bool(
+ self, pytester: Pytester, str_val: str, bool_val: bool
+ ) -> None:
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addini("strip", "", type="bool", default=True)
"""
)
if str_val != "no-ini":
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
strip=%s
"""
% str_val
)
- config = testdir.parseconfig()
+ config = pytester.parseconfig()
assert config.getini("strip") is bool_val
- def test_addinivalue_line_existing(self, testdir):
- testdir.makeconftest(
+ def test_addinivalue_line_existing(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addini("xy", "", type="linelist")
"""
)
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
xy= 123
"""
)
- config = testdir.parseconfig()
+ config = pytester.parseconfig()
values = config.getini("xy")
assert len(values) == 1
assert values == ["123"]
@@ -748,14 +766,14 @@ class TestConfigAPI:
assert len(values) == 2
assert values == ["123", "456"]
- def test_addinivalue_line_new(self, testdir):
- testdir.makeconftest(
+ def test_addinivalue_line_new(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addini("xy", "", type="linelist")
"""
)
- config = testdir.parseconfig()
+ config = pytester.parseconfig()
assert not config.getini("xy")
config.addinivalue_line("xy", "456")
values = config.getini("xy")
@@ -766,19 +784,17 @@ class TestConfigAPI:
assert len(values) == 2
assert values == ["456", "123"]
- def test_confcutdir_check_isdir(self, testdir):
+ def test_confcutdir_check_isdir(self, pytester: Pytester) -> None:
"""Give an error if --confcutdir is not a valid directory (#2078)"""
exp_match = r"^--confcutdir must be a directory, given: "
with pytest.raises(pytest.UsageError, match=exp_match):
- testdir.parseconfig(
- "--confcutdir", testdir.tmpdir.join("file").ensure(file=1)
- )
+ pytester.parseconfig("--confcutdir", pytester.path.joinpath("file"))
with pytest.raises(pytest.UsageError, match=exp_match):
- testdir.parseconfig("--confcutdir", testdir.tmpdir.join("inexistant"))
- config = testdir.parseconfig(
- "--confcutdir", testdir.tmpdir.join("dir").ensure(dir=1)
- )
- assert config.getoption("confcutdir") == str(testdir.tmpdir.join("dir"))
+ pytester.parseconfig("--confcutdir", pytester.path.joinpath("inexistant"))
+
+ p = pytester.mkdir("dir")
+ config = pytester.parseconfig("--confcutdir", p)
+ assert config.getoption("confcutdir") == str(p)
@pytest.mark.parametrize(
"names, expected",
@@ -796,12 +812,12 @@ class TestConfigAPI:
(["source/python/bar/__init__.py", "setup.py"], ["bar"]),
],
)
- def test_iter_rewritable_modules(self, names, expected):
+ def test_iter_rewritable_modules(self, names, expected) -> None:
assert list(_iter_rewritable_modules(names)) == expected
class TestConfigFromdictargs:
- def test_basic_behavior(self, _sys_snapshot):
+ def test_basic_behavior(self, _sys_snapshot) -> None:
option_dict = {"verbose": 444, "foo": "bar", "capture": "no"}
args = ["a", "b"]
@@ -824,8 +840,12 @@ class TestConfigFromdictargs:
assert config.option.verbose == 4
assert config.option.capture == "no"
- def test_inifilename(self, tmpdir):
- tmpdir.join("foo/bar.ini").ensure().write(
+ def test_inifilename(self, tmp_path: Path) -> None:
+ d1 = tmp_path.joinpath("foo")
+ d1.mkdir()
+ p1 = d1.joinpath("bar.ini")
+ p1.touch()
+ p1.write_text(
textwrap.dedent(
"""\
[pytest]
@@ -837,8 +857,11 @@ class TestConfigFromdictargs:
inifile = "../../foo/bar.ini"
option_dict = {"inifilename": inifile, "capture": "no"}
- cwd = tmpdir.join("a/b")
- cwd.join("pytest.ini").ensure().write(
+ cwd = tmp_path.joinpath("a/b")
+ cwd.mkdir(parents=True)
+ p2 = cwd.joinpath("pytest.ini")
+ p2.touch()
+ p2.write_text(
textwrap.dedent(
"""\
[pytest]
@@ -847,7 +870,8 @@ class TestConfigFromdictargs:
"""
)
)
- with cwd.ensure(dir=True).as_cwd():
+ with MonkeyPatch.context() as mp:
+ mp.chdir(cwd)
config = Config.fromdictargs(option_dict, ())
inipath = py.path.local(inifile)
@@ -861,18 +885,20 @@ class TestConfigFromdictargs:
assert config.inicfg.get("should_not_be_set") is None
-def test_options_on_small_file_do_not_blow_up(testdir) -> None:
+def test_options_on_small_file_do_not_blow_up(pytester: Pytester) -> None:
def runfiletest(opts: Sequence[str]) -> None:
- reprec = testdir.inline_run(*opts)
+ reprec = pytester.inline_run(*opts)
passed, skipped, failed = reprec.countoutcomes()
assert failed == 2
assert skipped == passed == 0
- path = testdir.makepyfile(
- """
+ path = str(
+ pytester.makepyfile(
+ """
def test_f1(): assert 0
def test_f2(): assert 0
"""
+ )
)
runfiletest([path])
@@ -887,7 +913,9 @@ def test_options_on_small_file_do_not_blow_up(testdir) -> None:
runfiletest(["-v", "-v", path])
-def test_preparse_ordering_with_setuptools(testdir, monkeypatch):
+def test_preparse_ordering_with_setuptools(
+ pytester: Pytester, monkeypatch: MonkeyPatch
+) -> None:
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
class EntryPoint:
@@ -909,18 +937,20 @@ def test_preparse_ordering_with_setuptools(testdir, monkeypatch):
return (Dist,)
monkeypatch.setattr(importlib_metadata, "distributions", my_dists)
- testdir.makeconftest(
+ pytester.makeconftest(
"""
pytest_plugins = "mytestplugin",
"""
)
monkeypatch.setenv("PYTEST_PLUGINS", "mytestplugin")
- config = testdir.parseconfig()
+ config = pytester.parseconfig()
plugin = config.pluginmanager.getplugin("mytestplugin")
assert plugin.x == 42
-def test_setuptools_importerror_issue1479(testdir, monkeypatch):
+def test_setuptools_importerror_issue1479(
+ pytester: Pytester, monkeypatch: MonkeyPatch
+) -> None:
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
class DummyEntryPoint:
@@ -941,10 +971,12 @@ def test_setuptools_importerror_issue1479(testdir, monkeypatch):
monkeypatch.setattr(importlib_metadata, "distributions", distributions)
with pytest.raises(ImportError):
- testdir.parseconfig()
+ pytester.parseconfig()
-def test_importlib_metadata_broken_distribution(testdir, monkeypatch):
+def test_importlib_metadata_broken_distribution(
+ pytester: Pytester, monkeypatch: MonkeyPatch
+) -> None:
"""Integration test for broken distributions with 'files' metadata being None (#5389)"""
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
@@ -965,11 +997,13 @@ def test_importlib_metadata_broken_distribution(testdir, monkeypatch):
return (Distribution(),)
monkeypatch.setattr(importlib_metadata, "distributions", distributions)
- testdir.parseconfig()
+ pytester.parseconfig()
@pytest.mark.parametrize("block_it", [True, False])
-def test_plugin_preparse_prevents_setuptools_loading(testdir, monkeypatch, block_it):
+def test_plugin_preparse_prevents_setuptools_loading(
+ pytester: Pytester, monkeypatch: MonkeyPatch, block_it: bool
+) -> None:
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
plugin_module_placeholder = object()
@@ -992,7 +1026,7 @@ def test_plugin_preparse_prevents_setuptools_loading(testdir, monkeypatch, block
monkeypatch.setattr(importlib_metadata, "distributions", distributions)
args = ("-p", "no:mytestplugin") if block_it else ()
- config = testdir.parseconfig(*args)
+ config = pytester.parseconfig(*args)
config.pluginmanager.import_plugin("mytestplugin")
if block_it:
assert "mytestplugin" not in sys.modules
@@ -1006,7 +1040,12 @@ def test_plugin_preparse_prevents_setuptools_loading(testdir, monkeypatch, block
@pytest.mark.parametrize(
"parse_args,should_load", [(("-p", "mytestplugin"), True), ((), False)]
)
-def test_disable_plugin_autoload(testdir, monkeypatch, parse_args, should_load):
+def test_disable_plugin_autoload(
+ pytester: Pytester,
+ monkeypatch: MonkeyPatch,
+ parse_args: Union[Tuple[str, str], Tuple[()]],
+ should_load: bool,
+) -> None:
class DummyEntryPoint:
project_name = name = "mytestplugin"
group = "pytest11"
@@ -1035,8 +1074,8 @@ def test_disable_plugin_autoload(testdir, monkeypatch, parse_args, should_load):
monkeypatch.setenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", "1")
monkeypatch.setattr(importlib_metadata, "distributions", distributions)
- monkeypatch.setitem(sys.modules, "mytestplugin", PseudoPlugin())
- config = testdir.parseconfig(*parse_args)
+ monkeypatch.setitem(sys.modules, "mytestplugin", PseudoPlugin()) # type: ignore[misc]
+ config = pytester.parseconfig(*parse_args)
has_loaded = config.pluginmanager.get_plugin("mytestplugin") is not None
assert has_loaded == should_load
if should_load:
@@ -1045,9 +1084,9 @@ def test_disable_plugin_autoload(testdir, monkeypatch, parse_args, should_load):
assert PseudoPlugin.attrs_used == []
-def test_plugin_loading_order(testdir):
+def test_plugin_loading_order(pytester: Pytester) -> None:
"""Test order of plugin loading with `-p`."""
- p1 = testdir.makepyfile(
+ p1 = pytester.makepyfile(
"""
def test_terminal_plugin(request):
import myplugin
@@ -1066,37 +1105,37 @@ def test_plugin_loading_order(testdir):
"""
},
)
- testdir.syspathinsert()
- result = testdir.runpytest("-p", "myplugin", str(p1))
+ pytester.syspathinsert()
+ result = pytester.runpytest("-p", "myplugin", str(p1))
assert result.ret == 0
-def test_cmdline_processargs_simple(testdir):
- testdir.makeconftest(
+def test_cmdline_processargs_simple(pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_cmdline_preparse(args):
args.append("-h")
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(["*pytest*", "*-h*"])
-def test_invalid_options_show_extra_information(testdir):
+def test_invalid_options_show_extra_information(pytester: Pytester) -> None:
"""Display extra information when pytest exits due to unrecognized
options in the command-line."""
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
addopts = --invalid-option
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stderr.fnmatch_lines(
[
"*error: unrecognized arguments: --invalid-option*",
- "* inifile: %s*" % testdir.tmpdir.join("tox.ini"),
- "* rootdir: %s*" % testdir.tmpdir,
+ "* inifile: %s*" % pytester.path.joinpath("tox.ini"),
+ "* rootdir: %s*" % pytester.path,
]
)
@@ -1110,42 +1149,49 @@ def test_invalid_options_show_extra_information(testdir):
["-v", "dir2", "dir1"],
],
)
-def test_consider_args_after_options_for_rootdir(testdir, args):
+def test_consider_args_after_options_for_rootdir(
+ pytester: Pytester, args: List[str]
+) -> None:
"""
Consider all arguments in the command-line for rootdir
discovery, even if they happen to occur after an option. #949
"""
# replace "dir1" and "dir2" from "args" into their real directory
- root = testdir.tmpdir.mkdir("myroot")
- d1 = root.mkdir("dir1")
- d2 = root.mkdir("dir2")
+ root = pytester.mkdir("myroot")
+ d1 = root.joinpath("dir1")
+ d1.mkdir()
+ d2 = root.joinpath("dir2")
+ d2.mkdir()
for i, arg in enumerate(args):
if arg == "dir1":
- args[i] = d1
+ args[i] = str(d1)
elif arg == "dir2":
- args[i] = d2
- with root.as_cwd():
- result = testdir.runpytest(*args)
+ args[i] = str(d2)
+ with MonkeyPatch.context() as mp:
+ mp.chdir(root)
+ result = pytester.runpytest(*args)
result.stdout.fnmatch_lines(["*rootdir: *myroot"])
-def test_toolongargs_issue224(testdir):
- result = testdir.runpytest("-m", "hello" * 500)
+def test_toolongargs_issue224(pytester: Pytester) -> None:
+ result = pytester.runpytest("-m", "hello" * 500)
assert result.ret == ExitCode.NO_TESTS_COLLECTED
-def test_config_in_subdirectory_colon_command_line_issue2148(testdir):
+def test_config_in_subdirectory_colon_command_line_issue2148(
+ pytester: Pytester,
+) -> None:
conftest_source = """
def pytest_addoption(parser):
parser.addini('foo', 'foo')
"""
- testdir.makefile(
+ pytester.makefile(
".ini",
**{"pytest": "[pytest]\nfoo = root", "subdir/pytest": "[pytest]\nfoo = subdir"},
)
- testdir.makepyfile(
+ pytester.makepyfile(
**{
"conftest": conftest_source,
"subdir/conftest": conftest_source,
@@ -1156,12 +1202,12 @@ def test_config_in_subdirectory_colon_command_line_issue2148(testdir):
}
)
- result = testdir.runpytest("subdir/test_foo.py::test_foo")
+ result = pytester.runpytest("subdir/test_foo.py::test_foo")
assert result.ret == 0
-def test_notify_exception(testdir, capfd):
- config = testdir.parseconfig()
+def test_notify_exception(pytester: Pytester, capfd) -> None:
+ config = pytester.parseconfig()
with pytest.raises(ValueError) as excinfo:
raise ValueError(1)
config.notify_exception(excinfo, config.option)
@@ -1177,7 +1223,7 @@ def test_notify_exception(testdir, capfd):
_, err = capfd.readouterr()
assert not err
- config = testdir.parseconfig("-p", "no:terminal")
+ config = pytester.parseconfig("-p", "no:terminal")
with pytest.raises(ValueError) as excinfo:
raise ValueError(1)
config.notify_exception(excinfo, config.option)
@@ -1185,9 +1231,9 @@ def test_notify_exception(testdir, capfd):
assert "ValueError" in err
-def test_no_terminal_discovery_error(testdir):
- testdir.makepyfile("raise TypeError('oops!')")
- result = testdir.runpytest("-p", "no:terminal", "--collect-only")
+def test_no_terminal_discovery_error(pytester: Pytester) -> None:
+ pytester.makepyfile("raise TypeError('oops!')")
+ result = pytester.runpytest("-p", "no:terminal", "--collect-only")
assert result.ret == ExitCode.INTERRUPTED
@@ -1226,10 +1272,10 @@ def test_get_plugin_specs_as_list() -> None:
assert _get_plugin_specs_as_list(("foo", "bar")) == ["foo", "bar"]
-def test_collect_pytest_prefix_bug_integration(testdir):
+def test_collect_pytest_prefix_bug_integration(pytester: Pytester) -> None:
"""Integration test for issue #3775"""
- p = testdir.copy_example("config/collect_pytest_prefix")
- result = testdir.runpytest(p)
+ p = pytester.copy_example("config/collect_pytest_prefix")
+ result = pytester.runpytest(p)
result.stdout.fnmatch_lines(["* 1 passed *"])
@@ -1396,9 +1442,9 @@ class TestRootdir:
class TestOverrideIniArgs:
@pytest.mark.parametrize("name", "setup.cfg tox.ini pytest.ini".split())
- def test_override_ini_names(self, testdir, name):
+ def test_override_ini_names(self, pytester: Pytester, name: str) -> None:
section = "[pytest]" if name != "setup.cfg" else "[tool:pytest]"
- testdir.tmpdir.join(name).write(
+ pytester.path.joinpath(name).write_text(
textwrap.dedent(
"""
{section}
@@ -1407,40 +1453,40 @@ class TestOverrideIniArgs:
)
)
)
- testdir.makeconftest(
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addini("custom", "")"""
)
- testdir.makepyfile(
+ pytester.makepyfile(
"""
def test_pass(pytestconfig):
ini_val = pytestconfig.getini("custom")
print('\\ncustom_option:%s\\n' % ini_val)"""
)
- result = testdir.runpytest("--override-ini", "custom=2.0", "-s")
+ result = pytester.runpytest("--override-ini", "custom=2.0", "-s")
assert result.ret == 0
result.stdout.fnmatch_lines(["custom_option:2.0"])
- result = testdir.runpytest(
+ result = pytester.runpytest(
"--override-ini", "custom=2.0", "--override-ini=custom=3.0", "-s"
)
assert result.ret == 0
result.stdout.fnmatch_lines(["custom_option:3.0"])
- def test_override_ini_pathlist(self, testdir):
- testdir.makeconftest(
+ def test_override_ini_pathlist(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
parser.addini("paths", "my new ini value", type="pathlist")"""
)
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
paths=blah.py"""
)
- testdir.makepyfile(
+ pytester.makepyfile(
"""
import py.path
def test_pathlist(pytestconfig):
@@ -1449,13 +1495,13 @@ class TestOverrideIniArgs:
for cpf in config_paths:
print('\\nuser_path:%s' % cpf.basename)"""
)
- result = testdir.runpytest(
+ result = pytester.runpytest(
"--override-ini", "paths=foo/bar1.py foo/bar2.py", "-s"
)
result.stdout.fnmatch_lines(["user_path:bar1.py", "user_path:bar2.py"])
- def test_override_multiple_and_default(self, testdir):
- testdir.makeconftest(
+ def test_override_multiple_and_default(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_addoption(parser):
addini = parser.addini
@@ -1464,14 +1510,14 @@ class TestOverrideIniArgs:
addini("custom_option_3", "", default=False, type="bool")
addini("custom_option_4", "", default=True, type="bool")"""
)
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
custom_option_1=custom_option_1
custom_option_2=custom_option_2
"""
)
- testdir.makepyfile(
+ pytester.makepyfile(
"""
def test_multiple_options(pytestconfig):
prefix = "custom_option"
@@ -1480,7 +1526,7 @@ class TestOverrideIniArgs:
print('\\nini%d:%s' % (x, ini_value))
"""
)
- result = testdir.runpytest(
+ result = pytester.runpytest(
"--override-ini",
"custom_option_1=fulldir=/tmp/user1",
"-o",
@@ -1500,14 +1546,14 @@ class TestOverrideIniArgs:
]
)
- def test_override_ini_usage_error_bad_style(self, testdir):
- testdir.makeini(
+ def test_override_ini_usage_error_bad_style(self, pytester: Pytester) -> None:
+ pytester.makeini(
"""
[pytest]
xdist_strict=False
"""
)
- result = testdir.runpytest("--override-ini", "xdist_strict", "True")
+ result = pytester.runpytest("--override-ini", "xdist_strict", "True")
result.stderr.fnmatch_lines(
[
"ERROR: -o/--override-ini expects option=value style (got: 'xdist_strict').",
@@ -1515,32 +1561,38 @@ class TestOverrideIniArgs:
)
@pytest.mark.parametrize("with_ini", [True, False])
- def test_override_ini_handled_asap(self, testdir, with_ini):
+ def test_override_ini_handled_asap(
+ self, pytester: Pytester, with_ini: bool
+ ) -> None:
"""-o should be handled as soon as possible and always override what's in ini files (#2238)"""
if with_ini:
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
python_files=test_*.py
"""
)
- testdir.makepyfile(
+ pytester.makepyfile(
unittest_ini_handle="""
def test():
pass
"""
)
- result = testdir.runpytest("--override-ini", "python_files=unittest_*.py")
+ result = pytester.runpytest("--override-ini", "python_files=unittest_*.py")
result.stdout.fnmatch_lines(["*1 passed in*"])
- def test_addopts_before_initini(self, monkeypatch, _config_for_test, _sys_snapshot):
+ def test_addopts_before_initini(
+ self, monkeypatch: MonkeyPatch, _config_for_test, _sys_snapshot
+ ) -> None:
cache_dir = ".custom_cache"
monkeypatch.setenv("PYTEST_ADDOPTS", "-o cache_dir=%s" % cache_dir)
config = _config_for_test
config._preparse([], addopts=True)
assert config._override_ini == ["cache_dir=%s" % cache_dir]
- def test_addopts_from_env_not_concatenated(self, monkeypatch, _config_for_test):
+ def test_addopts_from_env_not_concatenated(
+ self, monkeypatch: MonkeyPatch, _config_for_test
+ ) -> None:
"""PYTEST_ADDOPTS should not take values from normal args (#4265)."""
monkeypatch.setenv("PYTEST_ADDOPTS", "-o")
config = _config_for_test
@@ -1551,32 +1603,34 @@ class TestOverrideIniArgs:
in excinfo.value.args[0]
)
- def test_addopts_from_ini_not_concatenated(self, testdir):
+ def test_addopts_from_ini_not_concatenated(self, pytester: Pytester) -> None:
"""`addopts` from ini should not take values from normal args (#4265)."""
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
addopts=-o
"""
)
- result = testdir.runpytest("cache_dir=ignored")
+ result = pytester.runpytest("cache_dir=ignored")
result.stderr.fnmatch_lines(
[
"%s: error: argument -o/--override-ini: expected one argument (via addopts config)"
- % (testdir.request.config._parser.optparser.prog,)
+ % (pytester._request.config._parser.optparser.prog,)
]
)
assert result.ret == _pytest.config.ExitCode.USAGE_ERROR
- def test_override_ini_does_not_contain_paths(self, _config_for_test, _sys_snapshot):
+ def test_override_ini_does_not_contain_paths(
+ self, _config_for_test, _sys_snapshot
+ ) -> None:
"""Check that -o no longer swallows all options after it (#3103)"""
config = _config_for_test
config._preparse(["-o", "cache_dir=/cache", "/some/test/path"])
assert config._override_ini == ["cache_dir=/cache"]
- def test_multiple_override_ini_options(self, testdir):
+ def test_multiple_override_ini_options(self, pytester: Pytester) -> None:
"""Ensure a file path following a '-o' option does not generate an error (#3103)"""
- testdir.makepyfile(
+ pytester.makepyfile(
**{
"conftest.py": """
def pytest_addoption(parser):
@@ -1594,19 +1648,19 @@ class TestOverrideIniArgs:
""",
}
)
- result = testdir.runpytest("-o", "foo=1", "-o", "bar=0", "test_foo.py")
+ result = pytester.runpytest("-o", "foo=1", "-o", "bar=0", "test_foo.py")
assert "ERROR:" not in result.stderr.str()
result.stdout.fnmatch_lines(["collected 1 item", "*= 1 passed in *="])
-def test_help_via_addopts(testdir):
- testdir.makeini(
+def test_help_via_addopts(pytester: Pytester) -> None:
+ pytester.makeini(
"""
[pytest]
addopts = --unknown-option-should-allow-for-help --help
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
assert result.ret == 0
result.stdout.fnmatch_lines(
[
@@ -1618,8 +1672,8 @@ def test_help_via_addopts(testdir):
)
-def test_help_and_version_after_argument_error(testdir):
- testdir.makeconftest(
+def test_help_and_version_after_argument_error(pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def validate(arg):
raise argparse.ArgumentTypeError("argerror")
@@ -1632,13 +1686,13 @@ def test_help_and_version_after_argument_error(testdir):
)
"""
)
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
addopts = --invalid-option-should-allow-for-help
"""
)
- result = testdir.runpytest("--help")
+ result = pytester.runpytest("--help")
result.stdout.fnmatch_lines(
[
"usage: *",
@@ -1650,19 +1704,19 @@ def test_help_and_version_after_argument_error(testdir):
[
"ERROR: usage: *",
"%s: error: argument --invalid-option-should-allow-for-help: expected one argument"
- % (testdir.request.config._parser.optparser.prog,),
+ % (pytester._request.config._parser.optparser.prog,),
]
)
# Does not display full/default help.
assert "to see available markers type: pytest --markers" not in result.stdout.lines
assert result.ret == ExitCode.USAGE_ERROR
- result = testdir.runpytest("--version")
+ result = pytester.runpytest("--version")
result.stderr.fnmatch_lines([f"pytest {pytest.__version__}"])
assert result.ret == ExitCode.USAGE_ERROR
-def test_help_formatter_uses_py_get_terminal_width(monkeypatch):
+def test_help_formatter_uses_py_get_terminal_width(monkeypatch: MonkeyPatch) -> None:
from _pytest.config.argparsing import DropShorterLongHelpFormatter
monkeypatch.setenv("COLUMNS", "90")
@@ -1677,39 +1731,39 @@ def test_help_formatter_uses_py_get_terminal_width(monkeypatch):
assert formatter._width == 42
-def test_config_does_not_load_blocked_plugin_from_args(testdir):
+def test_config_does_not_load_blocked_plugin_from_args(pytester: Pytester) -> None:
"""This tests that pytest's config setup handles "-p no:X"."""
- p = testdir.makepyfile("def test(capfd): pass")
- result = testdir.runpytest(str(p), "-pno:capture")
+ p = pytester.makepyfile("def test(capfd): pass")
+ result = pytester.runpytest(str(p), "-pno:capture")
result.stdout.fnmatch_lines(["E fixture 'capfd' not found"])
assert result.ret == ExitCode.TESTS_FAILED
- result = testdir.runpytest(str(p), "-pno:capture", "-s")
+ result = pytester.runpytest(str(p), "-pno:capture", "-s")
result.stderr.fnmatch_lines(["*: error: unrecognized arguments: -s"])
assert result.ret == ExitCode.USAGE_ERROR
-def test_invocation_args(testdir):
+def test_invocation_args(pytester: Pytester) -> None:
"""Ensure that Config.invocation_* arguments are correctly defined"""
class DummyPlugin:
pass
- p = testdir.makepyfile("def test(): pass")
+ p = pytester.makepyfile("def test(): pass")
plugin = DummyPlugin()
- rec = testdir.inline_run(p, "-v", plugins=[plugin])
+ rec = pytester.inline_run(p, "-v", plugins=[plugin])
calls = rec.getcalls("pytest_runtest_protocol")
assert len(calls) == 1
call = calls[0]
config = call.item.config
- assert config.invocation_params.args == (p, "-v")
- assert config.invocation_params.dir == Path(str(testdir.tmpdir))
+ assert config.invocation_params.args == (str(p), "-v")
+ assert config.invocation_params.dir == pytester.path
plugins = config.invocation_params.plugins
assert len(plugins) == 2
assert plugins[0] is plugin
- assert type(plugins[1]).__name__ == "Collect" # installed by testdir.inline_run()
+ assert type(plugins[1]).__name__ == "Collect" # installed by pytester.inline_run()
# args cannot be None
with pytest.raises(TypeError):
@@ -1724,7 +1778,7 @@ def test_invocation_args(testdir):
if x not in _pytest.config.essential_plugins
],
)
-def test_config_blocked_default_plugins(testdir, plugin):
+def test_config_blocked_default_plugins(pytester: Pytester, plugin: str) -> None:
if plugin == "debugging":
# Fixed in xdist master (after 1.27.0).
# https://github.com/pytest-dev/pytest-xdist/pull/422
@@ -1735,8 +1789,8 @@ def test_config_blocked_default_plugins(testdir, plugin):
else:
pytest.skip("does not work with xdist currently")
- p = testdir.makepyfile("def test(): pass")
- result = testdir.runpytest(str(p), "-pno:%s" % plugin)
+ p = pytester.makepyfile("def test(): pass")
+ result = pytester.runpytest(str(p), "-pno:%s" % plugin)
if plugin == "python":
assert result.ret == ExitCode.USAGE_ERROR
@@ -1752,8 +1806,8 @@ def test_config_blocked_default_plugins(testdir, plugin):
if plugin != "terminal":
result.stdout.fnmatch_lines(["* 1 passed in *"])
- p = testdir.makepyfile("def test(): assert 0")
- result = testdir.runpytest(str(p), "-pno:%s" % plugin)
+ p = pytester.makepyfile("def test(): assert 0")
+ result = pytester.runpytest(str(p), "-pno:%s" % plugin)
assert result.ret == ExitCode.TESTS_FAILED
if plugin != "terminal":
result.stdout.fnmatch_lines(["* 1 failed in *"])
@@ -1762,8 +1816,8 @@ def test_config_blocked_default_plugins(testdir, plugin):
class TestSetupCfg:
- def test_pytest_setup_cfg_unsupported(self, testdir):
- testdir.makefile(
+ def test_pytest_setup_cfg_unsupported(self, pytester: Pytester) -> None:
+ pytester.makefile(
".cfg",
setup="""
[pytest]
@@ -1771,10 +1825,10 @@ class TestSetupCfg:
""",
)
with pytest.raises(pytest.fail.Exception):
- testdir.runpytest()
+ pytester.runpytest()
- def test_pytest_custom_cfg_unsupported(self, testdir):
- testdir.makefile(
+ def test_pytest_custom_cfg_unsupported(self, pytester: Pytester) -> None:
+ pytester.makefile(
".cfg",
custom="""
[pytest]
@@ -1782,33 +1836,35 @@ class TestSetupCfg:
""",
)
with pytest.raises(pytest.fail.Exception):
- testdir.runpytest("-c", "custom.cfg")
+ pytester.runpytest("-c", "custom.cfg")
class TestPytestPluginsVariable:
- def test_pytest_plugins_in_non_top_level_conftest_unsupported(self, testdir):
- testdir.makepyfile(
+ def test_pytest_plugins_in_non_top_level_conftest_unsupported(
+ self, pytester: Pytester
+ ) -> None:
+ pytester.makepyfile(
**{
"subdirectory/conftest.py": """
pytest_plugins=['capture']
"""
}
)
- testdir.makepyfile(
+ pytester.makepyfile(
"""
def test_func():
pass
"""
)
- res = testdir.runpytest()
+ res = pytester.runpytest()
assert res.ret == 2
msg = "Defining 'pytest_plugins' in a non-top-level conftest is no longer supported"
res.stdout.fnmatch_lines([f"*{msg}*", f"*subdirectory{os.sep}conftest.py*"])
@pytest.mark.parametrize("use_pyargs", [True, False])
def test_pytest_plugins_in_non_top_level_conftest_unsupported_pyargs(
- self, testdir, use_pyargs
- ):
+ self, pytester: Pytester, use_pyargs: bool
+ ) -> None:
"""When using --pyargs, do not emit the warning about non-top-level conftest warnings (#4039, #4044)"""
files = {
@@ -1819,11 +1875,11 @@ class TestPytestPluginsVariable:
"src/pkg/sub/conftest.py": "pytest_plugins=['capture']",
"src/pkg/sub/test_bar.py": "def test(): pass",
}
- testdir.makepyfile(**files)
- testdir.syspathinsert(testdir.tmpdir.join("src"))
+ pytester.makepyfile(**files)
+ pytester.syspathinsert(pytester.path.joinpath("src"))
args = ("--pyargs", "pkg") if use_pyargs else ()
- res = testdir.runpytest(*args)
+ res = pytester.runpytest(*args)
assert res.ret == (0 if use_pyargs else 2)
msg = (
msg
@@ -1834,33 +1890,35 @@ class TestPytestPluginsVariable:
res.stdout.fnmatch_lines([f"*{msg}*"])
def test_pytest_plugins_in_non_top_level_conftest_unsupported_no_top_level_conftest(
- self, testdir
- ):
- subdirectory = testdir.tmpdir.join("subdirectory")
+ self, pytester: Pytester
+ ) -> None:
+ subdirectory = pytester.path.joinpath("subdirectory")
subdirectory.mkdir()
- testdir.makeconftest(
+ pytester.makeconftest(
"""
pytest_plugins=['capture']
"""
)
- testdir.tmpdir.join("conftest.py").move(subdirectory.join("conftest.py"))
+ pytester.path.joinpath("conftest.py").rename(
+ subdirectory.joinpath("conftest.py")
+ )
- testdir.makepyfile(
+ pytester.makepyfile(
"""
def test_func():
pass
"""
)
- res = testdir.runpytest_subprocess()
+ res = pytester.runpytest_subprocess()
assert res.ret == 2
msg = "Defining 'pytest_plugins' in a non-top-level conftest is no longer supported"
res.stdout.fnmatch_lines([f"*{msg}*", f"*subdirectory{os.sep}conftest.py*"])
def test_pytest_plugins_in_non_top_level_conftest_unsupported_no_false_positives(
- self, testdir
- ):
- testdir.makepyfile(
+ self, pytester: Pytester
+ ) -> None:
+ pytester.makepyfile(
"def test_func(): pass",
**{
"subdirectory/conftest": "pass",
@@ -1871,13 +1929,13 @@ class TestPytestPluginsVariable:
""",
},
)
- res = testdir.runpytest_subprocess()
+ res = pytester.runpytest_subprocess()
assert res.ret == 0
msg = "Defining 'pytest_plugins' in a non-top-level conftest is no longer supported"
assert msg not in res.stdout.str()
-def test_conftest_import_error_repr(tmpdir):
+def test_conftest_import_error_repr(tmpdir: py.path.local) -> None:
"""`ConftestImportFailure` should use a short error message and readable
path to the failed conftest.py file."""
path = tmpdir.join("foo/conftest.py")
@@ -1893,7 +1951,7 @@ def test_conftest_import_error_repr(tmpdir):
raise ConftestImportFailure(path, exc_info) from exc
-def test_strtobool():
+def test_strtobool() -> None:
assert _strtobool("YES")
assert not _strtobool("NO")
with pytest.raises(ValueError):
diff --git a/testing/test_terminal.py b/testing/test_terminal.py
index 0b861f25a..a4d22d2aa 100644
--- a/testing/test_terminal.py
+++ b/testing/test_terminal.py
@@ -20,7 +20,7 @@ from _pytest._io.wcwidth import wcswidth
from _pytest.config import Config
from _pytest.config import ExitCode
from _pytest.monkeypatch import MonkeyPatch
-from _pytest.pytester import Testdir
+from _pytest.pytester import Pytester
from _pytest.reports import BaseReport
from _pytest.reports import CollectReport
from _pytest.terminal import _folded_skips
@@ -76,8 +76,8 @@ def test_plugin_nameversion(input, expected):
class TestTerminal:
- def test_pass_skip_fail(self, testdir, option):
- testdir.makepyfile(
+ def test_pass_skip_fail(self, pytester: Pytester, option) -> None:
+ pytester.makepyfile(
"""
import pytest
def test_ok():
@@ -88,7 +88,7 @@ class TestTerminal:
assert 0
"""
)
- result = testdir.runpytest(*option.args)
+ result = pytester.runpytest(*option.args)
if option.verbosity > 0:
result.stdout.fnmatch_lines(
[
@@ -105,16 +105,16 @@ class TestTerminal:
[" def test_func():", "> assert 0", "E assert 0"]
)
- def test_internalerror(self, testdir, linecomp):
- modcol = testdir.getmodulecol("def test_one(): pass")
+ def test_internalerror(self, pytester: Pytester, linecomp) -> None:
+ modcol = pytester.getmodulecol("def test_one(): pass")
rep = TerminalReporter(modcol.config, file=linecomp.stringio)
with pytest.raises(ValueError) as excinfo:
raise ValueError("hello")
rep.pytest_internalerror(excinfo.getrepr())
linecomp.assert_contains_lines(["INTERNALERROR> *ValueError*hello*"])
- def test_writeline(self, testdir, linecomp):
- modcol = testdir.getmodulecol("def test_one(): pass")
+ def test_writeline(self, pytester: Pytester, linecomp) -> None:
+ modcol = pytester.getmodulecol("def test_one(): pass")
rep = TerminalReporter(modcol.config, file=linecomp.stringio)
rep.write_fspath_result(modcol.nodeid, ".")
rep.write_line("hello world")
@@ -123,8 +123,8 @@ class TestTerminal:
assert lines[1].endswith(modcol.name + " .")
assert lines[2] == "hello world"
- def test_show_runtest_logstart(self, testdir, linecomp):
- item = testdir.getitem("def test_func(): pass")
+ def test_show_runtest_logstart(self, pytester: Pytester, linecomp) -> None:
+ item = pytester.getitem("def test_func(): pass")
tr = TerminalReporter(item.config, file=linecomp.stringio)
item.config.pluginmanager.register(tr)
location = item.reportinfo()
@@ -133,7 +133,9 @@ class TestTerminal:
)
linecomp.assert_contains_lines(["*test_show_runtest_logstart.py*"])
- def test_runtest_location_shown_before_test_starts(self, pytester):
+ def test_runtest_location_shown_before_test_starts(
+ self, pytester: Pytester
+ ) -> None:
pytester.makepyfile(
"""
def test_1():
@@ -146,7 +148,9 @@ class TestTerminal:
child.sendeof()
child.kill(15)
- def test_report_collect_after_half_a_second(self, pytester, monkeypatch):
+ def test_report_collect_after_half_a_second(
+ self, pytester: Pytester, monkeypatch: MonkeyPatch
+ ) -> None:
"""Test for "collecting" being updated after 0.5s"""
pytester.makepyfile(
@@ -173,8 +177,10 @@ class TestTerminal:
rest = child.read().decode("utf8")
assert "= \x1b[32m\x1b[1m2 passed\x1b[0m\x1b[32m in" in rest
- def test_itemreport_subclasses_show_subclassed_file(self, testdir):
- testdir.makepyfile(
+ def test_itemreport_subclasses_show_subclassed_file(
+ self, pytester: Pytester
+ ) -> None:
+ pytester.makepyfile(
**{
"tests/test_p1": """
class BaseTests(object):
@@ -197,10 +203,10 @@ class TestTerminal:
""",
}
)
- result = testdir.runpytest("tests/test_p2.py", "--rootdir=tests")
+ result = pytester.runpytest("tests/test_p2.py", "--rootdir=tests")
result.stdout.fnmatch_lines(["tests/test_p2.py .*", "=* 1 passed in *"])
- result = testdir.runpytest("-vv", "-rA", "tests/test_p2.py", "--rootdir=tests")
+ result = pytester.runpytest("-vv", "-rA", "tests/test_p2.py", "--rootdir=tests")
result.stdout.fnmatch_lines(
[
"tests/test_p2.py::TestMore::test_p1 <- test_p1.py PASSED *",
@@ -208,7 +214,7 @@ class TestTerminal:
"PASSED tests/test_p2.py::TestMore::test_p1",
]
)
- result = testdir.runpytest("-vv", "-rA", "tests/test_p3.py", "--rootdir=tests")
+ result = pytester.runpytest("-vv", "-rA", "tests/test_p3.py", "--rootdir=tests")
result.stdout.fnmatch_lines(
[
"tests/test_p3.py::TestMore::test_p1 <- test_p1.py FAILED *",
@@ -224,9 +230,11 @@ class TestTerminal:
]
)
- def test_itemreport_directclasses_not_shown_as_subclasses(self, testdir):
- a = testdir.mkpydir("a123")
- a.join("test_hello123.py").write(
+ def test_itemreport_directclasses_not_shown_as_subclasses(
+ self, pytester: Pytester
+ ) -> None:
+ a = pytester.mkpydir("a123")
+ a.joinpath("test_hello123.py").write_text(
textwrap.dedent(
"""\
class TestClass(object):
@@ -235,14 +243,14 @@ class TestTerminal:
"""
)
)
- result = testdir.runpytest("-vv")
+ result = pytester.runpytest("-vv")
assert result.ret == 0
result.stdout.fnmatch_lines(["*a123/test_hello123.py*PASS*"])
result.stdout.no_fnmatch_line("* <- *")
@pytest.mark.parametrize("fulltrace", ("", "--fulltrace"))
- def test_keyboard_interrupt(self, testdir, fulltrace):
- testdir.makepyfile(
+ def test_keyboard_interrupt(self, pytester: Pytester, fulltrace) -> None:
+ pytester.makepyfile(
"""
def test_foobar():
assert 0
@@ -253,7 +261,7 @@ class TestTerminal:
"""
)
- result = testdir.runpytest(fulltrace, no_reraise_ctrlc=True)
+ result = pytester.runpytest(fulltrace, no_reraise_ctrlc=True)
result.stdout.fnmatch_lines(
[
" def test_foobar():",
@@ -272,37 +280,37 @@ class TestTerminal:
)
result.stdout.fnmatch_lines(["*KeyboardInterrupt*"])
- def test_keyboard_in_sessionstart(self, testdir):
- testdir.makeconftest(
+ def test_keyboard_in_sessionstart(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_sessionstart():
raise KeyboardInterrupt
"""
)
- testdir.makepyfile(
+ pytester.makepyfile(
"""
def test_foobar():
pass
"""
)
- result = testdir.runpytest(no_reraise_ctrlc=True)
+ result = pytester.runpytest(no_reraise_ctrlc=True)
assert result.ret == 2
result.stdout.fnmatch_lines(["*KeyboardInterrupt*"])
- def test_collect_single_item(self, testdir):
+ def test_collect_single_item(self, pytester: Pytester) -> None:
"""Use singular 'item' when reporting a single test item"""
- testdir.makepyfile(
+ pytester.makepyfile(
"""
def test_foobar():
pass
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(["collected 1 item"])
- def test_rewrite(self, testdir, monkeypatch):
- config = testdir.parseconfig()
+ def test_rewrite(self, pytester: Pytester, monkeypatch) -> None:
+ config = pytester.parseconfig()
f = StringIO()
monkeypatch.setattr(f, "isatty", lambda *args: True)
tr = TerminalReporter(config, f)
@@ -312,57 +320,57 @@ class TestTerminal:
assert f.getvalue() == "hello" + "\r" + "hey" + (6 * " ")
def test_report_teststatus_explicit_markup(
- self, testdir: Testdir, color_mapping
+ self, monkeypatch: MonkeyPatch, pytester: Pytester, color_mapping
) -> None:
"""Test that TerminalReporter handles markup explicitly provided by
a pytest_report_teststatus hook."""
- testdir.monkeypatch.setenv("PY_COLORS", "1")
- testdir.makeconftest(
+ monkeypatch.setenv("PY_COLORS", "1")
+ pytester.makeconftest(
"""
def pytest_report_teststatus(report):
return 'foo', 'F', ('FOO', {'red': True})
"""
)
- testdir.makepyfile(
+ pytester.makepyfile(
"""
def test_foobar():
pass
"""
)
- result = testdir.runpytest("-v")
+ result = pytester.runpytest("-v")
result.stdout.fnmatch_lines(
color_mapping.format_for_fnmatch(["*{red}FOO{reset}*"])
)
class TestCollectonly:
- def test_collectonly_basic(self, testdir):
- testdir.makepyfile(
+ def test_collectonly_basic(self, pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
def test_func():
pass
"""
)
- result = testdir.runpytest("--collect-only")
+ result = pytester.runpytest("--collect-only")
result.stdout.fnmatch_lines(
["<Module test_collectonly_basic.py>", " <Function test_func>"]
)
- def test_collectonly_skipped_module(self, testdir):
- testdir.makepyfile(
+ def test_collectonly_skipped_module(self, pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
import pytest
pytest.skip("hello")
"""
)
- result = testdir.runpytest("--collect-only", "-rs")
+ result = pytester.runpytest("--collect-only", "-rs")
result.stdout.fnmatch_lines(["*ERROR collecting*"])
def test_collectonly_displays_test_description(
- self, testdir: Testdir, dummy_yaml_custom_test
+ self, pytester: Pytester, dummy_yaml_custom_test
) -> None:
"""Used dummy_yaml_custom_test for an Item without ``obj``."""
- testdir.makepyfile(
+ pytester.makepyfile(
"""
def test_with_description():
''' This test has a description.
@@ -371,7 +379,7 @@ class TestCollectonly:
more2.'''
"""
)
- result = testdir.runpytest("--collect-only", "--verbose")
+ result = pytester.runpytest("--collect-only", "--verbose")
result.stdout.fnmatch_lines(
[
"<YamlFile test1.yaml>",
@@ -386,24 +394,24 @@ class TestCollectonly:
consecutive=True,
)
- def test_collectonly_failed_module(self, testdir):
- testdir.makepyfile("""raise ValueError(0)""")
- result = testdir.runpytest("--collect-only")
+ def test_collectonly_failed_module(self, pytester: Pytester) -> None:
+ pytester.makepyfile("""raise ValueError(0)""")
+ result = pytester.runpytest("--collect-only")
result.stdout.fnmatch_lines(["*raise ValueError*", "*1 error*"])
- def test_collectonly_fatal(self, testdir):
- testdir.makeconftest(
+ def test_collectonly_fatal(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_collectstart(collector):
assert 0, "urgs"
"""
)
- result = testdir.runpytest("--collect-only")
+ result = pytester.runpytest("--collect-only")
result.stdout.fnmatch_lines(["*INTERNAL*args*"])
assert result.ret == 3
- def test_collectonly_simple(self, testdir):
- p = testdir.makepyfile(
+ def test_collectonly_simple(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""
def test_func1():
pass
@@ -412,7 +420,7 @@ class TestCollectonly:
pass
"""
)
- result = testdir.runpytest("--collect-only", p)
+ result = pytester.runpytest("--collect-only", p)
# assert stderr.startswith("inserting into sys.path")
assert result.ret == 0
result.stdout.fnmatch_lines(
@@ -424,9 +432,9 @@ class TestCollectonly:
]
)
- def test_collectonly_error(self, testdir):
- p = testdir.makepyfile("import Errlkjqweqwe")
- result = testdir.runpytest("--collect-only", p)
+ def test_collectonly_error(self, pytester: Pytester) -> None:
+ p = pytester.makepyfile("import Errlkjqweqwe")
+ result = pytester.runpytest("--collect-only", p)
assert result.ret == 2
result.stdout.fnmatch_lines(
textwrap.dedent(
@@ -439,28 +447,28 @@ class TestCollectonly:
).strip()
)
- def test_collectonly_missing_path(self, testdir):
+ def test_collectonly_missing_path(self, pytester: Pytester) -> None:
"""Issue 115: failure in parseargs will cause session not to
have the items attribute."""
- result = testdir.runpytest("--collect-only", "uhm_missing_path")
+ result = pytester.runpytest("--collect-only", "uhm_missing_path")
assert result.ret == 4
result.stderr.fnmatch_lines(
["*ERROR: file or directory not found: uhm_missing_path"]
)
- def test_collectonly_quiet(self, testdir):
- testdir.makepyfile("def test_foo(): pass")
- result = testdir.runpytest("--collect-only", "-q")
+ def test_collectonly_quiet(self, pytester: Pytester) -> None:
+ pytester.makepyfile("def test_foo(): pass")
+ result = pytester.runpytest("--collect-only", "-q")
result.stdout.fnmatch_lines(["*test_foo*"])
- def test_collectonly_more_quiet(self, testdir):
- testdir.makepyfile(test_fun="def test_foo(): pass")
- result = testdir.runpytest("--collect-only", "-qq")
+ def test_collectonly_more_quiet(self, pytester: Pytester) -> None:
+ pytester.makepyfile(test_fun="def test_foo(): pass")
+ result = pytester.runpytest("--collect-only", "-qq")
result.stdout.fnmatch_lines(["*test_fun.py: 1*"])
- def test_collect_only_summary_status(self, testdir):
+ def test_collect_only_summary_status(self, pytester: Pytester) -> None:
"""Custom status depending on test selection using -k or -m. #7701."""
- testdir.makepyfile(
+ pytester.makepyfile(
test_collect_foo="""
def test_foo(): pass
""",
@@ -469,41 +477,41 @@ class TestCollectonly:
def test_bar(): pass
""",
)
- result = testdir.runpytest("--collect-only")
+ result = pytester.runpytest("--collect-only")
result.stdout.fnmatch_lines("*== 3 tests collected in * ==*")
- result = testdir.runpytest("--collect-only", "test_collect_foo.py")
+ result = pytester.runpytest("--collect-only", "test_collect_foo.py")
result.stdout.fnmatch_lines("*== 1 test collected in * ==*")
- result = testdir.runpytest("--collect-only", "-k", "foo")
+ result = pytester.runpytest("--collect-only", "-k", "foo")
result.stdout.fnmatch_lines("*== 2/3 tests collected (1 deselected) in * ==*")
- result = testdir.runpytest("--collect-only", "-k", "test_bar")
+ result = pytester.runpytest("--collect-only", "-k", "test_bar")
result.stdout.fnmatch_lines("*== 1/3 tests collected (2 deselected) in * ==*")
- result = testdir.runpytest("--collect-only", "-k", "invalid")
+ result = pytester.runpytest("--collect-only", "-k", "invalid")
result.stdout.fnmatch_lines("*== no tests collected (3 deselected) in * ==*")
- testdir.mkdir("no_tests_here")
- result = testdir.runpytest("--collect-only", "no_tests_here")
+ pytester.mkdir("no_tests_here")
+ result = pytester.runpytest("--collect-only", "no_tests_here")
result.stdout.fnmatch_lines("*== no tests collected in * ==*")
- testdir.makepyfile(
+ pytester.makepyfile(
test_contains_error="""
raise RuntimeError
""",
)
- result = testdir.runpytest("--collect-only")
+ result = pytester.runpytest("--collect-only")
result.stdout.fnmatch_lines("*== 3 tests collected, 1 error in * ==*")
- result = testdir.runpytest("--collect-only", "-k", "foo")
+ result = pytester.runpytest("--collect-only", "-k", "foo")
result.stdout.fnmatch_lines(
"*== 2/3 tests collected (1 deselected), 1 error in * ==*"
)
class TestFixtureReporting:
- def test_setup_fixture_error(self, testdir):
- testdir.makepyfile(
+ def test_setup_fixture_error(self, pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
def setup_function(function):
print("setup func")
@@ -512,7 +520,7 @@ class TestFixtureReporting:
pass
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(
[
"*ERROR at setup of test_nada*",
@@ -524,8 +532,8 @@ class TestFixtureReporting:
)
assert result.ret != 0
- def test_teardown_fixture_error(self, testdir):
- testdir.makepyfile(
+ def test_teardown_fixture_error(self, pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
def test_nada():
pass
@@ -534,7 +542,7 @@ class TestFixtureReporting:
assert 0
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(
[
"*ERROR at teardown*",
@@ -546,8 +554,8 @@ class TestFixtureReporting:
]
)
- def test_teardown_fixture_error_and_test_failure(self, testdir):
- testdir.makepyfile(
+ def test_teardown_fixture_error_and_test_failure(self, pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
def test_fail():
assert 0, "failingfunc"
@@ -557,7 +565,7 @@ class TestFixtureReporting:
assert False
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(
[
"*ERROR at teardown of test_fail*",
@@ -572,9 +580,9 @@ class TestFixtureReporting:
]
)
- def test_setup_teardown_output_and_test_failure(self, testdir):
+ def test_setup_teardown_output_and_test_failure(self, pytester: Pytester) -> None:
"""Test for issue #442."""
- testdir.makepyfile(
+ pytester.makepyfile(
"""
def setup_function(function):
print("setup func")
@@ -586,7 +594,7 @@ class TestFixtureReporting:
print("teardown func")
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(
[
"*test_fail*",
@@ -602,8 +610,8 @@ class TestFixtureReporting:
class TestTerminalFunctional:
- def test_deselected(self, testdir):
- testpath = testdir.makepyfile(
+ def test_deselected(self, pytester: Pytester) -> None:
+ testpath = pytester.makepyfile(
"""
def test_one():
pass
@@ -613,14 +621,14 @@ class TestTerminalFunctional:
pass
"""
)
- result = testdir.runpytest("-k", "test_two:", testpath)
+ result = pytester.runpytest("-k", "test_two:", testpath)
result.stdout.fnmatch_lines(
["collected 3 items / 1 deselected / 2 selected", "*test_deselected.py ..*"]
)
assert result.ret == 0
- def test_deselected_with_hookwrapper(self, testdir):
- testpath = testdir.makeconftest(
+ def test_deselected_with_hookwrapper(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
import pytest
@@ -631,7 +639,7 @@ class TestTerminalFunctional:
config.hook.pytest_deselected(items=[deselected])
"""
)
- testpath = testdir.makepyfile(
+ testpath = pytester.makepyfile(
"""
def test_one():
pass
@@ -641,7 +649,7 @@ class TestTerminalFunctional:
pass
"""
)
- result = testdir.runpytest(testpath)
+ result = pytester.runpytest(testpath)
result.stdout.fnmatch_lines(
[
"collected 3 items / 1 deselected / 2 selected",
@@ -650,8 +658,10 @@ class TestTerminalFunctional:
)
assert result.ret == 0
- def test_show_deselected_items_using_markexpr_before_test_execution(self, testdir):
- testdir.makepyfile(
+ def test_show_deselected_items_using_markexpr_before_test_execution(
+ self, pytester: Pytester
+ ) -> None:
+ pytester.makepyfile(
test_show_deselected="""
import pytest
@@ -667,7 +677,7 @@ class TestTerminalFunctional:
pass
"""
)
- result = testdir.runpytest("-m", "not foo")
+ result = pytester.runpytest("-m", "not foo")
result.stdout.fnmatch_lines(
[
"collected 3 items / 1 deselected / 2 selected",
@@ -678,8 +688,8 @@ class TestTerminalFunctional:
result.stdout.no_fnmatch_line("*= 1 deselected =*")
assert result.ret == 0
- def test_no_skip_summary_if_failure(self, testdir):
- testdir.makepyfile(
+ def test_no_skip_summary_if_failure(self, pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
import pytest
def test_ok():
@@ -690,12 +700,12 @@ class TestTerminalFunctional:
pytest.skip("dontshow")
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
assert result.stdout.str().find("skip test summary") == -1
assert result.ret == 1
- def test_passes(self, testdir):
- p1 = testdir.makepyfile(
+ def test_passes(self, pytester: Pytester) -> None:
+ p1 = pytester.makepyfile(
"""
def test_passes():
pass
@@ -704,23 +714,26 @@ class TestTerminalFunctional:
pass
"""
)
- old = p1.dirpath().chdir()
+ old = p1.parent
+ pytester.chdir()
try:
- result = testdir.runpytest()
+ result = pytester.runpytest()
finally:
- old.chdir()
+ os.chdir(old)
result.stdout.fnmatch_lines(["test_passes.py ..*", "* 2 pass*"])
assert result.ret == 0
- def test_header_trailer_info(self, testdir, request):
- testdir.monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD")
- testdir.makepyfile(
+ def test_header_trailer_info(
+ self, monkeypatch: MonkeyPatch, pytester: Pytester, request
+ ) -> None:
+ monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD")
+ pytester.makepyfile(
"""
def test_passes():
pass
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
verinfo = ".".join(map(str, sys.version_info[:3]))
result.stdout.fnmatch_lines(
[
@@ -740,15 +753,17 @@ class TestTerminalFunctional:
if request.config.pluginmanager.list_plugin_distinfo():
result.stdout.fnmatch_lines(["plugins: *"])
- def test_no_header_trailer_info(self, testdir, request):
- testdir.monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD")
- testdir.makepyfile(
+ def test_no_header_trailer_info(
+ self, monkeypatch: MonkeyPatch, pytester: Pytester, request
+ ) -> None:
+ monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD")
+ pytester.makepyfile(
"""
def test_passes():
pass
"""
)
- result = testdir.runpytest("--no-header")
+ result = pytester.runpytest("--no-header")
verinfo = ".".join(map(str, sys.version_info[:3]))
result.stdout.no_fnmatch_line(
"platform %s -- Python %s*pytest-%s*py-%s*pluggy-%s"
@@ -763,42 +778,42 @@ class TestTerminalFunctional:
if request.config.pluginmanager.list_plugin_distinfo():
result.stdout.no_fnmatch_line("plugins: *")
- def test_header(self, testdir):
- testdir.tmpdir.join("tests").ensure_dir()
- testdir.tmpdir.join("gui").ensure_dir()
+ def test_header(self, pytester: Pytester) -> None:
+ pytester.path.joinpath("tests").mkdir()
+ pytester.path.joinpath("gui").mkdir()
# no ini file
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(["rootdir: *test_header0"])
# with configfile
- testdir.makeini("""[pytest]""")
- result = testdir.runpytest()
+ pytester.makeini("""[pytest]""")
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(["rootdir: *test_header0, configfile: tox.ini"])
# with testpaths option, and not passing anything in the command-line
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
testpaths = tests gui
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(
["rootdir: *test_header0, configfile: tox.ini, testpaths: tests, gui"]
)
# with testpaths option, passing directory in command-line: do not show testpaths then
- result = testdir.runpytest("tests")
+ result = pytester.runpytest("tests")
result.stdout.fnmatch_lines(["rootdir: *test_header0, configfile: tox.ini"])
def test_header_absolute_testpath(
- self, testdir: Testdir, monkeypatch: MonkeyPatch
+ self, pytester: Pytester, monkeypatch: MonkeyPatch
) -> None:
"""Regresstion test for #7814."""
- tests = testdir.tmpdir.join("tests")
- tests.ensure_dir()
- testdir.makepyprojecttoml(
+ tests = pytester.path.joinpath("tests")
+ tests.mkdir()
+ pytester.makepyprojecttoml(
"""
[tool.pytest.ini_options]
testpaths = ['{}']
@@ -806,7 +821,7 @@ class TestTerminalFunctional:
tests
)
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(
[
"rootdir: *absolute_testpath0, configfile: pyproject.toml, testpaths: {}".format(
@@ -815,38 +830,38 @@ class TestTerminalFunctional:
]
)
- def test_no_header(self, testdir):
- testdir.tmpdir.join("tests").ensure_dir()
- testdir.tmpdir.join("gui").ensure_dir()
+ def test_no_header(self, pytester: Pytester) -> None:
+ pytester.path.joinpath("tests").mkdir()
+ pytester.path.joinpath("gui").mkdir()
# with testpaths option, and not passing anything in the command-line
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
testpaths = tests gui
"""
)
- result = testdir.runpytest("--no-header")
+ result = pytester.runpytest("--no-header")
result.stdout.no_fnmatch_line(
"rootdir: *test_header0, inifile: tox.ini, testpaths: tests, gui"
)
# with testpaths option, passing directory in command-line: do not show testpaths then
- result = testdir.runpytest("tests", "--no-header")
+ result = pytester.runpytest("tests", "--no-header")
result.stdout.no_fnmatch_line("rootdir: *test_header0, inifile: tox.ini")
- def test_no_summary(self, testdir):
- p1 = testdir.makepyfile(
+ def test_no_summary(self, pytester: Pytester) -> None:
+ p1 = pytester.makepyfile(
"""
def test_no_summary():
assert false
"""
)
- result = testdir.runpytest(p1, "--no-summary")
+ result = pytester.runpytest(p1, "--no-summary")
result.stdout.no_fnmatch_line("*= FAILURES =*")
- def test_showlocals(self, testdir):
- p1 = testdir.makepyfile(
+ def test_showlocals(self, pytester: Pytester) -> None:
+ p1 = pytester.makepyfile(
"""
def test_showlocals():
x = 3
@@ -854,7 +869,7 @@ class TestTerminalFunctional:
assert 0
"""
)
- result = testdir.runpytest(p1, "-l")
+ result = pytester.runpytest(p1, "-l")
result.stdout.fnmatch_lines(
[
# "_ _ * Locals *",
@@ -863,8 +878,8 @@ class TestTerminalFunctional:
]
)
- def test_showlocals_short(self, testdir):
- p1 = testdir.makepyfile(
+ def test_showlocals_short(self, pytester: Pytester) -> None:
+ p1 = pytester.makepyfile(
"""
def test_showlocals_short():
x = 3
@@ -872,7 +887,7 @@ class TestTerminalFunctional:
assert 0
"""
)
- result = testdir.runpytest(p1, "-l", "--tb=short")
+ result = pytester.runpytest(p1, "-l", "--tb=short")
result.stdout.fnmatch_lines(
[
"test_showlocals_short.py:*",
@@ -884,8 +899,8 @@ class TestTerminalFunctional:
)
@pytest.fixture
- def verbose_testfile(self, testdir):
- return testdir.makepyfile(
+ def verbose_testfile(self, pytester: Pytester) -> Path:
+ return pytester.makepyfile(
"""
import pytest
def test_fail():
@@ -902,8 +917,8 @@ class TestTerminalFunctional:
"""
)
- def test_verbose_reporting(self, verbose_testfile, testdir):
- result = testdir.runpytest(
+ def test_verbose_reporting(self, verbose_testfile, pytester: Pytester) -> None:
+ result = pytester.runpytest(
verbose_testfile, "-v", "-Walways::pytest.PytestWarning"
)
result.stdout.fnmatch_lines(
@@ -916,12 +931,18 @@ class TestTerminalFunctional:
)
assert result.ret == 1
- def test_verbose_reporting_xdist(self, verbose_testfile, testdir, pytestconfig):
+ def test_verbose_reporting_xdist(
+ self,
+ verbose_testfile,
+ monkeypatch: MonkeyPatch,
+ pytester: Pytester,
+ pytestconfig,
+ ) -> None:
if not pytestconfig.pluginmanager.get_plugin("xdist"):
pytest.skip("xdist plugin not installed")
- testdir.monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD")
- result = testdir.runpytest(
+ monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD")
+ result = pytester.runpytest(
verbose_testfile, "-v", "-n 1", "-Walways::pytest.PytestWarning"
)
result.stdout.fnmatch_lines(
@@ -929,35 +950,35 @@ class TestTerminalFunctional:
)
assert result.ret == 1
- def test_quiet_reporting(self, testdir):
- p1 = testdir.makepyfile("def test_pass(): pass")
- result = testdir.runpytest(p1, "-q")
+ def test_quiet_reporting(self, pytester: Pytester) -> None:
+ p1 = pytester.makepyfile("def test_pass(): pass")
+ result = pytester.runpytest(p1, "-q")
s = result.stdout.str()
assert "test session starts" not in s
- assert p1.basename not in s
+ assert p1.name not in s
assert "===" not in s
assert "passed" in s
- def test_more_quiet_reporting(self, testdir):
- p1 = testdir.makepyfile("def test_pass(): pass")
- result = testdir.runpytest(p1, "-qq")
+ def test_more_quiet_reporting(self, pytester: Pytester) -> None:
+ p1 = pytester.makepyfile("def test_pass(): pass")
+ result = pytester.runpytest(p1, "-qq")
s = result.stdout.str()
assert "test session starts" not in s
- assert p1.basename not in s
+ assert p1.name not in s
assert "===" not in s
assert "passed" not in s
@pytest.mark.parametrize(
"params", [(), ("--collect-only",)], ids=["no-params", "collect-only"]
)
- def test_report_collectionfinish_hook(self, testdir, params):
- testdir.makeconftest(
+ def test_report_collectionfinish_hook(self, pytester: Pytester, params) -> None:
+ pytester.makeconftest(
"""
def pytest_report_collectionfinish(config, startdir, items):
return ['hello from hook: {0} items'.format(len(items))]
"""
)
- testdir.makepyfile(
+ pytester.makepyfile(
"""
import pytest
@pytest.mark.parametrize('i', range(3))
@@ -965,25 +986,25 @@ class TestTerminalFunctional:
pass
"""
)
- result = testdir.runpytest(*params)
+ result = pytester.runpytest(*params)
result.stdout.fnmatch_lines(["collected 3 items", "hello from hook: 3 items"])
- def test_summary_f_alias(self, testdir):
+ def test_summary_f_alias(self, pytester: Pytester) -> None:
"""Test that 'f' and 'F' report chars are aliases and don't show up twice in the summary (#6334)"""
- testdir.makepyfile(
+ pytester.makepyfile(
"""
def test():
assert False
"""
)
- result = testdir.runpytest("-rfF")
+ result = pytester.runpytest("-rfF")
expected = "FAILED test_summary_f_alias.py::test - assert False"
result.stdout.fnmatch_lines([expected])
assert result.stdout.lines.count(expected) == 1
- def test_summary_s_alias(self, testdir):
+ def test_summary_s_alias(self, pytester: Pytester) -> None:
"""Test that 's' and 'S' report chars are aliases and don't show up twice in the summary"""
- testdir.makepyfile(
+ pytester.makepyfile(
"""
import pytest
@@ -992,18 +1013,18 @@ class TestTerminalFunctional:
pass
"""
)
- result = testdir.runpytest("-rsS")
+ result = pytester.runpytest("-rsS")
expected = "SKIPPED [1] test_summary_s_alias.py:3: unconditional skip"
result.stdout.fnmatch_lines([expected])
assert result.stdout.lines.count(expected) == 1
-def test_fail_extra_reporting(testdir, monkeypatch):
+def test_fail_extra_reporting(pytester: Pytester, monkeypatch) -> None:
monkeypatch.setenv("COLUMNS", "80")
- testdir.makepyfile("def test_this(): assert 0, 'this_failed' * 100")
- result = testdir.runpytest("-rN")
+ pytester.makepyfile("def test_this(): assert 0, 'this_failed' * 100")
+ result = pytester.runpytest("-rN")
result.stdout.no_fnmatch_line("*short test summary*")
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(
[
"*test summary*",
@@ -1012,28 +1033,28 @@ def test_fail_extra_reporting(testdir, monkeypatch):
)
-def test_fail_reporting_on_pass(testdir):
- testdir.makepyfile("def test_this(): assert 1")
- result = testdir.runpytest("-rf")
+def test_fail_reporting_on_pass(pytester: Pytester) -> None:
+ pytester.makepyfile("def test_this(): assert 1")
+ result = pytester.runpytest("-rf")
result.stdout.no_fnmatch_line("*short test summary*")
-def test_pass_extra_reporting(testdir):
- testdir.makepyfile("def test_this(): assert 1")
- result = testdir.runpytest()
+def test_pass_extra_reporting(pytester: Pytester) -> None:
+ pytester.makepyfile("def test_this(): assert 1")
+ result = pytester.runpytest()
result.stdout.no_fnmatch_line("*short test summary*")
- result = testdir.runpytest("-rp")
+ result = pytester.runpytest("-rp")
result.stdout.fnmatch_lines(["*test summary*", "PASS*test_pass_extra_reporting*"])
-def test_pass_reporting_on_fail(testdir):
- testdir.makepyfile("def test_this(): assert 0")
- result = testdir.runpytest("-rp")
+def test_pass_reporting_on_fail(pytester: Pytester) -> None:
+ pytester.makepyfile("def test_this(): assert 0")
+ result = pytester.runpytest("-rp")
result.stdout.no_fnmatch_line("*short test summary*")
-def test_pass_output_reporting(testdir):
- testdir.makepyfile(
+def test_pass_output_reporting(pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
def setup_module():
print("setup_module")
@@ -1048,12 +1069,12 @@ def test_pass_output_reporting(testdir):
pass
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
s = result.stdout.str()
assert "test_pass_has_output" not in s
assert "Four score and seven years ago..." not in s
assert "test_pass_no_output" not in s
- result = testdir.runpytest("-rPp")
+ result = pytester.runpytest("-rPp")
result.stdout.fnmatch_lines(
[
"*= PASSES =*",
@@ -1072,8 +1093,8 @@ def test_pass_output_reporting(testdir):
)
-def test_color_yes(testdir, color_mapping):
- p1 = testdir.makepyfile(
+def test_color_yes(pytester: Pytester, color_mapping) -> None:
+ p1 = pytester.makepyfile(
"""
def fail():
assert 0
@@ -1082,7 +1103,7 @@ def test_color_yes(testdir, color_mapping):
fail()
"""
)
- result = testdir.runpytest("--color=yes", str(p1))
+ result = pytester.runpytest("--color=yes", str(p1))
result.stdout.fnmatch_lines(
color_mapping.format_for_fnmatch(
[
@@ -1109,7 +1130,7 @@ def test_color_yes(testdir, color_mapping):
]
)
)
- result = testdir.runpytest("--color=yes", "--tb=short", str(p1))
+ result = pytester.runpytest("--color=yes", "--tb=short", str(p1))
result.stdout.fnmatch_lines(
color_mapping.format_for_fnmatch(
[
@@ -1131,17 +1152,17 @@ def test_color_yes(testdir, color_mapping):
)
-def test_color_no(testdir):
- testdir.makepyfile("def test_this(): assert 1")
- result = testdir.runpytest("--color=no")
+def test_color_no(pytester: Pytester) -> None:
+ pytester.makepyfile("def test_this(): assert 1")
+ result = pytester.runpytest("--color=no")
assert "test session starts" in result.stdout.str()
result.stdout.no_fnmatch_line("*\x1b[1m*")
@pytest.mark.parametrize("verbose", [True, False])
-def test_color_yes_collection_on_non_atty(testdir, verbose):
+def test_color_yes_collection_on_non_atty(pytester: Pytester, verbose) -> None:
"""#1397: Skip collect progress report when working on non-terminals."""
- testdir.makepyfile(
+ pytester.makepyfile(
"""
import pytest
@pytest.mark.parametrize('i', range(10))
@@ -1152,7 +1173,7 @@ def test_color_yes_collection_on_non_atty(testdir, verbose):
args = ["--color=yes"]
if verbose:
args.append("-vv")
- result = testdir.runpytest(*args)
+ result = pytester.runpytest(*args)
assert "test session starts" in result.stdout.str()
assert "\x1b[1m" in result.stdout.str()
result.stdout.no_fnmatch_line("*collecting 10 items*")
@@ -1220,9 +1241,9 @@ def test_getreportopt() -> None:
assert getreportopt(config) == "fE"
-def test_terminalreporter_reportopt_addopts(testdir):
- testdir.makeini("[pytest]\naddopts=-rs")
- testdir.makepyfile(
+def test_terminalreporter_reportopt_addopts(pytester: Pytester) -> None:
+ pytester.makeini("[pytest]\naddopts=-rs")
+ pytester.makepyfile(
"""
import pytest
@@ -1235,12 +1256,12 @@ def test_terminalreporter_reportopt_addopts(testdir):
assert not tr.hasopt('qwe')
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(["*1 passed*"])
-def test_tbstyle_short(testdir):
- p = testdir.makepyfile(
+def test_tbstyle_short(pytester: Pytester) -> None:
+ p = pytester.makepyfile(
"""
import pytest
@@ -1252,19 +1273,19 @@ def test_tbstyle_short(testdir):
assert x
"""
)
- result = testdir.runpytest("--tb=short")
+ result = pytester.runpytest("--tb=short")
s = result.stdout.str()
assert "arg = 42" not in s
assert "x = 0" not in s
- result.stdout.fnmatch_lines(["*%s:8*" % p.basename, " assert x", "E assert*"])
- result = testdir.runpytest()
+ result.stdout.fnmatch_lines(["*%s:8*" % p.name, " assert x", "E assert*"])
+ result = pytester.runpytest()
s = result.stdout.str()
assert "x = 0" in s
assert "assert x" in s
-def test_traceconfig(testdir):
- result = testdir.runpytest("--traceconfig")
+def test_traceconfig(pytester: Pytester) -> None:
+ result = pytester.runpytest("--traceconfig")
result.stdout.fnmatch_lines(["*active plugins*"])
assert result.ret == ExitCode.NO_TESTS_COLLECTED
@@ -1273,15 +1294,15 @@ class TestGenericReporting:
"""Test class which can be subclassed with a different option provider to
run e.g. distributed tests."""
- def test_collect_fail(self, testdir, option):
- testdir.makepyfile("import xyz\n")
- result = testdir.runpytest(*option.args)
+ def test_collect_fail(self, pytester: Pytester, option) -> None:
+ pytester.makepyfile("import xyz\n")
+ result = pytester.runpytest(*option.args)
result.stdout.fnmatch_lines(
["ImportError while importing*", "*No module named *xyz*", "*1 error*"]
)
- def test_maxfailures(self, testdir, option):
- testdir.makepyfile(
+ def test_maxfailures(self, pytester: Pytester, option) -> None:
+ pytester.makepyfile(
"""
def test_1():
assert 0
@@ -1291,7 +1312,7 @@ class TestGenericReporting:
assert 0
"""
)
- result = testdir.runpytest("--maxfail=2", *option.args)
+ result = pytester.runpytest("--maxfail=2", *option.args)
result.stdout.fnmatch_lines(
[
"*def test_1():*",
@@ -1301,15 +1322,15 @@ class TestGenericReporting:
]
)
- def test_maxfailures_with_interrupted(self, testdir):
- testdir.makepyfile(
+ def test_maxfailures_with_interrupted(self, pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
def test(request):
request.session.shouldstop = "session_interrupted"
assert 0
"""
)
- result = testdir.runpytest("--maxfail=1", "-ra")
+ result = pytester.runpytest("--maxfail=1", "-ra")
result.stdout.fnmatch_lines(
[
"*= short test summary info =*",
@@ -1320,8 +1341,8 @@ class TestGenericReporting:
]
)
- def test_tb_option(self, testdir, option):
- testdir.makepyfile(
+ def test_tb_option(self, pytester: Pytester, option) -> None:
+ pytester.makepyfile(
"""
import pytest
def g():
@@ -1333,7 +1354,7 @@ class TestGenericReporting:
)
for tbopt in ["long", "short", "no"]:
print("testing --tb=%s..." % tbopt)
- result = testdir.runpytest("-rN", "--tb=%s" % tbopt)
+ result = pytester.runpytest("-rN", "--tb=%s" % tbopt)
s = result.stdout.str()
if tbopt == "long":
assert "print(6*7)" in s
@@ -1347,8 +1368,8 @@ class TestGenericReporting:
assert "--calling--" not in s
assert "IndexError" not in s
- def test_tb_crashline(self, testdir, option):
- p = testdir.makepyfile(
+ def test_tb_crashline(self, pytester: Pytester, option) -> None:
+ p = pytester.makepyfile(
"""
import pytest
def g():
@@ -1360,16 +1381,16 @@ class TestGenericReporting:
assert 0, "hello"
"""
)
- result = testdir.runpytest("--tb=line")
- bn = p.basename
+ result = pytester.runpytest("--tb=line")
+ bn = p.name
result.stdout.fnmatch_lines(
["*%s:3: IndexError*" % bn, "*%s:8: AssertionError: hello*" % bn]
)
s = result.stdout.str()
assert "def test_func2" not in s
- def test_pytest_report_header(self, testdir, option):
- testdir.makeconftest(
+ def test_pytest_report_header(self, pytester: Pytester, option) -> None:
+ pytester.makeconftest(
"""
def pytest_sessionstart(session):
session.config._somevalue = 42
@@ -1377,17 +1398,17 @@ class TestGenericReporting:
return "hello: %s" % config._somevalue
"""
)
- testdir.mkdir("a").join("conftest.py").write(
+ pytester.mkdir("a").joinpath("conftest.py").write_text(
"""
def pytest_report_header(config, startdir):
return ["line1", str(startdir)]
"""
)
- result = testdir.runpytest("a")
- result.stdout.fnmatch_lines(["*hello: 42*", "line1", str(testdir.tmpdir)])
+ result = pytester.runpytest("a")
+ result.stdout.fnmatch_lines(["*hello: 42*", "line1", str(pytester.path)])
- def test_show_capture(self, testdir):
- testdir.makepyfile(
+ def test_show_capture(self, pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
import sys
import logging
@@ -1399,7 +1420,7 @@ def pytest_report_header(config, startdir):
"""
)
- result = testdir.runpytest("--tb=short")
+ result = pytester.runpytest("--tb=short")
result.stdout.fnmatch_lines(
[
"!This is stdout!",
@@ -1408,7 +1429,7 @@ def pytest_report_header(config, startdir):
]
)
- result = testdir.runpytest("--show-capture=all", "--tb=short")
+ result = pytester.runpytest("--show-capture=all", "--tb=short")
result.stdout.fnmatch_lines(
[
"!This is stdout!",
@@ -1417,29 +1438,29 @@ def pytest_report_header(config, startdir):
]
)
- stdout = testdir.runpytest("--show-capture=stdout", "--tb=short").stdout.str()
+ stdout = pytester.runpytest("--show-capture=stdout", "--tb=short").stdout.str()
assert "!This is stderr!" not in stdout
assert "!This is stdout!" in stdout
assert "!This is a warning log msg!" not in stdout
- stdout = testdir.runpytest("--show-capture=stderr", "--tb=short").stdout.str()
+ stdout = pytester.runpytest("--show-capture=stderr", "--tb=short").stdout.str()
assert "!This is stdout!" not in stdout
assert "!This is stderr!" in stdout
assert "!This is a warning log msg!" not in stdout
- stdout = testdir.runpytest("--show-capture=log", "--tb=short").stdout.str()
+ stdout = pytester.runpytest("--show-capture=log", "--tb=short").stdout.str()
assert "!This is stdout!" not in stdout
assert "!This is stderr!" not in stdout
assert "!This is a warning log msg!" in stdout
- stdout = testdir.runpytest("--show-capture=no", "--tb=short").stdout.str()
+ stdout = pytester.runpytest("--show-capture=no", "--tb=short").stdout.str()
assert "!This is stdout!" not in stdout
assert "!This is stderr!" not in stdout
assert "!This is a warning log msg!" not in stdout
- def test_show_capture_with_teardown_logs(self, testdir):
+ def test_show_capture_with_teardown_logs(self, pytester: Pytester) -> None:
"""Ensure that the capturing of teardown logs honor --show-capture setting"""
- testdir.makepyfile(
+ pytester.makepyfile(
"""
import logging
import sys
@@ -1457,30 +1478,30 @@ def pytest_report_header(config, startdir):
"""
)
- result = testdir.runpytest("--show-capture=stdout", "--tb=short").stdout.str()
+ result = pytester.runpytest("--show-capture=stdout", "--tb=short").stdout.str()
assert "!stdout!" in result
assert "!stderr!" not in result
assert "!log!" not in result
- result = testdir.runpytest("--show-capture=stderr", "--tb=short").stdout.str()
+ result = pytester.runpytest("--show-capture=stderr", "--tb=short").stdout.str()
assert "!stdout!" not in result
assert "!stderr!" in result
assert "!log!" not in result
- result = testdir.runpytest("--show-capture=log", "--tb=short").stdout.str()
+ result = pytester.runpytest("--show-capture=log", "--tb=short").stdout.str()
assert "!stdout!" not in result
assert "!stderr!" not in result
assert "!log!" in result
- result = testdir.runpytest("--show-capture=no", "--tb=short").stdout.str()
+ result = pytester.runpytest("--show-capture=no", "--tb=short").stdout.str()
assert "!stdout!" not in result
assert "!stderr!" not in result
assert "!log!" not in result
@pytest.mark.xfail("not hasattr(os, 'dup')")
-def test_fdopen_kept_alive_issue124(testdir):
- testdir.makepyfile(
+def test_fdopen_kept_alive_issue124(pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
import os, sys
k = []
@@ -1493,12 +1514,12 @@ def test_fdopen_kept_alive_issue124(testdir):
stdout.close()
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(["*2 passed*"])
-def test_tbstyle_native_setup_error(testdir):
- testdir.makepyfile(
+def test_tbstyle_native_setup_error(pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
import pytest
@pytest.fixture
@@ -1509,14 +1530,14 @@ def test_tbstyle_native_setup_error(testdir):
pass
"""
)
- result = testdir.runpytest("--tb=native")
+ result = pytester.runpytest("--tb=native")
result.stdout.fnmatch_lines(
['*File *test_tbstyle_native_setup_error.py", line *, in setup_error_fixture*']
)
-def test_terminal_summary(testdir):
- testdir.makeconftest(
+def test_terminal_summary(pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
def pytest_terminal_summary(terminalreporter, exitstatus):
w = terminalreporter
@@ -1525,7 +1546,7 @@ def test_terminal_summary(testdir):
w.line("exitstatus: {0}".format(exitstatus))
"""
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.fnmatch_lines(
"""
*==== hello ====*
@@ -1536,18 +1557,18 @@ def test_terminal_summary(testdir):
@pytest.mark.filterwarnings("default")
-def test_terminal_summary_warnings_are_displayed(testdir):
+def test_terminal_summary_warnings_are_displayed(pytester: Pytester) -> None:
"""Test that warnings emitted during pytest_terminal_summary are displayed.
(#1305).
"""
- testdir.makeconftest(
+ pytester.makeconftest(
"""
import warnings
def pytest_terminal_summary(terminalreporter):
warnings.warn(UserWarning('internal warning'))
"""
)
- testdir.makepyfile(
+ pytester.makepyfile(
"""
def test_failure():
import warnings
@@ -1555,7 +1576,7 @@ def test_terminal_summary_warnings_are_displayed(testdir):
assert 0
"""
)
- result = testdir.runpytest("-ra")
+ result = pytester.runpytest("-ra")
result.stdout.fnmatch_lines(
[
"*= warnings summary =*",
@@ -1573,8 +1594,8 @@ def test_terminal_summary_warnings_are_displayed(testdir):
@pytest.mark.filterwarnings("default")
-def test_terminal_summary_warnings_header_once(testdir):
- testdir.makepyfile(
+def test_terminal_summary_warnings_header_once(pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
def test_failure():
import warnings
@@ -1582,7 +1603,7 @@ def test_terminal_summary_warnings_header_once(testdir):
assert 0
"""
)
- result = testdir.runpytest("-ra")
+ result = pytester.runpytest("-ra")
result.stdout.fnmatch_lines(
[
"*= warnings summary =*",
@@ -1598,8 +1619,8 @@ def test_terminal_summary_warnings_header_once(testdir):
@pytest.mark.filterwarnings("default")
-def test_terminal_no_summary_warnings_header_once(testdir):
- testdir.makepyfile(
+def test_terminal_no_summary_warnings_header_once(pytester: Pytester) -> None:
+ pytester.makepyfile(
"""
def test_failure():
import warnings
@@ -1607,7 +1628,7 @@ def test_terminal_no_summary_warnings_header_once(testdir):
assert 0
"""
)
- result = testdir.runpytest("--no-summary")
+ result = pytester.runpytest("--no-summary")
result.stdout.no_fnmatch_line("*= warnings summary =*")
result.stdout.no_fnmatch_line("*= short test summary info =*")
@@ -1796,8 +1817,8 @@ class TestClassicOutputStyle:
"""Ensure classic output style works as expected (#3883)"""
@pytest.fixture
- def test_files(self, testdir):
- testdir.makepyfile(
+ def test_files(self, pytester: Pytester) -> None:
+ pytester.makepyfile(
**{
"test_one.py": "def test_one(): pass",
"test_two.py": "def test_two(): assert 0",
@@ -1809,8 +1830,8 @@ class TestClassicOutputStyle:
}
)
- def test_normal_verbosity(self, testdir, test_files):
- result = testdir.runpytest("-o", "console_output_style=classic")
+ def test_normal_verbosity(self, pytester: Pytester, test_files) -> None:
+ result = pytester.runpytest("-o", "console_output_style=classic")
result.stdout.fnmatch_lines(
[
"test_one.py .",
@@ -1820,8 +1841,8 @@ class TestClassicOutputStyle:
]
)
- def test_verbose(self, testdir, test_files):
- result = testdir.runpytest("-o", "console_output_style=classic", "-v")
+ def test_verbose(self, pytester: Pytester, test_files) -> None:
+ result = pytester.runpytest("-o", "console_output_style=classic", "-v")
result.stdout.fnmatch_lines(
[
"test_one.py::test_one PASSED",
@@ -1833,15 +1854,15 @@ class TestClassicOutputStyle:
]
)
- def test_quiet(self, testdir, test_files):
- result = testdir.runpytest("-o", "console_output_style=classic", "-q")
+ def test_quiet(self, pytester: Pytester, test_files) -> None:
+ result = pytester.runpytest("-o", "console_output_style=classic", "-q")
result.stdout.fnmatch_lines([".F.F.", "*2 failed, 3 passed in*"])
class TestProgressOutputStyle:
@pytest.fixture
- def many_tests_files(self, testdir):
- testdir.makepyfile(
+ def many_tests_files(self, pytester: Pytester) -> None:
+ pytester.makepyfile(
test_bar="""
import pytest
@pytest.mark.parametrize('i', range(10))
@@ -1859,10 +1880,10 @@ class TestProgressOutputStyle:
""",
)
- def test_zero_tests_collected(self, testdir):
+ def test_zero_tests_collected(self, pytester: Pytester) -> None:
"""Some plugins (testmon for example) might issue pytest_runtest_logreport without any tests being
actually collected (#2971)."""
- testdir.makeconftest(
+ pytester.makeconftest(
"""
def pytest_collection_modifyitems(items, config):
from _pytest.runner import CollectReport
@@ -1873,12 +1894,12 @@ class TestProgressOutputStyle:
config.hook.pytest_runtest_logreport(report=rep)
"""
)
- output = testdir.runpytest()
+ output = pytester.runpytest()
output.stdout.no_fnmatch_line("*ZeroDivisionError*")
output.stdout.fnmatch_lines(["=* 2 passed in *="])
- def test_normal(self, many_tests_files, testdir):
- output = testdir.runpytest()
+ def test_normal(self, many_tests_files, pytester: Pytester) -> None:
+ output = pytester.runpytest()
output.stdout.re_match_lines(
[
r"test_bar.py \.{10} \s+ \[ 50%\]",
@@ -1887,9 +1908,11 @@ class TestProgressOutputStyle:
]
)
- def test_colored_progress(self, testdir, monkeypatch, color_mapping):
+ def test_colored_progress(
+ self, pytester: Pytester, monkeypatch, color_mapping
+ ) -> None:
monkeypatch.setenv("PY_COLORS", "1")
- testdir.makepyfile(
+ pytester.makepyfile(
test_axfail="""
import pytest
@pytest.mark.xfail
@@ -1914,7 +1937,7 @@ class TestProgressOutputStyle:
def test_foobar(i): raise ValueError()
""",
)
- result = testdir.runpytest()
+ result = pytester.runpytest()
result.stdout.re_match_lines(
color_mapping.format_for_rematch(
[
@@ -1927,7 +1950,7 @@ class TestProgressOutputStyle:
)
# Only xfail should have yellow progress indicator.
- result = testdir.runpytest("test_axfail.py")
+ result = pytester.runpytest("test_axfail.py")
result.stdout.re_match_lines(
color_mapping.format_for_rematch(
[
@@ -1937,14 +1960,14 @@ class TestProgressOutputStyle:
)
)
- def test_count(self, many_tests_files, testdir):
- testdir.makeini(
+ def test_count(self, many_tests_files, pytester: Pytester) -> None:
+ pytester.makeini(
"""
[pytest]
console_output_style = count
"""
)
- output = testdir.runpytest()
+ output = pytester.runpytest()
output.stdout.re_match_lines(
[
r"test_bar.py \.{10} \s+ \[10/20\]",
@@ -1953,8 +1976,8 @@ class TestProgressOutputStyle:
]
)
- def test_verbose(self, many_tests_files, testdir):
- output = testdir.runpytest("-v")
+ def test_verbose(self, many_tests_files, pytester: Pytester) -> None:
+ output = pytester.runpytest("-v")
output.stdout.re_match_lines(
[
r"test_bar.py::test_bar\[0\] PASSED \s+ \[ 5%\]",
@@ -1963,14 +1986,14 @@ class TestProgressOutputStyle:
]
)
- def test_verbose_count(self, many_tests_files, testdir):
- testdir.makeini(
+ def test_verbose_count(self, many_tests_files, pytester: Pytester) -> None:
+ pytester.makeini(
"""
[pytest]
console_output_style = count
"""
)
- output = testdir.runpytest("-v")
+ output = pytester.runpytest("-v")
output.stdout.re_match_lines(
[
r"test_bar.py::test_bar\[0\] PASSED \s+ \[ 1/20\]",
@@ -1979,28 +2002,34 @@ class TestProgressOutputStyle:
]
)
- def test_xdist_normal(self, many_tests_files, testdir, monkeypatch):
+ def test_xdist_normal(
+ self, many_tests_files, pytester: Pytester, monkeypatch
+ ) -> None:
pytest.importorskip("xdist")
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
- output = testdir.runpytest("-n2")
+ output = pytester.runpytest("-n2")
output.stdout.re_match_lines([r"\.{20} \s+ \[100%\]"])
- def test_xdist_normal_count(self, many_tests_files, testdir, monkeypatch):
+ def test_xdist_normal_count(
+ self, many_tests_files, pytester: Pytester, monkeypatch
+ ) -> None:
pytest.importorskip("xdist")
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
- testdir.makeini(
+ pytester.makeini(
"""
[pytest]
console_output_style = count
"""
)
- output = testdir.runpytest("-n2")
+ output = pytester.runpytest("-n2")
output.stdout.re_match_lines([r"\.{20} \s+ \[20/20\]"])
- def test_xdist_verbose(self, many_tests_files, testdir, monkeypatch):
+ def test_xdist_verbose(
+ self, many_tests_files, pytester: Pytester, monkeypatch
+ ) -> None:
pytest.importorskip("xdist")
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
- output = testdir.runpytest("-n2", "-v")
+ output = pytester.runpytest("-n2", "-v")
output.stdout.re_match_lines_random(
[
r"\[gw\d\] \[\s*\d+%\] PASSED test_bar.py::test_bar\[1\]",
@@ -2025,13 +2054,13 @@ class TestProgressOutputStyle:
]
)
- def test_capture_no(self, many_tests_files, testdir):
- output = testdir.runpytest("-s")
+ def test_capture_no(self, many_tests_files, pytester: Pytester) -> None:
+ output = pytester.runpytest("-s")
output.stdout.re_match_lines(
[r"test_bar.py \.{10}", r"test_foo.py \.{5}", r"test_foobar.py \.{5}"]
)
- output = testdir.runpytest("--capture=no")
+ output = pytester.runpytest("--capture=no")
output.stdout.no_fnmatch_line("*%]*")
@@ -2039,8 +2068,8 @@ class TestProgressWithTeardown:
"""Ensure we show the correct percentages for tests that fail during teardown (#3088)"""
@pytest.fixture
- def contest_with_teardown_fixture(self, testdir):
- testdir.makeconftest(
+ def contest_with_teardown_fixture(self, pytester: Pytester) -> None:
+ pytester.makeconftest(
"""
import pytest
@@ -2052,8 +2081,8 @@ class TestProgressWithTeardown:
)
@pytest.fixture
- def many_files(self, testdir, contest_with_teardown_fixture):
- testdir.makepyfile(
+ def many_files(self, pytester: Pytester, contest_with_teardown_fixture) -> None:
+ pytester.makepyfile(
test_bar="""
import pytest
@pytest.mark.parametrize('i', range(5))
@@ -2068,26 +2097,28 @@ class TestProgressWithTeardown:
""",
)
- def test_teardown_simple(self, testdir, contest_with_teardown_fixture):
- testdir.makepyfile(
+ def test_teardown_simple(
+ self, pytester: Pytester, contest_with_teardown_fixture
+ ) -> None:
+ pytester.makepyfile(
"""
def test_foo(fail_teardown):
pass
"""
)
- output = testdir.runpytest()
+ output = pytester.runpytest()
output.stdout.re_match_lines([r"test_teardown_simple.py \.E\s+\[100%\]"])
def test_teardown_with_test_also_failing(
- self, testdir, contest_with_teardown_fixture
- ):
- testdir.makepyfile(
+ self, pytester: Pytester, contest_with_teardown_fixture
+ ) -> None:
+ pytester.makepyfile(
"""
def test_foo(fail_teardown):
assert 0
"""
)
- output = testdir.runpytest("-rfE")
+ output = pytester.runpytest("-rfE")
output.stdout.re_match_lines(
[
r"test_teardown_with_test_also_failing.py FE\s+\[100%\]",
@@ -2096,16 +2127,16 @@ class TestProgressWithTeardown:
]
)
- def test_teardown_many(self, testdir, many_files):
- output = testdir.runpytest()
+ def test_teardown_many(self, pytester: Pytester, many_files) -> None:
+ output = pytester.runpytest()
output.stdout.re_match_lines(
[r"test_bar.py (\.E){5}\s+\[ 25%\]", r"test_foo.py (\.E){15}\s+\[100%\]"]
)
def test_teardown_many_verbose(
- self, testdir: Testdir, many_files, color_mapping
+ self, pytester: Pytester, many_files, color_mapping
) -> None:
- result = testdir.runpytest("-v")
+ result = pytester.runpytest("-v")
result.stdout.fnmatch_lines(
color_mapping.format_for_fnmatch(
[
@@ -2119,10 +2150,10 @@ class TestProgressWithTeardown:
)
)
- def test_xdist_normal(self, many_files, testdir, monkeypatch):
+ def test_xdist_normal(self, many_files, pytester: Pytester, monkeypatch) -> None:
pytest.importorskip("xdist")
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
- output = testdir.runpytest("-n2")
+ output = pytester.runpytest("-n2")
output.stdout.re_match_lines([r"[\.E]{40} \s+ \[100%\]"])
@@ -2160,7 +2191,7 @@ def test_skip_reasons_folding() -> None:
assert reason == message
-def test_line_with_reprcrash(monkeypatch):
+def test_line_with_reprcrash(monkeypatch: MonkeyPatch) -> None:
mocked_verbose_word = "FAILED"
mocked_pos = "some::nodeid"
@@ -2242,9 +2273,9 @@ def test_format_session_duration(seconds, expected):
assert format_session_duration(seconds) == expected
-def test_collecterror(testdir):
- p1 = testdir.makepyfile("raise SyntaxError()")
- result = testdir.runpytest("-ra", str(p1))
+def test_collecterror(pytester: Pytester) -> None:
+ p1 = pytester.makepyfile("raise SyntaxError()")
+ result = pytester.runpytest("-ra", str(p1))
result.stdout.fnmatch_lines(
[
"collected 0 items / 1 error",
@@ -2259,29 +2290,29 @@ def test_collecterror(testdir):
)
-def test_no_summary_collecterror(testdir):
- p1 = testdir.makepyfile("raise SyntaxError()")
- result = testdir.runpytest("-ra", "--no-summary", str(p1))
+def test_no_summary_collecterror(pytester: Pytester) -> None:
+ p1 = pytester.makepyfile("raise SyntaxError()")
+ result = pytester.runpytest("-ra", "--no-summary", str(p1))
result.stdout.no_fnmatch_line("*= ERRORS =*")
-def test_via_exec(testdir: Testdir) -> None:
- p1 = testdir.makepyfile("exec('def test_via_exec(): pass')")
- result = testdir.runpytest(str(p1), "-vv")
+def test_via_exec(pytester: Pytester) -> None:
+ p1 = pytester.makepyfile("exec('def test_via_exec(): pass')")
+ result = pytester.runpytest(str(p1), "-vv")
result.stdout.fnmatch_lines(
["test_via_exec.py::test_via_exec <- <string> PASSED*", "*= 1 passed in *"]
)
class TestCodeHighlight:
- def test_code_highlight_simple(self, testdir: Testdir, color_mapping) -> None:
- testdir.makepyfile(
+ def test_code_highlight_simple(self, pytester: Pytester, color_mapping) -> None:
+ pytester.makepyfile(
"""
def test_foo():
assert 1 == 10
"""
)
- result = testdir.runpytest("--color=yes")
+ result = pytester.runpytest("--color=yes")
result.stdout.fnmatch_lines(
color_mapping.format_for_fnmatch(
[
@@ -2292,15 +2323,17 @@ class TestCodeHighlight:
)
)
- def test_code_highlight_continuation(self, testdir: Testdir, color_mapping) -> None:
- testdir.makepyfile(
+ def test_code_highlight_continuation(
+ self, pytester: Pytester, color_mapping
+ ) -> None:
+ pytester.makepyfile(
"""
def test_foo():
print('''
'''); assert 0
"""
)
- result = testdir.runpytest("--color=yes")
+ result = pytester.runpytest("--color=yes")
result.stdout.fnmatch_lines(
color_mapping.format_for_fnmatch(