测试#

Matplotlib 使用pytest框架。

测试在 中lib/matplotlib/tests,对 pytest 测试基础设施的定制在matplotlib.testing.

要求#

要运行测试,您需要 设置 Matplotlib 进行开发。特别注意用于测试的附加依赖项。

笔记

我们将假设您希望在开发设置中运行测试。

虽然您可以针对常规安装的 Matplotlib 版本运行测试,但这是一个不太常见的用例。您仍然需要 额外的依赖项进行测试。您还必须从存储库中获取参考图像,因为它们没有与预构建的 Matplotlib 包一起分发。

运行测试#

在开发存储库的根目录中运行:

python -m pytest

pytest 可以通过很多命令行参数进行配置。一些特别有用的是:

-v或者--verbose

更详细

-n NUM

在 NUM 个进程上并行运行测试(需要pytest-xdist

--capture=no或者-s

不捕获标准输出

要从命令行运行单个测试,您可以提供文件路径,可选地后跟以两个冒号分隔的函数,例如(不需要安装测试,但应该安装 Matplotlib):

pytest lib/matplotlib/tests/test_simplification.py::test_clipping

编写一个简单的测试#

Matplotlib 的许多元素都可以使用标准测试进行测试。例如,这是一个来自 的测试matplotlib/tests/test_basic.py

def test_simple():
    """
    very simple example test
    """
    assert 1 + 1 == 2

Pytest 通过搜索名称以开头的文件"test_",然后在这些文件中查找 以 ."test"开头的函数或以"Test".

一些测试有内部副作用,需要在执行后清理(例如创建的图形或修改的rcParams)。pytest 夹具 matplotlib.testing.conftest.mpl_test_settings会自动清理这些;没有必要做任何进一步的事情。

测试中的随机数据#

随机数据是为示例生成数据的一种非常方便的方法,但是随机性对于测试来说是有问题的(因为测试必须是确定性的!)。要解决此问题,请在每个测试中设置种子。对于 numpy 的默认随机数生成器,请使用:

import numpy as np
rng = np.random.default_rng(19680801)

然后rng在生成随机数时使用。

种子是约翰亨特的生日。

编写图像比较测试#

编写基于图像的测试仅比简单测试稍微困难一些。主要考虑因素是您必须在image_comparison 装饰器中指定“基线”或预期的图像。例如,此测试生成单个图像并自动对其进行测试:

from matplotlib.testing.decorators import image_comparison
import matplotlib.pyplot as plt

@image_comparison(baseline_images=['line_dashes'], remove_text=True,
                  extensions=['png'])
def test_line_dashes():
    fig, ax = plt.subplots()
    ax.plot(range(10), linestyle=(0, (3, 3)), lw=5)

第一次运行此测试时,将没有要比较的基线图像,因此测试将失败。将输出图像(在本例中 result_images/test_lines/test_line_dashes.png)复制到源目录中树的正确子目录baseline_images(在本例中lib/matplotlib/tests/baseline_images/test_lines)。将此新文件置于源代码修订控制之下(带有)。重新运行测试时,它们现在应该通过了。git add

基线图像在 Matplotlib 存储库中占用了大量空间。图像比较测试的另一种方法是使用 check_figures_equal装饰器,它应该用于装饰带有两个Figure参数的函数,并使用两种不同的方法(测试方法和基线方法)在图形上绘制相同的图像。装饰师会安排布置图形,然后收集绘制的结果并进行比较。

有关其使用的更多信息,image_comparison请 参见文档。check_figures_equal

在 matplotlib.tests 中创建一个新模块#

我们尝试将测试按他们正在测试的主要模块分类。例如,与mathtext.py模块相关的测试在test_mathtext.py.

使用 GitHub Actions 进行 CI #

GitHub Actions是一个“在云中”的托管 CI 系统。

GitHub Actions 配置为接收新提交到 GitHub 存储库的通知,并在看到这些新提交时运行构建或测试。它会在其中查找 YAML 文件.github/workflows以查看如何测试项目。

GitHub Actions 已经为主要的 Matplotlib GitHub 存储库启用- 例如,请参阅测试工作流

一旦 YAML 工作流文件包含在其中,您的个人 Matplotlib 分支应该会自动启用 GitHub Actions。通常没有必要查看这些工作流程,因为针对主 Matplotlib 存储库提交的任何拉取请求都将被测试。分叉存储库中跳过了测试工作流,但您可以从GitHub Web 界面手动触发运行。

您可以在https://github.com/your_GitHub_user_name/matplotlib/actions查看 GitHub Actions 结果 ——这是一个示例

使用毒物#

Tox是一个针对多个 Python 环境运行测试的工具,包括多个 Python 版本(例如,3.7、3.8),甚至完全不同的 Python 实现(例如,CPython、PyPy、Jython 等),只要所有这些版本都是在系统的 $PATH 上可用(考虑使用系统包管理器,例如 apt-get、yum 或 Homebrew 来安装它们)。

tox 可以在提交拉取请求之前轻松确定您的工作副本是否引入了任何回归。以下是如何使用它:

$ pip install tox
$ tox

您还可以在环境子集上运行 tox:

$ tox -e py38,py39

Tox 按顺序处理所有内容,因此测试多个环境可能需要很长时间。为了加快速度,您可以尝试使用新的、并行化的 tox 版本,称为detox. 试试这个:

$ pip install -U -i http://pypi.testrun.org detox
$ detox

Tox 是使用一个名为tox.ini. 如果您想添加新的测试环境(例如, py33)或者如果您想调整依赖关系或测试运行的方式,您可能需要编辑此文件。有关该tox.ini文件的更多信息,请参阅Tox 配置规范

构建旧版本的 Matplotlib #

当运行 a查看哪个提交引入了某个错误时,您可能(很少)需要构建非常旧的 Matplotlib 版本。需要考虑以下约束:git bisect

  • Matplotlib 1.3(或更早版本)需要 numpy 1.8(或更早版本)。

测试 Matplotlib 的发布版本#

在已发布版本(例如 PyPI 包或 conda 包)的安装上运行测试还需要额外的设置。

笔记

对于最终用户,通常不需要在已发布的 Matplotlib 版本上运行测试。正式版本在发布前经过测试。

安装额外的依赖#

安装额外的依赖项进行测试

获取参考图像#

许多测试将绘图结果与参考图像进行比较。参考图像不是常规打包版本(pip 轮或 conda 包)的一部分。如果要使用参考图像运行测试,则需要获取与要测试的 Matplotlib 版本匹配的参考图像。

为此,请 matplotlib-X.Y.Z.tar.gzPyPI下载匹配的源代码分发, 或者克隆 git 存储库和. 将该文件夹复制到您的 matplotlib 安装文件夹中进行测试。 可以使用以下命令找到正确的目标文件夹:git checkout vX.Y.Zlib/matplotlib/tests/baseline_imagesmatplotlib/tests

python -c "import matplotlib.tests; print(matplotlib.tests.__file__.rsplit('/', 1)[0])"

一个类似的复制lib/mpl_toolkits/tests/baseline_images 是必要的测试mpl_toolkits

运行测试#

要在已安装的 Matplotlib 版本上运行所有测试:

python -m pytest --pyargs matplotlib.tests

测试发现范围可以缩小到单个测试模块甚至单个功能:

python -m pytest --pyargs matplotlib.tests.test_simplification.py::test_clipping