8000 Pytest compatible `knownfailif` and `image_comparison` decorators · Kojoley/matplotlib@e5ea9ee · GitHub
[go: up one dir, main page]

Skip to content

Commit e5ea9ee

Browse files
committed
Pytest compatible knownfailif and image_comparison decorators
1 parent 903d118 commit e5ea9ee

File tree

3 files changed

+63
-10
lines changed

3 files changed

+63
-10
lines changed

conftest.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from __future__ import (absolute_import, division, print_function,
2+
unicode_literals)
3+
4+
import inspect
5+
import pytest
6+
7+
import matplotlib
8+
matplotlib.use('agg')
9+
10+
from matplotlib.testing.decorators import ImageComparisonTest
11+
12+
13+
def pytest_configure(config):
14+
matplotlib._called_from_pytest = True
15+
16+
17+
def pytest_unconfigure(config):
18+
matplotlib._called_from_pytest = False
19+
20+
21+
def pytest_pycollect_makeitem(collector, name, obj):
22+
if inspect.isclass(obj):
23+
if issubclass(obj, ImageComparisonTest):
24+
# Workaround `image_compare` decorator as it returns class
25+
# instead of function and this confuses pytest because it crawls
26+
# original names and sees 'test_*', but not 'Test*' in that case
27+
return pytest.Class(name, parent=collector)

lib/matplotlib/testing/__init__.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import warnings
66
from contextlib import contextmanager
77

8+
import matplotlib
89
from matplotlib.cbook import is_string_like, iterable
910
from matplotlib import rcParams, rcdefaults, use
1011

@@ -14,16 +15,31 @@ def _is_list_like(obj):
1415
return not is_string_like(obj) and iterable(obj)
1516

1617

18+
def is_called_from_pytest():
19+
"""Returns whether the call was done from pytest"""
20+
return getattr(matplotlib, '_called_from_pytest', False)
21+
22+
1723
def xfail(msg=""):
1824
"""Explicitly fail an currently-executing test with the given message."""
19-
from .nose import knownfail
20-
knownfail(msg)
25+
__tracebackhide__ = True
26+
if is_called_from_pytest():
27+
import pytest
28+
pytest.xfail(msg)
29+
else:
30+
from .nose import knownfail
31+
knownfail(msg)
2132

2233

2334
def skip(msg=""):
2435
"""Skip an executing test with the given message."""
25-
from nose import SkipTest
26-
raise SkipTest(msg)
36+
__tracebackhide__ = True
37+
if is_called_from_pytest():
38+
import pytest
39+
pytest.skip(msg)
40+
else:
41+
from nose import SkipTest
42+
raise SkipTest(msg)
2743

2844

2945
# stolen from pytest

lib/matplotlib/testing/decorators.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from matplotlib import rcParams
2828
from matplotlib.testing.compare import comparable_formats, compare_images, \
2929
make_test_filename
30-
from . import copy_metadata, skip, xfail
30+
from . import copy_metadata, is_called_from_pytest, skip, xfail
3131
from .exceptions import ImageComparisonFailure
3232

3333

@@ -37,8 +37,12 @@ def skipif(condition, *args, **kwargs):
3737
3838
Optionally specify a reason for better reporting.
3939
"""
40-
from .nose.decorators import skipif
41-
return skipif(condition, *args, **kwargs)
40+
if is_called_from_pytest():
41+
import pytest
42+
return pytest.mark.skipif(condition, *args, **kwargs)
43+
else:
44+
from .nose.decorators import skipif
45+
return skipif(condition, *args, **kwargs)
4246

4347

4448
def knownfailureif(fail_condition, msg=None, known_exception_class=None):
@@ -53,8 +57,14 @@ def knownfailureif(fail_condition, msg=None, known_exception_class=None):
5357
if the exception is an instance of this class. (Default = None)
5458
5559
"""
56-
from .nose.decorators import knownfailureif
57-
return knownfailureif(fail_condition, msg, known_exception_class)
60+
if is_called_from_pytest():
61+
import pytest
62+
strict = fail_condition and fail_condition != 'indeterminate'
63+
return pytest.mark.xfail(condition=fail_condition, reason=msg,
64+
raises=known_exception_class, strict=strict)
65+
else:
66+
from .nose.decorators import knownfailureif
67+
return knownfailureif(fail_condition, msg, known_exception_class)
5868

5969

6070
def _do_cleanup(original_units_registry, original_settings):
@@ -198,7 +208,7 @@ def remove_text(figure):
198208
def test(self):
199209
baseline_dir, result_dir = _image_directories(self._func)
200210
if self._style != 'classic':
201-
xfail('temporarily disabled until 2.0 tag')
211+
skip('temporarily disabled until 2.0 tag')
202212
for fignum, baseline in zip(plt.get_fignums(), self._baseline_images):
203213
for extension in self._extensions:
204214
will_fail = not extension in comparable_formats()

0 commit comments

Comments
 (0)
0