Skip to content

Commit 6a8220c

Browse files
authored
Merge pull request #4399 from hugovk/PillowTestCase-to-pytest
Convert most PillowTestCase methods to pytest
2 parents 28a4982 + 38bf862 commit 6a8220c

86 files changed

Lines changed: 864 additions & 794 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Tests/helper.py

Lines changed: 101 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import unittest
1111
from io import BytesIO
1212

13+
import pytest
1314
from PIL import Image, ImageMath
1415

1516
logger = logging.getLogger(__name__)
@@ -64,148 +65,118 @@ def convert_to_comparable(a, b):
6465
return new_a, new_b
6566

6667

67-
class PillowTestCase(unittest.TestCase):
68-
def delete_tempfile(self, path):
69-
try:
70-
os.remove(path)
71-
except OSError:
72-
pass # report?
73-
74-
def assert_deep_equal(self, a, b, msg=None):
75-
try:
76-
self.assertEqual(
77-
len(a),
78-
len(b),
79-
msg or "got length {}, expected {}".format(len(a), len(b)),
80-
)
81-
self.assertTrue(
82-
all(x == y for x, y in zip(a, b)),
83-
msg or "got {}, expected {}".format(a, b),
84-
)
85-
except Exception:
86-
self.assertEqual(a, b, msg)
87-
88-
def assert_image(self, im, mode, size, msg=None):
89-
if mode is not None:
90-
self.assertEqual(
91-
im.mode,
92-
mode,
93-
msg or "got mode {!r}, expected {!r}".format(im.mode, mode),
94-
)
95-
96-
if size is not None:
97-
self.assertEqual(
98-
im.size,
99-
size,
100-
msg or "got size {!r}, expected {!r}".format(im.size, size),
101-
)
102-
103-
def assert_image_equal(self, a, b, msg=None):
104-
self.assertEqual(
105-
a.mode, b.mode, msg or "got mode {!r}, expected {!r}".format(a.mode, b.mode)
106-
)
107-
self.assertEqual(
108-
a.size, b.size, msg or "got size {!r}, expected {!r}".format(a.size, b.size)
68+
def assert_deep_equal(a, b, msg=None):
69+
try:
70+
assert len(a) == len(b), msg or "got length {}, expected {}".format(
71+
len(a), len(b)
10972
)
110-
if a.tobytes() != b.tobytes():
111-
if HAS_UPLOADER:
112-
try:
113-
url = test_image_results.upload(a, b)
114-
logger.error("Url for test images: %s" % url)
115-
except Exception:
116-
pass
117-
118-
self.fail(msg or "got different content")
119-
120-
def assert_image_equal_tofile(self, a, filename, msg=None, mode=None):
121-
with Image.open(filename) as img:
122-
if mode:
123-
img = img.convert(mode)
124-
self.assert_image_equal(a, img, msg)
125-
126-
def assert_image_similar(self, a, b, epsilon, msg=None):
127-
self.assertEqual(
128-
a.mode, b.mode, msg or "got mode {!r}, expected {!r}".format(a.mode, b.mode)
73+
except Exception:
74+
assert a == b, msg
75+
76+
77+
def assert_image(im, mode, size, msg=None):
78+
if mode is not None:
79+
assert im.mode == mode, msg or "got mode {!r}, expected {!r}".format(
80+
im.mode, mode
12981
)
130-
self.assertEqual(
131-
a.size, b.size, msg or "got size {!r}, expected {!r}".format(a.size, b.size)
82+
83+
if size is not None:
84+
assert im.size == size, msg or "got size {!r}, expected {!r}".format(
85+
im.size, size
13286
)
13387

134-
a, b = convert_to_comparable(a, b)
13588

136-
diff = 0
137-
for ach, bch in zip(a.split(), b.split()):
138-
chdiff = ImageMath.eval("abs(a - b)", a=ach, b=bch).convert("L")
139-
diff += sum(i * num for i, num in enumerate(chdiff.histogram()))
89+
def assert_image_equal(a, b, msg=None):
90+
assert a.mode == b.mode, msg or "got mode {!r}, expected {!r}".format(
91+
a.mode, b.mode
92+
)
93+
assert a.size == b.size, msg or "got size {!r}, expected {!r}".format(
94+
a.size, b.size
95+
)
96+
if a.tobytes() != b.tobytes():
97+
if HAS_UPLOADER:
98+
try:
99+
url = test_image_results.upload(a, b)
100+
logger.error("Url for test images: %s" % url)
101+
except Exception:
102+
pass
103+
104+
assert False, msg or "got different content"
105+
106+
107+
def assert_image_equal_tofile(a, filename, msg=None, mode=None):
108+
with Image.open(filename) as img:
109+
if mode:
110+
img = img.convert(mode)
111+
assert_image_equal(a, img, msg)
140112

141-
ave_diff = diff / (a.size[0] * a.size[1])
142-
try:
143-
self.assertGreaterEqual(
144-
epsilon,
145-
ave_diff,
146-
(msg or "")
147-
+ " average pixel value difference %.4f > epsilon %.4f"
148-
% (ave_diff, epsilon),
149-
)
150-
except Exception as e:
151-
if HAS_UPLOADER:
152-
try:
153-
url = test_image_results.upload(a, b)
154-
logger.error("Url for test images: %s" % url)
155-
except Exception:
156-
pass
157-
raise e
158-
159-
def assert_image_similar_tofile(self, a, filename, epsilon, msg=None, mode=None):
160-
with Image.open(filename) as img:
161-
if mode:
162-
img = img.convert(mode)
163-
self.assert_image_similar(a, img, epsilon, msg)
164-
165-
def assert_warning(self, warn_class, func, *args, **kwargs):
166-
import warnings
167-
168-
with warnings.catch_warnings(record=True) as w:
169-
# Cause all warnings to always be triggered.
170-
warnings.simplefilter("always")
171-
172-
# Hopefully trigger a warning.
173-
result = func(*args, **kwargs)
174-
175-
# Verify some things.
176-
if warn_class is None:
177-
self.assertEqual(
178-
len(w), 0, "Expected no warnings, got %s" % [v.category for v in w]
179-
)
180-
else:
181-
self.assertGreaterEqual(len(w), 1)
182-
found = False
183-
for v in w:
184-
if issubclass(v.category, warn_class):
185-
found = True
186-
break
187-
self.assertTrue(found)
188-
return result
189113

190-
def assert_all_same(self, items, msg=None):
191-
self.assertEqual(items.count(items[0]), len(items), msg)
114+
def assert_image_similar(a, b, epsilon, msg=None):
115+
assert a.mode == b.mode, msg or "got mode {!r}, expected {!r}".format(
116+
a.mode, b.mode
117+
)
118+
assert a.size == b.size, msg or "got size {!r}, expected {!r}".format(
119+
a.size, b.size
120+
)
121+
122+
a, b = convert_to_comparable(a, b)
123+
124+
diff = 0
125+
for ach, bch in zip(a.split(), b.split()):
126+
chdiff = ImageMath.eval("abs(a - b)", a=ach, b=bch).convert("L")
127+
diff += sum(i * num for i, num in enumerate(chdiff.histogram()))
128+
129+
ave_diff = diff / (a.size[0] * a.size[1])
130+
try:
131+
assert epsilon >= ave_diff, (
132+
msg or ""
133+
) + " average pixel value difference %.4f > epsilon %.4f" % (ave_diff, epsilon)
134+
except Exception as e:
135+
if HAS_UPLOADER:
136+
try:
137+
url = test_image_results.upload(a, b)
138+
logger.error("Url for test images: %s" % url)
139+
except Exception:
140+
pass
141+
raise e
142+
143+
144+
def assert_image_similar_tofile(a, filename, epsilon, msg=None, mode=None):
145+
with Image.open(filename) as img:
146+
if mode:
147+
img = img.convert(mode)
148+
assert_image_similar(a, img, epsilon, msg)
149+
150+
151+
def assert_all_same(items, msg=None):
152+
assert items.count(items[0]) == len(items), msg
192153

193-
def assert_not_all_same(self, items, msg=None):
194-
self.assertNotEqual(items.count(items[0]), len(items), msg)
195154

196-
def assert_tuple_approx_equal(self, actuals, targets, threshold, msg):
197-
"""Tests if actuals has values within threshold from targets"""
155+
def assert_not_all_same(items, msg=None):
156+
assert items.count(items[0]) != len(items), msg
198157

199-
value = True
200-
for i, target in enumerate(targets):
201-
value *= target - threshold <= actuals[i] <= target + threshold
202158

203-
self.assertTrue(value, msg + ": " + repr(actuals) + " != " + repr(targets))
159+
def assert_tuple_approx_equal(actuals, targets, threshold, msg):
160+
"""Tests if actuals has values within threshold from targets"""
161+
value = True
162+
for i, target in enumerate(targets):
163+
value *= target - threshold <= actuals[i] <= target + threshold
204164

205-
def skipKnownBadTest(self, msg=None):
206-
# Skip if PILLOW_RUN_KNOWN_BAD is not true in the environment.
207-
if not os.environ.get("PILLOW_RUN_KNOWN_BAD", False):
208-
self.skipTest(msg or "Known Bad Test")
165+
assert value, msg + ": " + repr(actuals) + " != " + repr(targets)
166+
167+
168+
def skip_known_bad_test(msg=None):
169+
# Skip if PILLOW_RUN_KNOWN_BAD is not true in the environment.
170+
if not os.environ.get("PILLOW_RUN_KNOWN_BAD", False):
171+
pytest.skip(msg or "Known bad test")
172+
173+
174+
class PillowTestCase(unittest.TestCase):
175+
def delete_tempfile(self, path):
176+
try:
177+
os.remove(path)
178+
except OSError:
179+
pass # report?
209180

210181
def tempfile(self, template):
211182
assert template[:5] in ("temp.", "temp_")

Tests/test_bmp_reference.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import os
22

3+
import pytest
34
from PIL import Image
45

5-
from .helper import PillowTestCase
6+
from .helper import PillowTestCase, assert_image_similar
67

78
base = os.path.join("Tests", "images", "bmp")
89

@@ -28,7 +29,7 @@ def open(f):
2829
pass
2930

3031
# Assert that there is no unclosed file warning
31-
self.assert_warning(None, open, f)
32+
pytest.warns(None, open, f)
3233

3334
def test_questionable(self):
3435
""" These shouldn't crash/dos, but it's not well defined that these
@@ -97,7 +98,7 @@ def get_compare(f):
9798
# be differently ordered for an equivalent image.
9899
im = im.convert("RGBA")
99100
compare = im.convert("RGBA")
100-
self.assert_image_similar(im, compare, 5)
101+
assert_image_similar(im, compare, 5)
101102

102103
except Exception as msg:
103104
# there are three here that are unsupported:

Tests/test_color_lut.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from PIL import Image, ImageFilter
55

6-
from .helper import PillowTestCase
6+
from .helper import PillowTestCase, assert_image_equal
77

88
try:
99
import numpy
@@ -147,7 +147,7 @@ def test_identities(self):
147147

148148
# Fast test with small cubes
149149
for size in [2, 3, 5, 7, 11, 16, 17]:
150-
self.assert_image_equal(
150+
assert_image_equal(
151151
im,
152152
im._new(
153153
im.im.color_lut_3d(
@@ -157,7 +157,7 @@ def test_identities(self):
157157
)
158158

159159
# Not so fast
160-
self.assert_image_equal(
160+
assert_image_equal(
161161
im,
162162
im._new(
163163
im.im.color_lut_3d(
@@ -173,7 +173,7 @@ def test_identities_4_channels(self):
173173
)
174174

175175
# Red channel copied to alpha
176-
self.assert_image_equal(
176+
assert_image_equal(
177177
Image.merge("RGBA", (im.split() * 2)[:4]),
178178
im._new(
179179
im.im.color_lut_3d(
@@ -194,7 +194,7 @@ def test_copy_alpha_channel(self):
194194
],
195195
)
196196

197-
self.assert_image_equal(
197+
assert_image_equal(
198198
im,
199199
im._new(
200200
im.im.color_lut_3d(
@@ -211,7 +211,7 @@ def test_channels_order(self):
211211

212212
# Reverse channels by splitting and using table
213213
# fmt: off
214-
self.assert_image_equal(
214+
assert_image_equal(
215215
Image.merge('RGB', im.split()[::-1]),
216216
im._new(im.im.color_lut_3d('RGB', Image.LINEAR,
217217
3, 2, 2, 2, [
@@ -368,15 +368,15 @@ def test_numpy_formats(self):
368368

369369
lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b))
370370
lut.table = numpy.array(lut.table, dtype=numpy.float16)
371-
self.assert_image_equal(im, im.filter(lut))
371+
assert_image_equal(im, im.filter(lut))
372372

373373
lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b))
374374
lut.table = numpy.array(lut.table, dtype=numpy.float32)
375-
self.assert_image_equal(im, im.filter(lut))
375+
assert_image_equal(im, im.filter(lut))
376376

377377
lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b))
378378
lut.table = numpy.array(lut.table, dtype=numpy.float64)
379-
self.assert_image_equal(im, im.filter(lut))
379+
assert_image_equal(im, im.filter(lut))
380380

381381
lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b))
382382
lut.table = numpy.array(lut.table, dtype=numpy.int32)

Tests/test_core_resources.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import sys
22
import unittest
33

4+
import pytest
45
from PIL import Image
56

67
from .helper import PillowTestCase, is_pypy
@@ -169,12 +170,12 @@ def test_units(self):
169170
self.assertEqual(Image.core.get_block_size(), 2 * 1024 * 1024)
170171

171172
def test_warnings(self):
172-
self.assert_warning(
173+
pytest.warns(
173174
UserWarning, Image._apply_env_variables, {"PILLOW_ALIGNMENT": "15"}
174175
)
175-
self.assert_warning(
176+
pytest.warns(
176177
UserWarning, Image._apply_env_variables, {"PILLOW_BLOCK_SIZE": "1024"}
177178
)
178-
self.assert_warning(
179+
pytest.warns(
179180
UserWarning, Image._apply_env_variables, {"PILLOW_BLOCKS_MAX": "wat"}
180181
)

0 commit comments

Comments
 (0)