44Developer's tips for testing
55============================
66
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
1419
1520Requirements
1621------------
1722
1823The following software is required to run the tests:
1924
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)
2629
2730Optionally you can install:
2831
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+
3235
3336Building matplotlib for image comparison tests
3437----------------------------------------------
@@ -53,58 +56,72 @@ value.
5356Running the tests
5457-----------------
5558
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::
5764
5865 python tests.py
5966
6067in the root directory of the distribution. The script takes a set of
6168commands, such as:
6269
6370======================== ===========
64- ``--pep8 `` pep8 checks
65- ``--no-pep8 `` Do not perform pep8 checks
71+ ``--pep8 `` Perform pep8 checks (requires pytest-pep8 _)
6672``--no-network `` Disable tests that require network access
6773======================== ===========
6874
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:
7277
7378============================= ===========
7479``--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
7885============================= ===========
7986
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)::
8390
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
8597
8698If you want to run the full test suite, but want to save wall time try
8799running the tests in parallel::
88100
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::
90105
106+ PYTHONHASHSEED=0 python tests.py --capture=no --verbose -n 5
91107
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 `::
95111
96112 import matplotlib
97113 matplotlib.test()
98114
99115.. hint ::
100116
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::
102118
103- pip install nose
119+ pip install pytest
104120 pip install mock
105121
106122
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
108125
109126
110127Writing a simple test
@@ -113,30 +130,20 @@ Writing a simple test
113130Many elements of Matplotlib can be tested using standard tests. For
114131example, here is a test from :mod: `matplotlib.tests.test_basic `::
115132
116- from nose.tools import assert_equal
117-
118133 def test_simple():
119134 """
120135 very simple example test
121136 """
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
130138
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" ``.
132142
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 `.
140147
141148
142149Writing an image comparison test
@@ -203,24 +210,22 @@ decorator:
203210Known failing tests
204211-------------------
205212
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::
211217
212- from nose.tools import assert_equal
213- from matplotlib.testing.decorators import knownfailureif
218+ import pytest
214219
215- @knownfailureif(True)
220+ @pytest.mark.xfail
216221 def test_simple_fail():
217222 '''very simple example test that should fail'''
218- assert_equal(1+1,3)
223+ assert 1 + 1 == 3
219224
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 .
224229
225230Creating a new module in matplotlib.tests
226231-----------------------------------------
@@ -229,11 +234,6 @@ We try to keep the tests categorized by the primary module they are
229234testing. For example, the tests related to the ``mathtext.py `` module
230235are in ``test_mathtext.py ``.
231236
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-
237237Using Travis CI
238238---------------
239239
0 commit comments