首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何针对使用matplotlib的代码编写单元测试?

如何针对使用matplotlib的代码编写单元测试?
EN

Stack Overflow用户
提问于 2015-01-15 00:44:51
回答 2查看 11.5K关注 0票数 47

我正在开发一个python (2.7)程序,它会生成许多不同的matplotlib图形(数据不是随机的)。我愿意实现一些测试(使用unittest),以确保生成的数据是正确的。例如,我将期望的图形(数据或图像)存储在某个位置,然后运行我的函数并将结果与引用进行比较。有没有办法做到这一点?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-15 03:32:30

在我的experience中,图像比较测试最终带来的麻烦比它们的价值更多。如果您希望跨多个可能具有稍微不同的字体或可用绘图后端的系统(如TravisCI)运行持续集成,情况尤其如此。即使在函数完全正常工作的情况下,保持测试通过也可能需要大量的工作。此外,这种测试方式需要将图像保存在git存储库中,如果您经常更改代码,这可能会很快导致存储库膨胀。

在我看来,更好的方法是(1)假设matplotlib实际上将正确地绘制图形,(2)对绘图函数返回的数据运行数值测试。(如果您知道在哪里查找,也可以始终在Axes对象中找到此数据。)

例如,假设您想测试一个简单的函数,如下所示:

import numpy as np
import matplotlib.pyplot as plt
def plot_square(x, y):
    y_squared = np.square(y)
    return plt.plot(x, y_squared)

然后,您的单元测试可能如下所示

def test_plot_square1():
    x, y = [0, 1, 2], [0, 1, 2]
    line, = plot_square(x, y)
    x_plot, y_plot = line.get_xydata().T
    np.testing.assert_array_equal(y_plot, np.square(y))

或者,等同地,

def test_plot_square2():
    f, ax = plt.subplots()
    x, y = [0, 1, 2], [0, 1, 2]
    plot_square(x, y)
    x_plot, y_plot = ax.lines[0].get_xydata().T
    np.testing.assert_array_equal(y_plot, np.square(y))
票数 47
EN

Stack Overflow用户

发布于 2019-02-17 00:45:23

您还可以使用unittest.mock模拟matplotlib.pyplot,并检查是否使用适当的参数对其进行了适当的调用。假设您想要测试module.py中的一个plot_data(data)函数(假设它位于package/src/中),该函数如下所示:

import matplotlib.pyplot as plt

def plot_data(x, y, title):
    plt.figure()
    plt.title(title)
    plt.plot(x, y)
    plt.show()

为了在test_module.py文件中测试此函数,您需要:

import numpy as np

from unittest import mock
import package.src.module as my_module  # Specify path to your module.py


@mock.patch("%s.my_module.plt" % __name__)
def test_module(mock_plt):
    x = np.arange(0, 5, 0.1)
    y = np.sin(x)
    my_module.plot_data(x, y, "my title")

    # Assert plt.title has been called with expected arg
    mock_plt.title.assert_called_once_with("my title")

    # Assert plt.figure got called
    assert mock_plt.figure.called

这将检查是否使用参数my title调用了title方法,以及是否在plt对象的plot_data内调用了figure方法。

更详细的解释:

@mock.patch("module.plt")装饰器“修补”导入到module.py中的plt模块,并将其作为mock对象(mock_plt)作为参数注入到test_module中。这个模拟对象(作为mock_plt传递)现在可以在我们的测试中使用,以记录plot_data (我们正在测试的函数)对plt执行的所有操作-这是因为plot_dataplt的所有调用现在都将在我们的模拟对象上进行。

此外,除了assert_called_once_with之外,您可能还想使用其他类似的方法,如assert_not_calledassert_called_once等。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27948126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档