Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit84f471e

Browse files
authored
Merge pull request#6730 from Kojoley/improve-tests
TST: Add Py.test testing framework support
2 parents36f1353 +a66d599 commit84f471e

File tree

8 files changed

+207
-25
lines changed

8 files changed

+207
-25
lines changed

‎.travis.yml

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,13 @@ env:
4545
-NPROC=2
4646
-TEST_ARGS=--no-pep8
4747
-NOSE_ARGS="--processes=$NPROC --process-timeout=300"
48+
-PYTEST_ARGS="-ra --timeout=300 --durations=25 --cov-report= --cov=lib"# -n $NPROC
4849
-PYTHON_ARGS=
4950
-DELETE_FONT_CACHE=
51+
-USE_PYTEST=false
52+
#- PYTHONHASHSEED=0 # Workaround for pytest-xdist flaky colletion order
53+
# # https://github.com/pytest-dev/pytest/issues/920
54+
# # https://github.com/pytest-dev/pytest/issues/1075
5055

5156
matrix:
5257
include:
@@ -60,6 +65,8 @@ matrix:
6065
env:TEST_ARGS=--pep8
6166
-python:3.5
6267
env:BUILD_DOCS=true
68+
-python:3.5
69+
env:USE_PYTEST=true PANDAS=pandas DELETE_FONT_CACHE=1 TEST_ARGS=
6370
-python:"nightly"
6471
env:PRE=--pre
6572
-os:osx
@@ -107,10 +114,14 @@ install:
107114
# Install dependencies from pypi
108115
pip install $PRE python-dateutil $NUMPY pyparsing!=2.1.6 $PANDAS pep8 cycler coveralls coverage
109116
pip install $PRE pillow sphinx!=1.3.0 $MOCK numpydoc ipython colorspacious
117+
110118
# Install nose from a build which has partial
111119
# support for python36 and suport for coverage output suppressing
112120
pip install git+https://github.com/jenshnielsen/nose.git@matplotlibnose
113121
122+
# pytest-cov>=2.3.1 due to https://github.com/pytest-dev/pytest-cov/issues/124
123+
pip install $PRE pytest 'pytest-cov>=2.3.1' pytest-timeout pytest-xdist pytest-faulthandler
124+
114125
# We manually install humor sans using the package from Ubuntu 14.10. Unfortunatly humor sans is not
115126
# availible in the Ubuntu version used by Travis but we can manually install the deb from a later
116127
# version since is it basically just a .ttf file
@@ -147,16 +158,21 @@ script:
147158
-|
148159
echo Testing import of tkagg backend
149160
MPLBACKEND="tkagg" python -c 'import matplotlib.pyplot as plt; print(plt.get_backend())'
150-
echo The following args are passed to nose $NOSE_ARGS
151161
if [[ $BUILD_DOCS == false ]]; then
152162
if [[ $DELETE_FONT_CACHE == 1 ]]; then
153163
rm -rf ~/.cache/matplotlib
154164
fi
155165
export MPL_REPO_DIR=$PWD # needed for pep8-conformance test of the examples
156-
if [[ $TRAVIS_OS_NAME == 'osx' ]]; then
157-
python tests.py $NOSE_ARGS $TEST_ARGS
166+
if [[ $USE_PYTEST == false ]]; then
167+
echo The following args are passed to nose $NOSE_ARGS
168+
if [[ $TRAVIS_OS_NAME == 'osx' ]]; then
169+
python tests.py $NOSE_ARGS $TEST_ARGS
170+
else
171+
gdb -return-child-result -batch -ex r -ex bt --args python $PYTHON_ARGS tests.py $NOSE_ARGS $TEST_ARGS
172+
fi
158173
else
159-
gdb -return-child-result -batch -ex r -ex bt --args python $PYTHON_ARGS tests.py $NOSE_ARGS $TEST_ARGS
174+
echo The following args are passed to pytest $PYTEST_ARGS
175+
py.test $PYTEST_ARGS $TEST_ARGS
160176
fi
161177
else
162178
cd doc
@@ -171,6 +187,9 @@ script:
171187
pip install $PRE requests==2.9.2 linkchecker
172188
linkchecker build/html/index.html
173189
fi
190+
# Currently disabled because of differece in behaviour
191+
# between `pytest-cov` and `nose-coverage`
192+
#- if [[ $USE_PYTEST == true ]]; then coveralls; fi
174193
-rm -rf $HOME/.cache/matplotlib/tex.cache
175194
-rm -rf $HOME/.cache/matplotlib/test_cache
176195

‎appveyor.yml

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ environment:
1414
CMD_IN_ENV:"cmd /E:ON /V:ON /C obvci_appveyor_python_build_env.cmd"
1515
# Workaround for https://github.com/conda/conda-build/issues/636
1616
PYTHONIOENCODING:"UTF-8"
17+
TEST_ARGS:--no-pep8
18+
PYTEST_ARGS:-ra --timeout=300 --durations=25#--cov-report= --cov=lib #-n %NUMBER_OF_PROCESSORS%
19+
USE_PYTEST:no
20+
#PYTHONHASHSEED: 0 # Workaround for pytest-xdist flaky colletion order
21+
# # https://github.com/pytest-dev/pytest/issues/920
22+
# # https://github.com/pytest-dev/pytest/issues/1075
1723

1824
matrix:
1925
# for testing purpose: numpy 1.8 on py2.7, for the rest use 1.10/latest
@@ -38,6 +44,13 @@ environment:
3844
PYTHON_VERSION:"3.5"
3945
TEST_ALL:"no"
4046
CONDA_INSTALL_LOCN:"C:\\Miniconda35-x64"
47+
-TARGET_ARCH:"x64"
48+
CONDA_PY:"35"
49+
CONDA_NPY:"110"
50+
PYTHON_VERSION:"3.5"
51+
TEST_ALL:"no"
52+
CONDA_INSTALL_LOCN:"C:\\Miniconda35-x64"
53+
USE_PYTEST:yes
4154
-TARGET_ARCH:"x86"
4255
CONDA_PY:"27"
4356
CONDA_NPY:"18"
@@ -58,7 +71,7 @@ platform:
5871
build:false
5972

6073
init:
61-
-cmd:"ECHO %PYTHON_VERSION% %CONDA_INSTALL_LOCN%"
74+
-cmd:"ECHO %PYTHON_VERSION%PYTEST=%USE_PYTEST%%CONDA_INSTALL_LOCN%"
6275

6376
install:
6477
-cmd:set PATH=%CONDA_INSTALL_LOCN%;%CONDA_INSTALL_LOCN%\scripts;%PATH%;
@@ -82,10 +95,15 @@ install:
8295
# same things as the requirements in ci/conda_recipe/meta.yaml
8396
# if conda-forge gets a new pyqt, it might be nice to install it as well to have more backends
8497
# https://github.com/conda-forge/conda-forge.github.io/issues/157#issuecomment-223536381
85-
-cmd:conda create -q -n test-environment python=%PYTHON_VERSION% pip setuptools numpy python-dateutil freetype=2.6 msinttypes "tk=8.5" pyparsing pytz tornado "libpng>=1.6.21,<1.7" "zlib=1.2" "cycler>=0.10" nose mock
98+
-conda create -q -n test-environment python=%PYTHON_VERSION%
99+
pip setuptools numpy python-dateutil freetype=2.6 msinttypes "tk=8.5"
100+
pyparsing pytz tornado "libpng>=1.6.21,<1.7" "zlib=1.2" "cycler>=0.10"
101+
nose mock sphinx
86102
-activate test-environment
87103
-cmd:echo %PYTHON_VERSION% %TARGET_ARCH%
88104
-cmd:IF %PYTHON_VERSION% == 2.7 conda install -q functools32
105+
# pytest-cov>=2.3.1 due to https://github.com/pytest-dev/pytest-cov/issues/124
106+
-if x%USE_PYTEST% == xyes conda install -q pytest "pytest-cov>=2.3.1" pytest-timeout#pytest-xdist
89107

90108
# Let the install prefer the static builds of the libs
91109
-set LIBRARY_LIB=%CONDA_PREFIX%\Library\lib
@@ -124,7 +142,9 @@ test_script:
124142
# Test import of tkagg backend
125143
-python -c "import matplotlib as m; m.use('tkagg'); import matplotlib.pyplot as plt; print(plt.get_backend())"
126144
# tests
127-
-python tests.py
145+
-if x%USE_PYTEST% == xyes echo The following args are passed to pytest %PYTEST_ARGS%
146+
-if x%USE_PYTEST% == xyes py.test %PYTEST_ARGS% %TEST_ARGS%
147+
-if x%USE_PYTEST% == xno python tests.py %TEST_ARGS%
128148
# Generate a html for visual tests
129149
-python visual_tests.py
130150

‎conftest.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
from __future__import (absolute_import,division,print_function,
2+
unicode_literals)
3+
4+
importinspect
5+
importos
6+
importpytest
7+
importunittest
8+
9+
importmatplotlib
10+
matplotlib.use('agg')
11+
12+
frommatplotlibimportdefault_test_modules
13+
frommatplotlib.testing.decoratorsimportImageComparisonTest
14+
15+
16+
IGNORED_TESTS= {
17+
'matplotlib': [
18+
'test_usetex',
19+
],
20+
}
21+
22+
23+
defblacklist_check(path):
24+
"""Check if test is blacklisted and should be ignored"""
25+
head,tests_dir=os.path.split(path.dirname)
26+
iftests_dir!='tests':
27+
returnTrue
28+
head,top_module=os.path.split(head)
29+
returnpath.purebasenameinIGNORED_TESTS.get(top_module, [])
30+
31+
32+
defwhitelist_check(path):
33+
"""Check if test is not whitelisted and should be ignored"""
34+
left=path.dirname
35+
last_left=None
36+
module_path=path.purebasename
37+
whilelen(left)andleft!=last_left:
38+
last_left=left
39+
left,tail=os.path.split(left)
40+
module_path='.'.join([tail,module_path])
41+
ifmodule_pathindefault_test_modules:
42+
returnFalse
43+
returnTrue
44+
45+
46+
COLLECT_FILTERS= {
47+
'none':lambda_:False,
48+
'blacklist':blacklist_check,
49+
'whitelist':whitelist_check,
50+
}
51+
52+
53+
defis_nose_class(cls):
54+
"""Check if supplied class looks like Nose testcase"""
55+
returnany(namein ['setUp','tearDown']
56+
forname,_ininspect.getmembers(cls))
57+
58+
59+
defpytest_addoption(parser):
60+
group=parser.getgroup("matplotlib","matplotlib custom options")
61+
62+
group.addoption('--collect-filter',action='store',
63+
choices=COLLECT_FILTERS,default='blacklist',
64+
help='filter tests during collection phase')
65+
66+
group.addoption('--no-pep8',action='store_true',
67+
help='skip PEP8 compliance tests')
68+
69+
70+
defpytest_configure(config):
71+
matplotlib._called_from_pytest=True
72+
matplotlib._init_tests()
73+
74+
ifconfig.getoption('--no-pep8'):
75+
default_test_modules.remove('matplotlib.tests.test_coding_standards')
76+
IGNORED_TESTS['matplotlib']+='test_coding_standards'
77+
78+
79+
defpytest_unconfigure(config):
80+
matplotlib._called_from_pytest=False
81+
82+
83+
defpytest_ignore_collect(path,config):
84+
ifpath.ext=='.py':
85+
collect_filter=config.getoption('--collect-filter')
86+
returnCOLLECT_FILTERS[collect_filter](path)
87+
88+
89+
defpytest_pycollect_makeitem(collector,name,obj):
90+
ifinspect.isclass(obj):
91+
ifissubclass(obj,ImageComparisonTest):
92+
# Workaround `image_compare` decorator as it returns class
93+
# instead of function and this confuses pytest because it crawls
94+
# original names and sees 'test_*', but not 'Test*' in that case
95+
returnpytest.Class(name,parent=collector)
96+
97+
ifis_nose_class(obj)andnotissubclass(obj,unittest.TestCase):
98+
# Workaround unittest-like setup/teardown names in pure classes
99+
setup=getattr(obj,'setUp',None)
100+
ifsetupisnotNone:
101+
obj.setup_method=lambdaself,_:obj.setUp(self)
102+
tearDown=getattr(obj,'tearDown',None)
103+
iftearDownisnotNone:
104+
obj.teardown_method=lambdaself,_:obj.tearDown(self)
105+
setUpClass=getattr(obj,'setUpClass',None)
106+
ifsetUpClassisnotNone:
107+
obj.setup_class=obj.setUpClass
108+
tearDownClass=getattr(obj,'tearDownClass',None)
109+
iftearDownClassisnotNone:
110+
obj.teardown_class=obj.tearDownClass
111+
112+
returnpytest.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
importwarnings
66
fromcontextlibimportcontextmanager
77

8+
importmatplotlib
89
frommatplotlib.cbookimportis_string_like,iterable
910
frommatplotlibimportrcParams,rcdefaults,use
1011

@@ -14,16 +15,31 @@ def _is_list_like(obj):
1415
returnnotis_string_like(obj)anditerable(obj)
1516

1617

18+
defis_called_from_pytest():
19+
"""Returns whether the call was done from pytest"""
20+
returngetattr(matplotlib,'_called_from_pytest',False)
21+
22+
1723
defxfail(msg=""):
1824
"""Explicitly fail an currently-executing test with the given message."""
19-
from .noseimportknownfail
20-
knownfail(msg)
25+
__tracebackhide__=True
26+
ifis_called_from_pytest():
27+
importpytest
28+
pytest.xfail(msg)
29+
else:
30+
from .noseimportknownfail
31+
knownfail(msg)
2132

2233

2334
defskip(msg=""):
2435
"""Skip an executing test with the given message."""
25-
fromnoseimportSkipTest
26-
raiseSkipTest(msg)
36+
__tracebackhide__=True
37+
ifis_called_from_pytest():
38+
importpytest
39+
pytest.skip(msg)
40+
else:
41+
fromnoseimportSkipTest
42+
raiseSkipTest(msg)
2743

2844

2945
# stolen from pytest

‎lib/matplotlib/testing/decorators.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
frommatplotlibimportrcParams
2828
frommatplotlib.testing.compareimportcomparable_formats,compare_images, \
2929
make_test_filename
30-
from .importcopy_metadata,skip,xfail
30+
from .importcopy_metadata,is_called_from_pytest,skip,xfail
3131
from .exceptionsimportImageComparisonFailure
3232

3333

@@ -37,8 +37,12 @@ def skipif(condition, *args, **kwargs):
3737
3838
Optionally specify a reason for better reporting.
3939
"""
40-
from .nose.decoratorsimportskipif
41-
returnskipif(condition,*args,**kwargs)
40+
ifis_called_from_pytest():
41+
importpytest
42+
returnpytest.mark.skipif(condition,*args,**kwargs)
43+
else:
44+
from .nose.decoratorsimportskipif
45+
returnskipif(condition,*args,**kwargs)
4246

4347

4448
defknownfailureif(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.decoratorsimportknownfailureif
57-
returnknownfailureif(fail_condition,msg,known_exception_class)
60+
ifis_called_from_pytest():
61+
importpytest
62+
strict=fail_conditionandfail_condition!='indeterminate'
63+
returnpytest.mark.xfail(condition=fail_condition,reason=msg,
64+
raises=known_exception_class,strict=strict)
65+
else:
66+
from .nose.decoratorsimportknownfailureif
67+
returnknownfailureif(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
deftest(self):
199209
baseline_dir,result_dir=_image_directories(self._func)
200210
ifself._style!='classic':
201-
xfail('temporarily disabled until 2.0 tag')
211+
skip('temporarily disabled until 2.0 tag')
202212
forfignum,baselineinzip(plt.get_fignums(),self._baseline_images):
203213
forextensioninself._extensions:
204214
will_fail=notextensionincomparable_formats()
@@ -228,7 +238,7 @@ def test(self):
228238
@knownfailureif(
229239
will_fail,fail_msg,
230240
known_exception_class=ImageComparisonFailure)
231-
defdo_test():
241+
defdo_test(fignum,actual_fname,expected_fname):
232242
figure=plt.figure(fignum)
233243

234244
ifself._remove_text:
@@ -255,7 +265,7 @@ def do_test():
255265
(self._freetype_version,ft2font.__freetype_version__))
256266
raise
257267

258-
yield(do_test,)
268+
yielddo_test,fignum,actual_fname,expected_fname
259269

260270

261271
defimage_comparison(baseline_images=None,extensions=None,tol=0,

‎lib/matplotlib/tests/test_axes.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
importwarnings
2323

2424
importmatplotlib
25-
frommatplotlib.testing.decoratorsimportimage_comparison,cleanup,skipif
25+
frommatplotlib.testing.decoratorsimportimage_comparison,cleanup
26+
frommatplotlib.testingimportskip
2627
importmatplotlib.pyplotasplt
2728
importmatplotlib.markersasmmarkers
2829
importmatplotlib.patchesasmpatches
@@ -86,11 +87,11 @@ def test_formatter_ticker():
8687
ax.autoscale_view()
8788

8889

89-
@skipif(LooseVersion(np.__version__)>=LooseVersion('1.11.0'),
90-
reason="Fall out from a fixed numpy bug")
9190
@image_comparison(baseline_images=["formatter_large_small"])
9291
deftest_formatter_large_small():
9392
# github issue #617, pull #619
93+
ifLooseVersion(np.__version__)>=LooseVersion('1.11.0'):
94+
skip("Fall out from a fixed numpy bug")
9495
fig,ax=plt.subplots(1)
9596
x= [0.500000001,0.500000002]
9697
y= [1e64,1.1e64]

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp