File: test_raises.py

package info (click to toggle)
pytest-check 2.7.6-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 480 kB
  • sloc: python: 2,220; sh: 17; makefile: 6
file content (255 lines) | stat: -rw-r--r-- 6,735 bytes parent folder | download
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
import pytest

from pytest_check import raises


class BaseTestException(Exception):
    pass


class _TestException(BaseTestException):
    pass


class AnotherTestException(BaseTestException):
    pass


BASE_IMPORTS_AND_EXCEPTIONS = """
from pytest_check import raises

class BaseTestException(Exception):
    pass


class _TestException(BaseTestException):
    pass


class AnotherTestException(BaseTestException):
    pass
"""


def test_raises():
    with raises(_TestException):
        raise _TestException


def test_raises_with_assertion_error():
    with raises(AssertionError):
        assert 0


def test_raises_with_multiple_errors(testdir):
    with raises((_TestException, AnotherTestException)):
        raise _TestException

    with raises((_TestException, AnotherTestException)):
        raise AnotherTestException

    testdir.makepyfile(
        BASE_IMPORTS_AND_EXCEPTIONS
        + """
def test_failures():
  with raises((_TestException, AnotherTestException)):
      raise AssertionError
""",
    )

    result = testdir.runpytest()
    result.assert_outcomes(failed=1, passed=0)
    result.stdout.re_match_lines(
        [
            "FAILURE: ",
            # Python < 3.10 reports error at `raise` but 3.10 reports at `with`
            r".*raise AssertionError.*"
            r"|.*with raises\(\(_TestException, AnotherTestException\)\):.*",
        ],
        consecutive=True,
    )


def test_raises_with_parents_and_children(testdir):
    with raises(BaseTestException):
        raise _TestException

    with raises((BaseTestException, _TestException)):
        raise BaseTestException

    with raises((BaseTestException, _TestException)):
        raise _TestException

    # Children shouldn't catch their parents, only vice versa.
    testdir.makepyfile(
        BASE_IMPORTS_AND_EXCEPTIONS
        + """
def test_failures():
    with raises((_TestException, AnotherTestException)):
        raise BaseTestException
""",
    )

    result = testdir.runpytest()
    result.assert_outcomes(failed=1, passed=0)
    result.stdout.re_match_lines(
        [
            "FAILURE: ",
            # Python < 3.10 reports error at `raise` but 3.10 reports at `with`
            r".*raise BaseTestException.*"
            r"|.*with raises\(\(_TestException, AnotherTestException\)\):.*",
        ],
        consecutive=True,
    )


@pytest.mark.parametrize(
    "run_flags,match_lines",
    [
        ("--exitfirst", ["test_raises_stop_on_fail.py:19: ValueError"]),
        ("", ["*Failed Checks: 2*"]),
    ],
)
def test_raises_stop_on_fail(run_flags, match_lines, testdir):
    """
    Test multiple failures with and without `--exitfirst`

    With `--exitfirst`, first error is the only one reported, and without,
    multiple errors are accumulated.
    """
    # test_failures below includes one passed check, two checked failures, and
    # a final passed check.  `--exitfirst` should result in only the first
    # error reported, and subsequent errors and successes are ignored.  Without
    # that flag, two failures should be counted and reported, and the last
    # success should be executed.
    testdir.makepyfile(
        BASE_IMPORTS_AND_EXCEPTIONS
        + """
def test_failures():
    with raises(BaseTestException):
        raise BaseTestException

    with raises(BaseTestException):
        raise ValueError

    with raises(BaseTestException):
        raise ValueError

    with raises(BaseTestException):
        raise BaseTestException
    """,
    )

    result = testdir.runpytest(run_flags)
    result.assert_outcomes(failed=1)
    result.stdout.fnmatch_lines(match_lines)


def test_can_mix_assertions_and_checks(pytester):
    """
    You can mix checks and asserts, but a failing assert stops test execution.
    """
    pytester.copy_example("examples/test_example_mix_checks_and_assertions.py")
    result = pytester.runpytest()
    result.assert_outcomes(failed=1)
    result.stdout.fnmatch_lines(
        [
            "*FAILURE:*",
            "*Failed Checks: 1*",
            "*assert 1 == 2*",
        ],
    )


def test_msg_kwarg_with_raises_context_manager(testdir):
    testdir.makepyfile(
        """
        from pytest_check import raises

        def raise_valueerror():
            raise ValueError

        def test():
            with raises(AssertionError, msg="hello, world!"):
                raise_valueerror()
    """,
    )

    result = testdir.runpytest()
    result.assert_outcomes(failed=1)
    result.stdout.fnmatch_lines(["FAILURE: hello, world!"])


def test_raises_function(testdir):
    def raise_error():
        raise _TestException

    # Single exception
    raises(_TestException, raise_error)

    # Multiple exceptions
    raises((_TestException, AnotherTestException), raise_error)

    def assert_foo_equals_bar(foo, bar=None):
        assert foo == bar

    # Test args and kwargs are passed to callable
    raises(AssertionError, assert_foo_equals_bar, 1, bar=2)

    # Kwarg `msg` is special and can be found in failure output.
    testdir.makepyfile(
        """
        from pytest_check import raises

        def raise_valueerror():
            raise ValueError

        def test():
            raises(AssertionError, raise_valueerror, msg="hello, world!")
    """,
    )

    result = testdir.runpytest()
    result.assert_outcomes(failed=1)
    result.stdout.fnmatch_lines(["FAILURE: hello, world!"])


def test_raises_with_exception_value():
    with raises(_TestException) as e:
        raise _TestException("This is a _TestException")
    assert str(e.value) == "This is a _TestException"


def test_raises_with_empty_exception_value():
    with raises(_TestException) as e:
        raise _TestException
    assert str(e.value) == ""


def test_raises_with_none_exception_value(testdir):
    testdir.makepyfile(
        """
        from pytest_check import raises

        def test():
            with raises(AssertionError) as e:
                x = 1
                assert x == 1
            
            assert str(e.value) == "None"
    """,
    )

    result = testdir.runpytest()
    result.assert_outcomes(failed=1)
    result.stdout.fnmatch_lines(["FAILURE: None"])
    result.stdout.no_fnmatch_line("*assert str(e.value) == 'None'*")
    result.stdout.no_fnmatch_line("*AssertionError: assert 'None'*")

def test_raises_custom_msg(run_example_test):
    result = run_example_test("test_example_raises.py", 'test_raises_msg_fail', '-ra')
    result.assert_outcomes(failed=1)
    expected_line = 'FAILED test_example_raises.py::test_raises_msg_fail'
    if pytest.version_tuple >= (7, 3, 0):  # pragma: no branch
        expected_line += ' - Custom error message'
    result.stdout.fnmatch_lines([expected_line])