4
4
Developer's tips for testing
5
5
============================
6
6
7
- Matplotlib has a testing infrastructure based on nose _, making it easy
8
- to write new tests. The tests are in :mod: `matplotlib.tests `, and
9
- customizations to the nose testing infrastructure are in
10
- :mod: `matplotlib.testing `. (There is other old testing cruft around,
11
- please ignore it while we consolidate our testing to these locations.)
12
-
13
- .. _nose : https://nose.readthedocs.io/en/latest/
7
+ Matplotlib has a testing infrastructure based on pytest _, making it easy to
8
+ write new tests. The tests are in :mod: `matplotlib.tests `, and customizations
9
+ to the pytest testing infrastructure are in :mod: `matplotlib.tests.conftest `
10
+ and :mod: `matplotlib.testing `. (There is other old testing cruft around, please
11
+ ignore it while we consolidate our testing to these locations.)
12
+
13
+ .. _pytest : http://doc.pytest.org/en/latest/
14
+ .. _mock : https://docs.python.org/dev/library/unittest.mock.html>
15
+ .. _Ghostscript : https://www.ghostscript.com/
16
+ .. _Inkscape : https://inkscape.org
17
+ .. _pytest-cov : https://pytest-cov.readthedocs.io/en/latest/
18
+ .. _pytest-pep8 : https://pypi.python.org/pypi/pytest-pep8
14
19
15
20
Requirements
16
21
------------
17
22
18
23
The following software is required to run the tests:
19
24
20
- - nose _, version 1.0 or later
21
- - `mock <https://docs.python.org/dev/library/unittest.mock.html >`_, when running python
22
- versions < 3.3
23
- - `Ghostscript <https://www.ghostscript.com/ >`_ (to render PDF
24
- files)
25
- - `Inkscape <https://inkscape.org >`_ (to render SVG files)
25
+ - pytest _, version 3.0.0 or later
26
+ - mock _, when running Python versions < 3.3
27
+ - Ghostscript _ (to render PDF files)
28
+ - Inkscape _ (to render SVG files)
26
29
27
30
Optionally you can install:
28
31
29
- - ` coverage < https://coverage.readthedocs.io/en/latest/ >`_ to collect coverage
30
- information
31
- - ` pep8 < http://pep8.readthedocs.io/en/latest >`_ to test coding standards
32
+ - pytest-cov _ to collect coverage information
33
+ - pytest-pep8 _ to test coding standards
34
+
32
35
33
36
Building matplotlib for image comparison tests
34
37
----------------------------------------------
@@ -53,58 +56,72 @@ value.
53
56
Running the tests
54
57
-----------------
55
58
56
- Running the tests is simple. Make sure you have nose installed and run::
59
+ Running the tests is simple. Make sure you have pytest installed and run::
60
+
61
+ py.test
62
+
63
+ or::
57
64
58
65
python tests.py
59
66
60
67
in the root directory of the distribution. The script takes a set of
61
68
commands, such as:
62
69
63
70
======================== ===========
64
- ``--pep8 `` pep8 checks
65
- ``--no-pep8 `` Do not perform pep8 checks
71
+ ``--pep8 `` Perform pep8 checks (requires pytest-pep8 _)
66
72
``--no-network `` Disable tests that require network access
67
73
======================== ===========
68
74
69
- Additional arguments are passed on to nosetests. See the nose
70
- documentation for supported arguments. Some of the more important ones are given
71
- here:
75
+ Additional arguments are passed on to pytest. See the pytest documentation for
76
+ supported arguments. Some of the more important ones are given here:
72
77
73
78
============================= ===========
74
79
``--verbose `` Be more verbose
75
- ``--processes=NUM `` Run tests in parallel over NUM processes
76
- ``--process-timeout=SECONDS `` Set timeout for results from test runner process
77
- ``--nocapture `` Do not capture stdout
80
+ ``--n NUM `` Run tests in parallel over NUM
81
+ processes (requires pytest-xdist _)
82
+ ``--timeout=SECONDS `` Set timeout for results from each test
83
+ process (requires pytest-timeout _)
84
+ ``--capture=no `` or ``-s `` Do not capture stdout
78
85
============================= ===========
79
86
80
- To run a single test from the command line, you can provide a
81
- dot-separated path to the module followed by the function separated by
82
- a colon , e.g., (this is assuming the test is installed)::
87
+ To run a single test from the command line, you can provide a dot-separated
88
+ path to the module, optionally followed by the function separated by two
89
+ colons , e.g., (this is assuming the test is installed)::
83
90
84
- python tests.py matplotlib.tests.test_simplification:test_clipping
91
+ python tests.py matplotlib.tests.test_simplification::test_clipping
92
+
93
+ or by passing a file path, optionally followed by the function separated by two
94
+ colons, e.g., (tests do not need to be installed, but Matplotlib should be)::
95
+
96
+ python tests.py lib/matplotlib/tests/test_simplification.py::test_clipping
85
97
86
98
If you want to run the full test suite, but want to save wall time try
87
99
running the tests in parallel::
88
100
89
- python tests.py --nocapture --verbose --processes=5 --process-timeout=300
101
+ python tests.py --capture=no --verbose -n 5
102
+
103
+ Depending on your version of Python and pytest-xdist, you may need to set
104
+ ``PYTHONHASHSEED `` to a fixed value when running in parallel::
90
105
106
+ PYTHONHASHSEED=0 python tests.py --capture=no --verbose -n 5
91
107
92
- An alternative implementation that does not look at command line
93
- arguments works from within Python is to run the tests from the
94
- matplotlib library function :func: `matplotlib.test `::
108
+ An alternative implementation that does not look at command line arguments
109
+ and works from within Python is to run the tests from the Matplotlib library
110
+ function :func: `matplotlib.test `::
95
111
96
112
import matplotlib
97
113
matplotlib.test()
98
114
99
115
.. hint ::
100
116
101
- To run the tests you need to install nose and mock if using python 2.7::
117
+ To run the tests you need to install pytest and mock if using python 2.7::
102
118
103
- pip install nose
119
+ pip install pytest
104
120
pip install mock
105
121
106
122
107
- .. _`nosetest arguments` : http://nose.readthedocs.io/en/latest/usage.html
123
+ .. _pytest-xdist : https://pypi.python.org/pypi/pytest-xdist
124
+ .. _pytest-timeout : https://pypi.python.org/pypi/pytest-timeout
108
125
109
126
110
127
Writing a simple test
@@ -113,30 +130,20 @@ Writing a simple test
113
130
Many elements of Matplotlib can be tested using standard tests. For
114
131
example, here is a test from :mod: `matplotlib.tests.test_basic `::
115
132
116
- from nose.tools import assert_equal
117
-
118
133
def test_simple():
119
134
"""
120
135
very simple example test
121
136
"""
122
- assert_equal(1+1,2)
123
-
124
- Nose determines which functions are tests by searching for functions
125
- beginning with "test" in their name.
126
-
127
- If the test has side effects that need to be cleaned up, such as
128
- creating figures using the pyplot interface, use the ``@cleanup ``
129
- decorator::
137
+ assert 1 + 1 == 2
130
138
131
- from matplotlib.testing.decorators import cleanup
139
+ Pytest determines which functions are tests by searching for files whose names
140
+ begin with ``"test_" `` and then within those files for functions beginning with
141
+ ``"test" `` or classes beginning with ``"Test" ``.
132
142
133
- @cleanup
134
- def test_create_figure():
135
- """
136
- very simple example test that creates a figure using pyplot.
137
- """
138
- fig = figure()
139
- ...
143
+ Tests that have side effects that need to be cleaned up, such as created
144
+ figures using the pyplot interface or modified rc params, will be automatically
145
+ reset by the pytest fixture
146
+ :func: `~matplotlib.tests.conftest.mpl_test_settings `.
140
147
141
148
142
149
Writing an image comparison test
@@ -203,24 +210,22 @@ decorator:
203
210
Known failing tests
204
211
-------------------
205
212
206
- If you're writing a test, you may mark it as a known failing test with
207
- the :func: `~matplotlib.testing.decorators.knownfailureif `
208
- decorator. This allows the test to be added to the test suite and run
209
- on the buildbots without causing undue alarm. For example, although
210
- the following test will fail, it is an expected failure::
213
+ If you're writing a test, you may mark it as a known failing test with the
214
+ :func: `pytest.mark.xfail ` decorator. This allows the test to be added to the
215
+ test suite and run on the buildbots without causing undue alarm. For example,
216
+ although the following test will fail, it is an expected failure::
211
217
212
- from nose.tools import assert_equal
213
- from matplotlib.testing.decorators import knownfailureif
218
+ import pytest
214
219
215
- @knownfailureif(True)
220
+ @pytest.mark.xfail
216
221
def test_simple_fail():
217
222
'''very simple example test that should fail'''
218
- assert_equal(1+1,3)
223
+ assert 1 + 1 == 3
219
224
220
- Note that the first argument to the
221
- :func: ` ~matplotlib.testing.decorators.knownfailureif ` decorator is a
222
- fail condition, which can be a value such as True, False, or
223
- 'indeterminate', or may be a dynamically evaluated expression .
225
+ Note that the first argument to the :func: ` ~pytest.mark.xfail ` decorator is a
226
+ fail condition, which can be a value such as True, False, or may be a
227
+ dynamically evaluated expression. If a condition is supplied, then a reason
228
+ must also be supplied with the `` reason='message' `` keyword argument .
224
229
225
230
Creating a new module in matplotlib.tests
226
231
-----------------------------------------
@@ -229,11 +234,6 @@ We try to keep the tests categorized by the primary module they are
229
234
testing. For example, the tests related to the ``mathtext.py `` module
230
235
are in ``test_mathtext.py ``.
231
236
232
- Let's say you've added a new module named ``whizbang.py `` and you want
233
- to add tests for it in ``matplotlib.tests.test_whizbang ``. To add
234
- this module to the list of default tests, append its name to
235
- ``default_test_modules `` in :file: `lib/matplotlib/__init__.py `.
236
-
237
237
Using Travis CI
238
238
---------------
239
239
0 commit comments