Skip to content

Commit 9edc946

Browse files
committed
Migrate docs from README to website
1 parent e6c1308 commit 9edc946

8 files changed

+21
-361
lines changed

README.rst

Lines changed: 0 additions & 361 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
About
2-
-----
3-
41
This is a plugin to facilitate image comparison for
52
`Matplotlib <http://www.matplotlib.org>`__ figures in pytest.
63

@@ -9,361 +6,3 @@ generated image, and the RMS of the residual is compared to a
96
user-specified tolerance. If the residual is too large, the test will
107
fail (this is implemented using helper functions from
118
``matplotlib.testing``).
12-
13-
For more information on how to write tests to do this, see the **Using**
14-
section below.
15-
16-
Installing
17-
----------
18-
19-
This plugin is compatible with Python 3.6 and later, and
20-
requires `pytest <http://pytest.org>`__ and
21-
`matplotlib <http://www.matplotlib.org>`__ to be installed.
22-
23-
To install, you can do::
24-
25-
pip install pytest-mpl
26-
27-
You can check that the plugin is registered with pytest by doing::
28-
29-
pytest --version
30-
31-
which will show a list of plugins:
32-
33-
::
34-
35-
This is pytest version 2.7.1, imported from ...
36-
setuptools registered plugins:
37-
pytest-mpl-0.1 at ...
38-
39-
Using
40-
-----
41-
42-
With Baseline Images
43-
^^^^^^^^^^^^^^^^^^^^
44-
45-
To use, you simply need to mark the function where you want to compare
46-
images using ``@pytest.mark.mpl_image_compare``, and make sure that the
47-
function returns a Matplotlib figure (or any figure object that has a
48-
``savefig`` method):
49-
50-
.. code:: python
51-
52-
import pytest
53-
import matplotlib.pyplot as plt
54-
55-
@pytest.mark.mpl_image_compare
56-
def test_succeeds():
57-
fig = plt.figure()
58-
ax = fig.add_subplot(1,1,1)
59-
ax.plot([1,2,3])
60-
return fig
61-
62-
To generate the baseline images, run the tests with the
63-
``--mpl-generate-path`` option with the name of the directory where the
64-
generated images should be placed::
65-
66-
pytest --mpl-generate-path=baseline
67-
68-
If the directory does not exist, it will be created. The directory will
69-
be interpreted as being relative to where you are running ``pytest``.
70-
Once you are happy with the generated images, you should move them to a
71-
sub-directory called ``baseline`` relative to the test files (this name
72-
is configurable, see below). You can also generate the baseline image
73-
directly in the right directory.
74-
75-
With a Hash Library
76-
^^^^^^^^^^^^^^^^^^^
77-
78-
Instead of comparing to baseline images, you can instead compare against a JSON
79-
library of SHA-256 hashes. This has the advantage of not having to check baseline
80-
images into the repository with the tests, or download them from a remote
81-
source.
82-
83-
The hash library can be generated with
84-
``--mpl-generate-hash-library=path_to_file.json``. The hash library to be used
85-
can either be specified via the ``--mpl-hash-library=`` command line argument,
86-
or via the ``hash_library=`` keyword argument to the
87-
``@pytest.mark.mpl_image_compare`` decorator.
88-
89-
When generating a hash library, the tests will also be run as usual against the
90-
existing hash library specified by ``--mpl-hash-library`` or the keyword argument.
91-
However, generating baseline images will always result in the tests being skipped.
92-
93-
Hybrid Mode: Hashes and Images
94-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
95-
96-
It is possible to configure both hashes and baseline images. In this scenario
97-
only the hash comparison can determine the test result. If the hash comparison
98-
fails, the test will fail, however a comparison to the baseline image will be
99-
carried out so the actual difference can be seen. If the hash comparison passes,
100-
the comparison to the baseline image is skipped (unless **results always** is
101-
configured).
102-
103-
This is especially useful if the baseline images are external to the repository
104-
containing the tests, and are accessed via HTTP. In this situation, if the hashes
105-
match, the baseline images won't be retrieved, saving time and bandwidth. Also, it
106-
allows the tests to be modified and the hashes updated to reflect the changes
107-
without having to modify the external images.
108-
109-
110-
Running Tests
111-
^^^^^^^^^^^^^
112-
113-
Once tests are written with baseline images, a hash library, or both to compare
114-
against, the tests can be run with::
115-
116-
pytest --mpl
117-
118-
and the tests will pass if the images are the same. If you omit the
119-
``--mpl`` option, the tests will run but will only check that the code
120-
runs, without checking the output images.
121-
122-
If pytest-mpl is not installed, the image comparison tests will cause pytest
123-
to show a warning, ``PytestReturnNotNoneWarning``. Installing pytest-mpl will
124-
solve this issue. Alternativly, the image comparison tests can be deselected
125-
by running pytest with ``-m "not mpl_image_compare"``.
126-
127-
128-
Generating a Test Summary
129-
^^^^^^^^^^^^^^^^^^^^^^^^^
130-
131-
By specifying the ``--mpl-generate-summary=html`` CLI argument, a HTML summary
132-
page will be generated showing the test result, log entry and generated result
133-
image. When in the (default) image comparison mode, the baseline image, diff
134-
image and RMS (if any), and tolerance of each test will also be shown.
135-
When in the hash comparison mode, the baseline hash and result hash will
136-
also be shown. When in hybrid mode, all of these are included.
137-
138-
When generating a HTML summary, the ``--mpl-results-always`` option is
139-
automatically applied (see section below). Therefore images for passing
140-
tests will also be shown.
141-
142-
+---------------+---------------+---------------+
143-
| |html all| | |html filter| | |html result| |
144-
+---------------+---------------+---------------+
145-
146-
As well as ``html``, ``basic-html`` can be specified for an alternative HTML
147-
summary which does not rely on JavaScript or external resources. A ``json``
148-
summary can also be saved. Multiple options can be specified comma-separated.
149-
150-
Options
151-
-------
152-
153-
Tolerance
154-
^^^^^^^^^
155-
156-
The RMS tolerance for the image comparison (which defaults to 2) can be
157-
specified in the ``mpl_image_compare`` decorator with the ``tolerance``
158-
argument:
159-
160-
.. code:: python
161-
162-
@pytest.mark.mpl_image_compare(tolerance=20)
163-
def test_image():
164-
...
165-
166-
Savefig options
167-
^^^^^^^^^^^^^^^
168-
169-
You can pass keyword arguments to ``savefig`` by using
170-
``savefig_kwargs`` in the ``mpl_image_compare`` decorator:
171-
172-
.. code:: python
173-
174-
@pytest.mark.mpl_image_compare(savefig_kwargs={'dpi':300})
175-
def test_image():
176-
...
177-
178-
Baseline images
179-
^^^^^^^^^^^^^^^
180-
181-
The baseline directory (which defaults to ``baseline`` ) and the
182-
filename of the plot (which defaults to the name of the test with a
183-
``.png`` suffix) can be customized with the ``baseline_dir`` and
184-
``filename`` arguments in the ``mpl_image_compare`` decorator:
185-
186-
.. code:: python
187-
188-
@pytest.mark.mpl_image_compare(baseline_dir='baseline_images',
189-
filename='other_name.png')
190-
def test_image():
191-
...
192-
193-
The baseline directory in the decorator above will be interpreted as
194-
being relative to the test file. Note that the baseline directory can
195-
also be a URL (which should start with ``http://`` or ``https://`` and
196-
end in a slash). If you want to specify mirrors, set ``baseline_dir`` to
197-
a comma-separated list of URLs (real commas in the URL should be encoded
198-
as ``%2C``).
199-
200-
Finally, you can also set a custom baseline directory globally when
201-
running tests by running ``pytest`` with::
202-
203-
pytest --mpl --mpl-baseline-path=baseline_images
204-
205-
This directory will be interpreted as being relative to where pytest
206-
is run. However, if the ``--mpl-baseline-relative`` option is also
207-
included, this directory will be interpreted as being relative to
208-
the current test directory.
209-
In addition, if both this option and the ``baseline_dir``
210-
option in the ``mpl_image_compare`` decorator are used, the one in the
211-
decorator takes precedence.
212-
213-
Results always
214-
^^^^^^^^^^^^^^
215-
216-
By default, result images are only saved for tests that fail.
217-
Passing ``--mpl-results-always`` to pytest will force result images
218-
to be saved for all tests, even for tests that pass.
219-
220-
When in **hybrid mode**, even if a test passes hash comparison,
221-
a comparison to the baseline image will also be carried out,
222-
with the baseline image and diff image (if image comparison fails)
223-
saved for all tests. This secondary comparison will not affect
224-
the success status of the test.
225-
226-
This option is useful for always *comparing* the result images against
227-
the baseline images, while only *assessing* the tests against the
228-
hash library.
229-
If you only update your baseline images after merging a PR, this
230-
option means that the generated summary will always show how the
231-
PR affects the baseline images, with the success status of each
232-
test (based on the hash library) also shown in the generated
233-
summary. This option is applied automatically when generating
234-
a HTML summary.
235-
236-
When the ``--mpl-results-always`` option is active, and some hash
237-
comparison tests are performed, a hash library containing all the
238-
result hashes will also be saved to the root of the results directory.
239-
The filename will be extracted from ``--mpl-generate-hash-library``,
240-
``--mpl-hash-library`` or ``hash_library=`` in that order.
241-
242-
Base style
243-
^^^^^^^^^^
244-
245-
By default, tests will be run using the Matplotlib 'classic' style
246-
(ignoring any locally defined RC parameters). This can be overridden by
247-
using the ``style`` argument:
248-
249-
.. code:: python
250-
251-
@pytest.mark.mpl_image_compare(style='fivethirtyeight')
252-
def test_image():
253-
...
254-
255-
Package version dependencies
256-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
257-
Different versions of Matplotlib and FreeType may result in slightly
258-
different images. When testing on multiple platforms or as part of a
259-
pipeline, it is important to ensure that the versions of these
260-
packages match the versions used to generate the images used for
261-
comparison. It can be useful to pin versions of Matplotlib and FreeType
262-
so as to avoid automatic updates that fail tests.
263-
264-
Removing text
265-
^^^^^^^^^^^^^
266-
267-
If you are running a test for which you are not interested in comparing
268-
the text labels, you can use the ``remove_text`` argument to the
269-
decorator:
270-
271-
.. code:: python
272-
273-
@pytest.mark.mpl_image_compare(remove_text=True)
274-
def test_image():
275-
...
276-
277-
This will make the test insensitive to changes in e.g. the freetype
278-
library.
279-
280-
Supported formats and deterministic output
281-
------------------------------------------
282-
283-
By default, pytest-mpl will save and compare figures in PNG format. However,
284-
it is possible to set the format to use by setting e.g. ``savefig_kwargs={'format': 'pdf'}``
285-
in ``mpl_image_compare``. Supported formats are ``'eps'``, ``'pdf'``, ``'png'``, and ``'svg'``.
286-
Note that Ghostscript is required to be installed for comparing PDF and EPS figures, while
287-
Inkscape is required for SVG comparison.
288-
289-
By default, Matplotlib does not produce deterministic output that will have a
290-
consistent hash every time it is run, or over different Matplotlib versions. In
291-
order to enforce that the output is deterministic, you can set the ``deterministic``
292-
keyword argument in ``mpl_image_compare``:
293-
294-
.. code:: python
295-
296-
@pytest.mark.mpl_image_compare(deterministic=True)
297-
298-
This does a number of things such as e.g., setting the creation date in the
299-
metadata to be constant, and avoids hard-coding the Matplotlib in the files.
300-
301-
Test failure example
302-
--------------------
303-
304-
If the images produced by the tests are correct, then the test will
305-
pass, but if they are not, the test will fail with a message similar to
306-
the following::
307-
308-
E Exception: Error: Image files did not match.
309-
E RMS Value: 142.2287807767823
310-
E Expected:
311-
E /var/folders/zy/t1l3sx310d3d6p0kyxqzlrnr0000gr/T/tmp4h4oxr7y/baseline-coords_overlay_auto_coord_meta.png
312-
E Actual:
313-
E /var/folders/zy/t1l3sx310d3d6p0kyxqzlrnr0000gr/T/tmp4h4oxr7y/coords_overlay_auto_coord_meta.png
314-
E Difference:
315-
E /var/folders/zy/t1l3sx310d3d6p0kyxqzlrnr0000gr/T/tmp4h4oxr7y/coords_overlay_auto_coord_meta-failed-diff.png
316-
E Tolerance:
317-
E 10
318-
319-
The image paths included in the exception are then available for
320-
inspection:
321-
322-
+----------------+----------------+-------------+
323-
| Expected | Actual | Difference |
324-
+================+================+=============+
325-
| |expected| | |actual| | |diff| |
326-
+----------------+----------------+-------------+
327-
328-
In this case, the differences are very clear, while in some cases it may
329-
be necessary to use the difference image, or blink the expected and
330-
actual images, in order to see what changed.
331-
332-
The default tolerance is 2, which is very strict. In some cases, you may
333-
want to relax this to account for differences in fonts across different
334-
systems.
335-
336-
By default, the expected, actual and difference files are written to a
337-
temporary directory with a non-deterministic path. If you want to instead
338-
write them to a specific directory, you can use::
339-
340-
pytest --mpl --mpl-results-path=results
341-
342-
The ``results`` directory will then contain one sub-directory per test, and each
343-
sub-directory will contain the three files mentioned above. If you are using a
344-
continuous integration service, you can then use the option to upload artifacts
345-
to upload these results to somewhere where you can view them. For more
346-
information, see:
347-
348-
* `Uploading artifacts on Travis-CI <https://docs.travis-ci.com/user/uploading-artifacts/>`_
349-
* `Build Artifacts (CircleCI) <https://circleci.com/docs/1.0/build-artifacts/>`_
350-
* `Packaging Artifacts (AppVeyor) <https://www.appveyor.com/docs/packaging-artifacts/>`_
351-
352-
Running the tests for pytest-mpl
353-
--------------------------------
354-
355-
If you are contributing some changes and want to run the tests, first
356-
install the latest version of the plugin then do::
357-
358-
cd tests
359-
pytest --mpl
360-
361-
The reason for having to install the plugin first is to ensure that the
362-
plugin is correctly loaded as part of the test suite.
363-
364-
.. |html all| image:: images/html_all.png
365-
.. |html filter| image:: images/html_filter.png
366-
.. |html result| image:: images/html_result.png
367-
.. |expected| image:: images/baseline-coords_overlay_auto_coord_meta.png
368-
.. |actual| image:: images/coords_overlay_auto_coord_meta.png
369-
.. |diff| image:: images/coords_overlay_auto_coord_meta-failed-diff.png

docs/configuration.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,27 @@ decorator:
131131
This will make the test insensitive to changes in e.g. the freetype
132132
library.
133133

134+
Supported formats and deterministic output
135+
------------------------------------------
136+
137+
By default, pytest-mpl will save and compare figures in PNG format. However,
138+
it is possible to set the format to use by setting e.g. ``savefig_kwargs={'format': 'pdf'}``
139+
in ``mpl_image_compare``. Supported formats are ``'eps'``, ``'pdf'``, ``'png'``, and ``'svg'``.
140+
Note that Ghostscript is required to be installed for comparing PDF and EPS figures, while
141+
Inkscape is required for SVG comparison.
142+
143+
By default, Matplotlib does not produce deterministic output that will have a
144+
consistent hash every time it is run, or over different Matplotlib versions. In
145+
order to enforce that the output is deterministic, you can set the ``deterministic``
146+
keyword argument in ``mpl_image_compare``:
147+
148+
.. code:: python
149+
150+
@pytest.mark.mpl_image_compare(deterministic=True)
151+
152+
This does a number of things such as e.g., setting the creation date in the
153+
metadata to be constant, and avoids hard-coding the Matplotlib in the files.
154+
134155
Test failure example
135156
--------------------
136157

Binary file not shown.
Binary file not shown.
-23.4 KB
Binary file not shown.

images/html_all.png

-60.1 KB
Binary file not shown.

images/html_filter.png

-56.6 KB
Binary file not shown.

images/html_result.png

-56.3 KB
Binary file not shown.

0 commit comments

Comments
 (0)