Skip to content

Commit 9417188

Browse files
gfyoungPingviinituutti
authored andcommitted
REF/TST: Add pytest idiom to test_testing (pandas-dev#24369)
Splits test file into multiple new files and delegates remaining tests to the miscellaneous test_util.py
1 parent f759b05 commit 9417188

12 files changed

+1484
-990
lines changed

ci/code_checks.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ if [[ -z "$CHECK" || "$CHECK" == "patterns" ]]; then
145145
RET=$(($RET + $?)) ; echo $MSG "DONE"
146146

147147
MSG='Check that the deprecated `assert_raises_regex` is not used (`pytest.raises(match=pattern)` should be used instead)' ; echo $MSG
148-
invgrep -R --exclude=*.pyc --exclude=testing.py --exclude=test_testing.py assert_raises_regex pandas
148+
invgrep -R --exclude=*.pyc --exclude=testing.py --exclude=test_util.py assert_raises_regex pandas
149149
RET=$(($RET + $?)) ; echo $MSG "DONE"
150150

151151
# Check that we use pytest.raises only as a context manager

pandas/tests/util/conftest.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import pytest
2+
3+
4+
@pytest.fixture(params=[True, False])
5+
def check_dtype(request):
6+
return request.param
7+
8+
9+
@pytest.fixture(params=[True, False])
10+
def check_exact(request):
11+
return request.param
12+
13+
14+
@pytest.fixture(params=[True, False])
15+
def check_index_type(request):
16+
return request.param
17+
18+
19+
@pytest.fixture(params=[True, False])
20+
def check_less_precise(request):
21+
return request.param
22+
23+
24+
@pytest.fixture(params=[True, False])
25+
def check_categorical(request):
26+
return request.param
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import numpy as np
4+
import pytest
5+
6+
from pandas import DataFrame, Index, Series, Timestamp
7+
from pandas.util.testing import assert_almost_equal
8+
9+
10+
def _assert_almost_equal_both(a, b, **kwargs):
11+
"""
12+
Check that two objects are approximately equal.
13+
14+
This check is performed commutatively.
15+
16+
Parameters
17+
----------
18+
a : object
19+
The first object to compare.
20+
b : object
21+
The second object to compare.
22+
kwargs : dict
23+
The arguments passed to `assert_almost_equal`.
24+
"""
25+
assert_almost_equal(a, b, **kwargs)
26+
assert_almost_equal(b, a, **kwargs)
27+
28+
29+
def _assert_not_almost_equal(a, b, **kwargs):
30+
"""
31+
Check that two objects are not approximately equal.
32+
33+
Parameters
34+
----------
35+
a : object
36+
The first object to compare.
37+
b : object
38+
The second object to compare.
39+
kwargs : dict
40+
The arguments passed to `assert_almost_equal`.
41+
"""
42+
try:
43+
assert_almost_equal(a, b, **kwargs)
44+
msg = ("{a} and {b} were approximately equal "
45+
"when they shouldn't have been").format(a=a, b=b)
46+
pytest.fail(msg=msg)
47+
except AssertionError:
48+
pass
49+
50+
51+
def _assert_not_almost_equal_both(a, b, **kwargs):
52+
"""
53+
Check that two objects are not approximately equal.
54+
55+
This check is performed commutatively.
56+
57+
Parameters
58+
----------
59+
a : object
60+
The first object to compare.
61+
b : object
62+
The second object to compare.
63+
kwargs : dict
64+
The arguments passed to `tm.assert_almost_equal`.
65+
"""
66+
_assert_not_almost_equal(a, b, **kwargs)
67+
_assert_not_almost_equal(b, a, **kwargs)
68+
69+
70+
@pytest.mark.parametrize("a,b", [
71+
(1.1, 1.1), (1.1, 1.100001), (np.int16(1), 1.000001),
72+
(np.float64(1.1), 1.1), (np.uint32(5), 5),
73+
])
74+
def test_assert_almost_equal_numbers(a, b):
75+
_assert_almost_equal_both(a, b)
76+
77+
78+
@pytest.mark.parametrize("a,b", [
79+
(1.1, 1), (1.1, True), (1, 2), (1.0001, np.int16(1)),
80+
])
81+
def test_assert_not_almost_equal_numbers(a, b):
82+
_assert_not_almost_equal_both(a, b)
83+
84+
85+
@pytest.mark.parametrize("a,b", [
86+
(0, 0), (0, 0.0), (0, np.float64(0)), (0.000001, 0),
87+
])
88+
def test_assert_almost_equal_numbers_with_zeros(a, b):
89+
_assert_almost_equal_both(a, b)
90+
91+
92+
@pytest.mark.parametrize("a,b", [
93+
(0.001, 0), (1, 0),
94+
])
95+
def test_assert_not_almost_equal_numbers_with_zeros(a, b):
96+
_assert_not_almost_equal_both(a, b)
97+
98+
99+
@pytest.mark.parametrize("a,b", [
100+
(1, "abc"), (1, [1, ]), (1, object()),
101+
])
102+
def test_assert_not_almost_equal_numbers_with_mixed(a, b):
103+
_assert_not_almost_equal_both(a, b)
104+
105+
106+
@pytest.mark.parametrize(
107+
"left_dtype", ["M8[ns]", "m8[ns]", "float64", "int64", "object"])
108+
@pytest.mark.parametrize(
109+
"right_dtype", ["M8[ns]", "m8[ns]", "float64", "int64", "object"])
110+
def test_assert_almost_equal_edge_case_ndarrays(left_dtype, right_dtype):
111+
# Empty compare.
112+
_assert_almost_equal_both(np.array([], dtype=left_dtype),
113+
np.array([], dtype=right_dtype),
114+
check_dtype=False)
115+
116+
117+
def test_assert_almost_equal_dicts():
118+
_assert_almost_equal_both({"a": 1, "b": 2}, {"a": 1, "b": 2})
119+
120+
121+
@pytest.mark.parametrize("a,b", [
122+
({"a": 1, "b": 2}, {"a": 1, "b": 3}),
123+
({"a": 1, "b": 2}, {"a": 1, "b": 2, "c": 3}),
124+
({"a": 1}, 1), ({"a": 1}, "abc"), ({"a": 1}, [1, ]),
125+
])
126+
def test_assert_not_almost_equal_dicts(a, b):
127+
_assert_not_almost_equal_both(a, b)
128+
129+
130+
@pytest.mark.parametrize("val", [1, 2])
131+
def test_assert_almost_equal_dict_like_object(val):
132+
dict_val = 1
133+
real_dict = dict(a=val)
134+
135+
class DictLikeObj(object):
136+
def keys(self):
137+
return "a",
138+
139+
def __getitem__(self, item):
140+
if item == "a":
141+
return dict_val
142+
143+
func = (_assert_almost_equal_both if val == dict_val
144+
else _assert_not_almost_equal_both)
145+
func(real_dict, DictLikeObj(), check_dtype=False)
146+
147+
148+
def test_assert_almost_equal_strings():
149+
_assert_almost_equal_both("abc", "abc")
150+
151+
152+
@pytest.mark.parametrize("a,b", [
153+
("abc", "abcd"), ("abc", "abd"), ("abc", 1), ("abc", [1, ]),
154+
])
155+
def test_assert_not_almost_equal_strings(a, b):
156+
_assert_not_almost_equal_both(a, b)
157+
158+
159+
@pytest.mark.parametrize("a,b", [
160+
([1, 2, 3], [1, 2, 3]), (np.array([1, 2, 3]), np.array([1, 2, 3])),
161+
])
162+
def test_assert_almost_equal_iterables(a, b):
163+
_assert_almost_equal_both(a, b)
164+
165+
166+
@pytest.mark.parametrize("a,b", [
167+
# Class is different.
168+
(np.array([1, 2, 3]), [1, 2, 3]),
169+
170+
# Dtype is different.
171+
(np.array([1, 2, 3]), np.array([1., 2., 3.])),
172+
173+
# Can't compare generators.
174+
(iter([1, 2, 3]), [1, 2, 3]), ([1, 2, 3], [1, 2, 4]),
175+
([1, 2, 3], [1, 2, 3, 4]), ([1, 2, 3], 1),
176+
])
177+
def test_assert_not_almost_equal_iterables(a, b):
178+
_assert_not_almost_equal(a, b)
179+
180+
181+
def test_assert_almost_equal_null():
182+
_assert_almost_equal_both(None, None)
183+
184+
185+
@pytest.mark.parametrize("a,b", [
186+
(None, np.NaN), (None, 0), (np.NaN, 0),
187+
])
188+
def test_assert_not_almost_equal_null(a, b):
189+
_assert_not_almost_equal(a, b)
190+
191+
192+
@pytest.mark.parametrize("a,b", [
193+
(np.inf, np.inf), (np.inf, float("inf")),
194+
(np.array([np.inf, np.nan, -np.inf]),
195+
np.array([np.inf, np.nan, -np.inf])),
196+
(np.array([np.inf, None, -np.inf], dtype=np.object_),
197+
np.array([np.inf, np.nan, -np.inf], dtype=np.object_)),
198+
])
199+
def test_assert_almost_equal_inf(a, b):
200+
_assert_almost_equal_both(a, b)
201+
202+
203+
def test_assert_not_almost_equal_inf():
204+
_assert_not_almost_equal_both(np.inf, 0)
205+
206+
207+
@pytest.mark.parametrize("a,b", [
208+
(Index([1., 1.1]), Index([1., 1.100001])),
209+
(Series([1., 1.1]), Series([1., 1.100001])),
210+
(np.array([1.1, 2.000001]), np.array([1.1, 2.0])),
211+
(DataFrame({"a": [1., 1.1]}), DataFrame({"a": [1., 1.100001]}))
212+
])
213+
def test_assert_almost_equal_pandas(a, b):
214+
_assert_almost_equal_both(a, b)
215+
216+
217+
def test_assert_almost_equal_object():
218+
a = [Timestamp("2011-01-01"), Timestamp("2011-01-01")]
219+
b = [Timestamp("2011-01-01"), Timestamp("2011-01-01")]
220+
_assert_almost_equal_both(a, b)
221+
222+
223+
def test_assert_almost_equal_value_mismatch():
224+
msg = "expected 2\\.00000 but got 1\\.00000, with decimal 5"
225+
226+
with pytest.raises(AssertionError, match=msg):
227+
assert_almost_equal(1, 2)
228+
229+
230+
@pytest.mark.parametrize("a,b,klass1,klass2", [
231+
(np.array([1]), 1, "ndarray", "int"),
232+
(1, np.array([1]), "int", "ndarray"),
233+
])
234+
def test_assert_almost_equal_class_mismatch(a, b, klass1, klass2):
235+
msg = """numpy array are different
236+
237+
numpy array classes are different
238+
\\[left\\]: {klass1}
239+
\\[right\\]: {klass2}""".format(klass1=klass1, klass2=klass2)
240+
241+
with pytest.raises(AssertionError, match=msg):
242+
assert_almost_equal(a, b)
243+
244+
245+
def test_assert_almost_equal_value_mismatch1():
246+
msg = """numpy array are different
247+
248+
numpy array values are different \\(66\\.66667 %\\)
249+
\\[left\\]: \\[nan, 2\\.0, 3\\.0\\]
250+
\\[right\\]: \\[1\\.0, nan, 3\\.0\\]"""
251+
252+
with pytest.raises(AssertionError, match=msg):
253+
assert_almost_equal(np.array([np.nan, 2, 3]),
254+
np.array([1, np.nan, 3]))
255+
256+
257+
def test_assert_almost_equal_value_mismatch2():
258+
msg = """numpy array are different
259+
260+
numpy array values are different \\(50\\.0 %\\)
261+
\\[left\\]: \\[1, 2\\]
262+
\\[right\\]: \\[1, 3\\]"""
263+
264+
with pytest.raises(AssertionError, match=msg):
265+
assert_almost_equal(np.array([1, 2]), np.array([1, 3]))
266+
267+
268+
def test_assert_almost_equal_value_mismatch3():
269+
msg = """numpy array are different
270+
271+
numpy array values are different \\(16\\.66667 %\\)
272+
\\[left\\]: \\[\\[1, 2\\], \\[3, 4\\], \\[5, 6\\]\\]
273+
\\[right\\]: \\[\\[1, 3\\], \\[3, 4\\], \\[5, 6\\]\\]"""
274+
275+
with pytest.raises(AssertionError, match=msg):
276+
assert_almost_equal(np.array([[1, 2], [3, 4], [5, 6]]),
277+
np.array([[1, 3], [3, 4], [5, 6]]))
278+
279+
280+
def test_assert_almost_equal_value_mismatch4():
281+
msg = """numpy array are different
282+
283+
numpy array values are different \\(25\\.0 %\\)
284+
\\[left\\]: \\[\\[1, 2\\], \\[3, 4\\]\\]
285+
\\[right\\]: \\[\\[1, 3\\], \\[3, 4\\]\\]"""
286+
287+
with pytest.raises(AssertionError, match=msg):
288+
assert_almost_equal(np.array([[1, 2], [3, 4]]),
289+
np.array([[1, 3], [3, 4]]))
290+
291+
292+
def test_assert_almost_equal_shape_mismatch_override():
293+
msg = """Index are different
294+
295+
Index shapes are different
296+
\\[left\\]: \\(2L*,\\)
297+
\\[right\\]: \\(3L*,\\)"""
298+
with pytest.raises(AssertionError, match=msg):
299+
assert_almost_equal(np.array([1, 2]),
300+
np.array([3, 4, 5]),
301+
obj="Index")
302+
303+
304+
def test_assert_almost_equal_unicode():
305+
# see gh-20503
306+
msg = """numpy array are different
307+
308+
numpy array values are different \\(33\\.33333 %\\)
309+
\\[left\\]: \\[á, à, ä\\]
310+
\\[right\\]: \\[á, à, å\\]"""
311+
312+
with pytest.raises(AssertionError, match=msg):
313+
assert_almost_equal(np.array([u"á", u"à", u"ä"]),
314+
np.array([u"á", u"à", u"å"]))
315+
316+
317+
def test_assert_almost_equal_timestamp():
318+
a = np.array([Timestamp("2011-01-01"), Timestamp("2011-01-01")])
319+
b = np.array([Timestamp("2011-01-01"), Timestamp("2011-01-02")])
320+
321+
msg = """numpy array are different
322+
323+
numpy array values are different \\(50\\.0 %\\)
324+
\\[left\\]: \\[2011-01-01 00:00:00, 2011-01-01 00:00:00\\]
325+
\\[right\\]: \\[2011-01-01 00:00:00, 2011-01-02 00:00:00\\]"""
326+
327+
with pytest.raises(AssertionError, match=msg):
328+
assert_almost_equal(a, b)
329+
330+
331+
def test_assert_almost_equal_iterable_length_mismatch():
332+
msg = """Iterable are different
333+
334+
Iterable length are different
335+
\\[left\\]: 2
336+
\\[right\\]: 3"""
337+
338+
with pytest.raises(AssertionError, match=msg):
339+
assert_almost_equal([1, 2], [3, 4, 5])
340+
341+
342+
def test_assert_almost_equal_iterable_values_mismatch():
343+
msg = """Iterable are different
344+
345+
Iterable values are different \\(50\\.0 %\\)
346+
\\[left\\]: \\[1, 2\\]
347+
\\[right\\]: \\[1, 3\\]"""
348+
349+
with pytest.raises(AssertionError, match=msg):
350+
assert_almost_equal([1, 2], [1, 3])

0 commit comments

Comments
 (0)