File: test_fixture_mistakes.py

package info (click to toggle)
python-pytest-trio 0.8.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 464 kB
  • sloc: python: 944; sh: 49; makefile: 20
file content (167 lines) | stat: -rw-r--r-- 4,134 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import pytest
from pytest_trio import trio_fixture

from .helpers import enable_trio_mode


def test_trio_fixture_with_non_trio_test(testdir):
    testdir.makepyfile(
        """
        import trio
        from pytest_trio import trio_fixture
        import pytest

        @trio_fixture
        def trio_time():
            return trio.current_time()

        @pytest.fixture
        def indirect_trio_time(trio_time):
            return trio_time + 1

        @pytest.mark.trio
        async def test_async(mock_clock, trio_time, indirect_trio_time):
            assert trio_time == 0
            assert indirect_trio_time == 1

        def test_sync(trio_time):
            pass

        def test_sync_indirect(indirect_trio_time):
            pass
        """
    )

    result = testdir.runpytest()

    result.assert_outcomes(passed=1, errors=2)
    result.stdout.fnmatch_lines(["*: Trio fixtures can only be used by Trio tests*"])


def test_trio_fixture_with_wrong_scope_without_trio_mode(testdir):
    # There's a trick here: when you have a non-function-scope fixture, it's
    # not instantiated for any particular function (obviously). So... when our
    # pytest_fixture_setup hook tries to check for marks, it can't normally
    # see @pytest.mark.trio. So... it's actually almost impossible to have an
    # async fixture get treated as a Trio fixture *and* have it be
    # non-function-scope. But, class-scoped fixtures can see marks on the
    # class, so this is one way (the only way?) it can happen:
    testdir.makepyfile(
        """
        import pytest

        @pytest.fixture(scope="class")
        async def async_class_fixture():
            pass

        @pytest.mark.trio
        class TestFoo:
            async def test_foo(self, async_class_fixture):
                pass
        """
    )

    result = testdir.runpytest()

    result.assert_outcomes(errors=1)
    result.stdout.fnmatch_lines(["*: Trio fixtures must be function-scope*"])


@enable_trio_mode
def test_trio_fixture_with_wrong_scope_in_trio_mode(testdir, enable_trio_mode):
    enable_trio_mode(testdir)

    testdir.makepyfile(
        """
        import pytest

        @pytest.fixture(scope="session")
        async def async_session_fixture():
            pass


        async def test_whatever(async_session_fixture):
            pass
        """
    )

    result = testdir.runpytest()

    result.assert_outcomes(errors=1)
    result.stdout.fnmatch_lines(["*: Trio fixtures must be function-scope*"])


@enable_trio_mode
def test_async_fixture_with_sync_test_in_trio_mode(testdir, enable_trio_mode):
    enable_trio_mode(testdir)

    testdir.makepyfile(
        """
        import pytest

        @pytest.fixture
        async def async_fixture():
            pass


        def test_whatever(async_fixture):
            pass
        """
    )

    result = testdir.runpytest()

    result.assert_outcomes(errors=1)
    result.stdout.fnmatch_lines(["*: Trio fixtures can only be used by Trio tests*"])


@enable_trio_mode
def test_fixture_cancels_test_but_doesnt_raise(testdir, enable_trio_mode):
    enable_trio_mode(testdir)

    testdir.makepyfile(
        """
        import pytest
        import trio

        @pytest.fixture
        async def async_fixture():
            with trio.CancelScope() as cscope:
                cscope.cancel()
                yield


        async def test_whatever(async_fixture):
            pass
        """
    )

    result = testdir.runpytest()

    result.assert_outcomes(failed=1)
    result.stdout.fnmatch_lines(["*async_fixture*cancelled the test*"])


@enable_trio_mode
def test_too_many_clocks(testdir, enable_trio_mode):
    enable_trio_mode(testdir)

    testdir.makepyfile(
        """
        import pytest

        @pytest.fixture
        def extra_clock(mock_clock):
            return mock_clock

        async def test_whatever(mock_clock, extra_clock):
            pass
        """
    )

    result = testdir.runpytest()

    result.assert_outcomes(failed=1)
    result.stdout.fnmatch_lines(
        ["*ValueError: Expected at most one Clock in kwargs, got *"]
    )