1""" 2Tests and examples for correct "+/-" usage in error diffs. 3 4See https://github.com/pytest-dev/pytest/issues/3333 for details. 5 6""" 7import sys 8 9import pytest 10 11 12TESTCASES = [ 13 pytest.param( 14 """ 15 def test_this(): 16 result = [1, 4, 3] 17 expected = [1, 2, 3] 18 assert result == expected 19 """, 20 """ 21 > assert result == expected 22 E assert [1, 4, 3] == [1, 2, 3] 23 E At index 1 diff: 4 != 2 24 E Full diff: 25 E - [1, 2, 3] 26 E ? ^ 27 E + [1, 4, 3] 28 E ? ^ 29 """, 30 id="Compare lists, one item differs", 31 ), 32 pytest.param( 33 """ 34 def test_this(): 35 result = [1, 2, 3] 36 expected = [1, 2] 37 assert result == expected 38 """, 39 """ 40 > assert result == expected 41 E assert [1, 2, 3] == [1, 2] 42 E Left contains one more item: 3 43 E Full diff: 44 E - [1, 2] 45 E + [1, 2, 3] 46 E ? +++ 47 """, 48 id="Compare lists, one extra item", 49 ), 50 pytest.param( 51 """ 52 def test_this(): 53 result = [1, 3] 54 expected = [1, 2, 3] 55 assert result == expected 56 """, 57 """ 58 > assert result == expected 59 E assert [1, 3] == [1, 2, 3] 60 E At index 1 diff: 3 != 2 61 E Right contains one more item: 3 62 E Full diff: 63 E - [1, 2, 3] 64 E ? --- 65 E + [1, 3] 66 """, 67 id="Compare lists, one item missing", 68 ), 69 pytest.param( 70 """ 71 def test_this(): 72 result = (1, 4, 3) 73 expected = (1, 2, 3) 74 assert result == expected 75 """, 76 """ 77 > assert result == expected 78 E assert (1, 4, 3) == (1, 2, 3) 79 E At index 1 diff: 4 != 2 80 E Full diff: 81 E - (1, 2, 3) 82 E ? ^ 83 E + (1, 4, 3) 84 E ? ^ 85 """, 86 id="Compare tuples", 87 ), 88 pytest.param( 89 """ 90 def test_this(): 91 result = {1, 3, 4} 92 expected = {1, 2, 3} 93 assert result == expected 94 """, 95 """ 96 > assert result == expected 97 E assert {1, 3, 4} == {1, 2, 3} 98 E Extra items in the left set: 99 E 4 100 E Extra items in the right set: 101 E 2 102 E Full diff: 103 E - {1, 2, 3} 104 E ? ^ ^ 105 E + {1, 3, 4} 106 E ? ^ ^ 107 """, 108 id="Compare sets", 109 ), 110 pytest.param( 111 """ 112 def test_this(): 113 result = {1: 'spam', 3: 'eggs'} 114 expected = {1: 'spam', 2: 'eggs'} 115 assert result == expected 116 """, 117 """ 118 > assert result == expected 119 E AssertionError: assert {1: 'spam', 3: 'eggs'} == {1: 'spam', 2: 'eggs'} 120 E Common items: 121 E {1: 'spam'} 122 E Left contains 1 more item: 123 E {3: 'eggs'} 124 E Right contains 1 more item: 125 E {2: 'eggs'} 126 E Full diff: 127 E - {1: 'spam', 2: 'eggs'} 128 E ? ^ 129 E + {1: 'spam', 3: 'eggs'} 130 E ? ^ 131 """, 132 id="Compare dicts with differing keys", 133 ), 134 pytest.param( 135 """ 136 def test_this(): 137 result = {1: 'spam', 2: 'eggs'} 138 expected = {1: 'spam', 2: 'bacon'} 139 assert result == expected 140 """, 141 """ 142 > assert result == expected 143 E AssertionError: assert {1: 'spam', 2: 'eggs'} == {1: 'spam', 2: 'bacon'} 144 E Common items: 145 E {1: 'spam'} 146 E Differing items: 147 E {2: 'eggs'} != {2: 'bacon'} 148 E Full diff: 149 E - {1: 'spam', 2: 'bacon'} 150 E ? ^^^^^ 151 E + {1: 'spam', 2: 'eggs'} 152 E ? ^^^^ 153 """, 154 id="Compare dicts with differing values", 155 ), 156 pytest.param( 157 """ 158 def test_this(): 159 result = {1: 'spam', 2: 'eggs'} 160 expected = {1: 'spam', 3: 'bacon'} 161 assert result == expected 162 """, 163 """ 164 > assert result == expected 165 E AssertionError: assert {1: 'spam', 2: 'eggs'} == {1: 'spam', 3: 'bacon'} 166 E Common items: 167 E {1: 'spam'} 168 E Left contains 1 more item: 169 E {2: 'eggs'} 170 E Right contains 1 more item: 171 E {3: 'bacon'} 172 E Full diff: 173 E - {1: 'spam', 3: 'bacon'} 174 E ? ^ ^^^^^ 175 E + {1: 'spam', 2: 'eggs'} 176 E ? ^ ^^^^ 177 """, 178 id="Compare dicts with differing items", 179 ), 180 pytest.param( 181 """ 182 def test_this(): 183 result = "spmaeggs" 184 expected = "spameggs" 185 assert result == expected 186 """, 187 """ 188 > assert result == expected 189 E AssertionError: assert 'spmaeggs' == 'spameggs' 190 E - spameggs 191 E ? - 192 E + spmaeggs 193 E ? + 194 """, 195 id="Compare strings", 196 ), 197 pytest.param( 198 """ 199 def test_this(): 200 result = "spam bacon eggs" 201 assert "bacon" not in result 202 """, 203 """ 204 > assert "bacon" not in result 205 E AssertionError: assert 'bacon' not in 'spam bacon eggs' 206 E 'bacon' is contained here: 207 E spam bacon eggs 208 E ? +++++ 209 """, 210 id='Test "not in" string', 211 ), 212] 213if sys.version_info[:2] >= (3, 7): 214 TESTCASES.extend( 215 [ 216 pytest.param( 217 """ 218 from dataclasses import dataclass 219 220 @dataclass 221 class A: 222 a: int 223 b: str 224 225 def test_this(): 226 result = A(1, 'spam') 227 expected = A(2, 'spam') 228 assert result == expected 229 """, 230 """ 231 > assert result == expected 232 E AssertionError: assert A(a=1, b='spam') == A(a=2, b='spam') 233 E Matching attributes: 234 E ['b'] 235 E Differing attributes: 236 E ['a'] 237 E Drill down into differing attribute a: 238 E a: 1 != 2 239 E +1 240 E -2 241 """, 242 id="Compare data classes", 243 ), 244 pytest.param( 245 """ 246 import attr 247 248 @attr.s(auto_attribs=True) 249 class A: 250 a: int 251 b: str 252 253 def test_this(): 254 result = A(1, 'spam') 255 expected = A(1, 'eggs') 256 assert result == expected 257 """, 258 """ 259 > assert result == expected 260 E AssertionError: assert A(a=1, b='spam') == A(a=1, b='eggs') 261 E Matching attributes: 262 E ['a'] 263 E Differing attributes: 264 E ['b'] 265 E Drill down into differing attribute b: 266 E b: 'spam' != 'eggs' 267 E - eggs 268 E + spam 269 """, 270 id="Compare attrs classes", 271 ), 272 ] 273 ) 274 275 276@pytest.mark.parametrize("code, expected", TESTCASES) 277def test_error_diff(code, expected, testdir): 278 expected = [line.lstrip() for line in expected.splitlines()] 279 p = testdir.makepyfile(code) 280 result = testdir.runpytest(p, "-vv") 281 result.stdout.fnmatch_lines(expected) 282 assert result.ret == 1 283