コード例 #1
0
def test_pdb_teardown_skipped(pytester: Pytester, monkeypatch: MonkeyPatch,
                              mark: str) -> None:
    """With --pdb, setUp and tearDown should not be called for skipped tests."""
    tracked: List[str] = []
    monkeypatch.setattr(pytest,
                        "test_pdb_teardown_skipped",
                        tracked,
                        raising=False)

    pytester.makepyfile("""
        import unittest
        import pytest

        class MyTestCase(unittest.TestCase):

            def setUp(self):
                pytest.test_pdb_teardown_skipped.append("setUp:" + self.id())

            def tearDown(self):
                pytest.test_pdb_teardown_skipped.append("tearDown:" + self.id())

            {mark}("skipped for reasons")
            def test_1(self):
                pass

    """.format(mark=mark))
    result = pytester.runpytest_inprocess("--pdb")
    result.stdout.fnmatch_lines("* 1 skipped in *")
    assert tracked == []
コード例 #2
0
 def test_pdb_custom_cls_without_pdb(self, pytester: Pytester,
                                     custom_pdb_calls: List[str]) -> None:
     p1 = pytester.makepyfile("""xxx """)
     result = pytester.runpytest_inprocess("--pdbcls=_pytest:_CustomPdb",
                                           p1)
     result.stdout.fnmatch_lines(["*NameError*xxx*", "*1 error*"])
     assert custom_pdb_calls == []
コード例 #3
0
def runpdb_and_get_report(pytester: Pytester, source: str):
    p = pytester.makepyfile(source)
    result = pytester.runpytest_inprocess("--pdb", p)
    reports = result.reprec.getreports(
        "pytest_runtest_logreport")  # type: ignore[attr-defined]
    assert len(reports) == 3, reports  # setup/call/teardown
    return reports[1]
コード例 #4
0
def test_current_test_env_var(pytester: Pytester,
                              monkeypatch: MonkeyPatch) -> None:
    pytest_current_test_vars: List[Tuple[str, str]] = []
    monkeypatch.setattr(sys,
                        "pytest_current_test_vars",
                        pytest_current_test_vars,
                        raising=False)
    pytester.makepyfile("""
        import pytest
        import sys
        import os

        @pytest.fixture
        def fix():
            sys.pytest_current_test_vars.append(('setup', os.environ['PYTEST_CURRENT_TEST']))
            yield
            sys.pytest_current_test_vars.append(('teardown', os.environ['PYTEST_CURRENT_TEST']))

        def test(fix):
            sys.pytest_current_test_vars.append(('call', os.environ['PYTEST_CURRENT_TEST']))
    """)
    result = pytester.runpytest_inprocess()
    assert result.ret == 0
    test_id = "test_current_test_env_var.py::test"
    assert pytest_current_test_vars == [
        ("setup", test_id + " (setup)"),
        ("call", test_id + " (call)"),
        ("teardown", test_id + " (teardown)"),
    ]
    assert "PYTEST_CURRENT_TEST" not in os.environ
コード例 #5
0
def test_pdb_teardown_called(pytester: Pytester,
                             monkeypatch: MonkeyPatch) -> None:
    """Ensure tearDown() is always called when --pdb is given in the command-line.

    We delay the normal tearDown() calls when --pdb is given, so this ensures we are calling
    tearDown() eventually to avoid memory leaks when using --pdb.
    """
    teardowns: List[str] = []
    monkeypatch.setattr(pytest,
                        "test_pdb_teardown_called_teardowns",
                        teardowns,
                        raising=False)

    pytester.makepyfile("""
        import unittest
        import pytest

        class MyTestCase(unittest.TestCase):

            def tearDown(self):
                pytest.test_pdb_teardown_called_teardowns.append(self.id())

            def test_1(self):
                pass
            def test_2(self):
                pass
    """)
    result = pytester.runpytest_inprocess("--pdb")
    result.stdout.fnmatch_lines("* 2 passed in *")
    assert teardowns == [
        "test_pdb_teardown_called.MyTestCase.test_1",
        "test_pdb_teardown_called.MyTestCase.test_2",
    ]
コード例 #6
0
def test_clean_up(pytester: Pytester) -> None:
    """Test that the plugin cleans up after itself."""
    # This is tough to test behaviorly because the cleanup really runs last.
    # So the test make several implementation assumptions:
    # - Cleanup is done in pytest_unconfigure().
    # - Not a hookwrapper.
    # So we can add a hookwrapper ourselves to test what it does.
    pytester.makefile(".ini",
                      pytest="[pytest]\npythonpath=I_SHALL_BE_REMOVED\n")
    pytester.makepyfile(test_foo="""def test_foo(): pass""")

    before: Optional[List[str]] = None
    after: Optional[List[str]] = None

    class Plugin:
        @pytest.hookimpl(hookwrapper=True, tryfirst=True)
        def pytest_unconfigure(self) -> Generator[None, None, None]:
            nonlocal before, after
            before = sys.path.copy()
            yield
            after = sys.path.copy()

    result = pytester.runpytest_inprocess(plugins=[Plugin()])
    assert result.ret == 0

    assert before is not None
    assert after is not None
    assert any("I_SHALL_BE_REMOVED" in entry for entry in before)
    assert not any("I_SHALL_BE_REMOVED" in entry for entry in after)
コード例 #7
0
    def test_calls_show_2(self, pytester: Pytester, mock_timing) -> None:

        pytester.makepyfile(self.source)
        result = pytester.runpytest_inprocess("--durations=2")
        assert result.ret == 0

        lines = result.stdout.get_lines_after("*slowest*durations*")
        assert "4 passed" in lines[2]
コード例 #8
0
    def test_early_load_setuptools_name(
        self, pytester: Pytester, monkeypatch, load_cov_early
    ) -> None:
        monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD")

        pytester.makepyfile(mytestplugin1_module="")
        pytester.makepyfile(mytestplugin2_module="")
        pytester.makepyfile(mycov_module="")
        pytester.syspathinsert()

        loaded = []

        @attr.s
        class DummyEntryPoint:
            name = attr.ib()
            module = attr.ib()
            group = "pytest11"

            def load(self):
                __import__(self.module)
                loaded.append(self.name)
                return sys.modules[self.module]

        entry_points = [
            DummyEntryPoint("myplugin1", "mytestplugin1_module"),
            DummyEntryPoint("myplugin2", "mytestplugin2_module"),
            DummyEntryPoint("mycov", "mycov_module"),
        ]

        @attr.s
        class DummyDist:
            entry_points = attr.ib()
            files = ()

        def my_dists():
            return (DummyDist(entry_points),)

        monkeypatch.setattr(importlib_metadata, "distributions", my_dists)
        params = ("-p", "mycov") if load_cov_early else ()
        pytester.runpytest_inprocess(*params)
        if load_cov_early:
            assert loaded == ["mycov", "myplugin1", "myplugin2"]
        else:
            assert loaded == ["myplugin1", "myplugin2", "mycov"]
コード例 #9
0
 def test_pdb_custom_cls(self, pytester: Pytester,
                         custom_debugger_hook) -> None:
     p1 = pytester.makepyfile("""
         def test_nothing():
             breakpoint()
     """)
     result = pytester.runpytest_inprocess(
         "--pdb", "--pdbcls=_pytest:_CustomDebugger", p1)
     result.stdout.fnmatch_lines(["*CustomDebugger*", "*1 passed*"])
     assert custom_debugger_hook == ["init", "set_trace"]
コード例 #10
0
def test_executable_path_commandoption(pytester: Pytester):
    testcase_path = pytester.makepyfile("""
    def test_executable_path(executable_path, default_executable_path):
        assert executable_path != default_executable_path
        assert executable_path == "path/to/chrome"
    """)
    result = pytester.runpytest_inprocess(testcase_path, "--executable-path",
                                          "path/to/chrome")

    result.assert_outcomes(passed=1)
コード例 #11
0
ファイル: acceptance_test.py プロジェクト: yaoan8844/pytest
    def test_setup_function(self, pytester: Pytester, mock_timing) -> None:
        pytester.makepyfile(self.source)
        result = pytester.runpytest_inprocess("--durations=10")
        assert result.ret == 0

        result.stdout.fnmatch_lines_random("""
            *durations*
            5.00s call *test_1*
            2.00s setup *test_1*
        """)
コード例 #12
0
    def test_with_failing_collection(self, pytester: Pytester, mock_timing) -> None:
        pytester.makepyfile(self.source)
        pytester.makepyfile(test_collecterror="""xyz""")
        result = pytester.runpytest_inprocess("--durations=2", "-k test_1")
        assert result.ret == 2

        result.stdout.fnmatch_lines(["*Interrupted: 1 error during collection*"])
        # Collection errors abort test execution, therefore no duration is
        # output
        result.stdout.no_fnmatch_line("*duration*")
コード例 #13
0
ファイル: acceptance_test.py プロジェクト: yaoan8844/pytest
    def test_calls(self, pytester: Pytester, mock_timing) -> None:
        pytester.makepyfile(self.source)
        result = pytester.runpytest_inprocess("--durations=10")
        assert result.ret == 0

        result.stdout.fnmatch_lines_random(
            ["*durations*", "*call*test_3*", "*call*test_2*"])

        result.stdout.fnmatch_lines([
            "(8 durations < 0.005s hidden.  Use -vv to show these durations.)"
        ])
コード例 #14
0
    def test_calls_showall_verbose(self, pytester: Pytester, mock_timing) -> None:
        pytester.makepyfile(self.source)
        result = pytester.runpytest_inprocess("--durations=0", "-vv")
        assert result.ret == 0

        for x in "123":
            for y in ("call",):  # 'setup', 'call', 'teardown':
                for line in result.stdout.lines:
                    if ("test_%s" % x) in line and y in line:
                        break
                else:
                    raise AssertionError(f"not found {x} {y}")
コード例 #15
0
def test_options_updating(pytester: Pytester):
    testcase_path = pytester.makepyfile("""
    import pytest

    @pytest.mark.options(devtools=True, headless=True)
    def test_options(options):
        assert options["devtools"] is True
        assert options["headless"] is True
    """)

    result = pytester.runpytest_inprocess(testcase_path)

    result.assert_outcomes(passed=1)
コード例 #16
0
def test_pytester_subprocess_via_runpytest_arg(pytester: Pytester) -> None:
    testfile = pytester.makepyfile("""
        def test_pytester_subprocess(pytester):
            import os
            testfile = pytester.makepyfile(
                \"""
                import os
                def test_one():
                    assert {} != os.getpid()
                \""".format(os.getpid())
            )
            assert pytester.runpytest(testfile).ret == 0
        """)
    result = pytester.runpytest_inprocess("-p", "pytester", "--runpytest",
                                          "subprocess", testfile)
    assert result.ret == 0
コード例 #17
0
def test_args_commandoption(pytester: Pytester):
    testcase_path = pytester.makepyfile("""
    def test_args(args):
        assert args == ["--proxy-server=localhost:5555,direct://", "--proxy-bypass-list=192.0.0.1/8;10.0.0.1/8"]
    """)

    result = pytester.runpytest_inprocess(
        testcase_path,
        "--args",
        "proxy-server",
        "localhost:5555,direct://",
        "--args",
        "proxy-bypass-list",
        "192.0.0.1/8;10.0.0.1/8",
    )

    result.assert_outcomes(passed=1)
コード例 #18
0
def test_function_item_obj_is_instance(pytester: Pytester) -> None:
    """item.obj should be a bound method on unittest.TestCase function items (#5390)."""
    pytester.makeconftest("""
        def pytest_runtest_makereport(item, call):
            if call.when == 'call':
                class_ = item.parent.obj
                assert isinstance(item.obj.__self__, class_)
    """)
    pytester.makepyfile("""
        import unittest

        class Test(unittest.TestCase):
            def test_foo(self):
                pass
    """)
    result = pytester.runpytest_inprocess()
    result.stdout.fnmatch_lines(["* 1 passed in*"])
コード例 #19
0
def test_platform_unknown(pytester: Pytester):
    pytester.makeconftest("""
    import pytest

    @pytest.fixture(scope="session")
    def platform():
        return "unknown"
    """)

    testcase_path = pytester.makepyfile("""
    def test_default_executable_path(default_executable_path):
        assert default_executable_path is None

    def test_executable_path(executable_path):
        assert executable_path is None
    """)
    result = pytester.runpytest_inprocess(testcase_path)

    result.assert_outcomes(passed=2)
コード例 #20
0
def test_clean_up_pythonpath(pytester: Pytester) -> None:
    """Test that the srcpaths plugin cleans up after itself."""
    pytester.makefile(".ini", pytest="[pytest]\npythonpath=I_SHALL_BE_REMOVED\n")
    pytester.makepyfile(test_foo="""def test_foo(): pass""")

    before: Optional[List[str]] = None
    after: Optional[List[str]] = None

    class Plugin:
        @pytest.hookimpl(hookwrapper=True, tryfirst=True)
        def pytest_unconfigure(self) -> Generator[None, None, None]:
            nonlocal before, after
            before = sys.path.copy()
            yield
            after = sys.path.copy()

    result = pytester.runpytest_inprocess(plugins=[Plugin()])
    assert result.ret == 0

    assert before is not None
    assert after is not None
    assert any("I_SHALL_BE_REMOVED" in entry for entry in before)
    assert not any("I_SHALL_BE_REMOVED" in entry for entry in after)
コード例 #21
0
 def test_with_not(self, pytester: Pytester, mock_timing) -> None:
     pytester.makepyfile(self.source)
     result = pytester.runpytest_inprocess("-k not 1")
     assert result.ret == 0
コード例 #22
0
    def test_with_deselected(self, pytester: Pytester, mock_timing) -> None:
        pytester.makepyfile(self.source)
        result = pytester.runpytest_inprocess("--durations=2", "-k test_3")
        assert result.ret == 0

        result.stdout.fnmatch_lines(["*durations*", "*call*test_3*"])
コード例 #23
0
 def test_pdb_custom_cls_invalid(self, pytester: Pytester) -> None:
     result = pytester.runpytest_inprocess("--pdbcls=invalid")
     result.stderr.fnmatch_lines([
         "*: error: argument --pdbcls: 'invalid' is not in the format 'modname:classname'"
     ])