我想为交互式matplotlib图编写unittest。我的问题是我找不到模拟按键或鼠标按键事件的好方法。我了解pyautogui,但是随后我不得不关心matplotlib窗口在屏幕上的位置(例如,在TravisCI上,我怀疑它是否可以在不配置的情况下正常运行)。我曾尝试研究Matplotlib的单元测试,但找不到任何有用的东西。最好的解决方案是在代码内触发事件而不涉及GUI部分,但到目前为止我还无法解决。
我想出的最简单的示例如下。您可以使用i
键在绘图上标记点。我要测试的功能是on_press
。
import numpy as np
import matplotlib.pyplot as plt
class PointRecorder:
def __init__(self, x, y):
plt.ion()
self.figure = plt.figure()
self.cid = self.figure.canvas.mpl_connect("key_press_event", self.on_press)
self.x = x
self.y = y
self.x_points, self.y_points = [2], [0.5]
plt.plot(self.x, self.y, "r")
self.pts, = plt.plot(self.x_points, self.y_points, "ko", markersize=6, zorder=99)
plt.show(block=True)
def on_press(self, event):
ix, iy = event.xdata, event.ydata
if event.inaxes is None:
return
if event.key == 'i':
self.x_points.append(ix)
self.y_points.append(iy)
self.pts.set_data(self.x_points, self.y_points)
if self.pts.stale:
self.figure.canvas.draw_idle()
def get_data(self):
return self.pts.get_data()
if __name__ == "__main__":
x = np.linspace(0, 6, 100)
y = np.sin(x)
graph = PointRecorder(x, y)
print(*graph.get_data())
您能提出一种应如何正确测试这种功能的方法吗?
答案 0 :(得分:1)
我不是单元测试方面的专家,但是我的猜测是您需要实例化一个Event对象(在key_press_event的情况下,它应该是一个KeyEvent),并从您的设备中调用graph.on_press(event)
测试代码
答案 1 :(得分:0)
根据建议,解决方案如下:首先定义一个空白事件。
PointRecorder
然后初始化上面的mock_event
类。之后,定义一个适合PointRecorder.on_press
方法的patch
。还要plt.show
@mock.patch("matplotlib.pyplot.show")
def test_insert(mock_show):
x, y = np.arange(100), np.arange(100)
obj = PointRecorder(x, y)
mck = mock_event(xdata=50, ydata=40, button="i", key="i", fig=obj.figure, canvas=obj.figure.canvas, inaxes=True)
obj.on_clicked(event=mck)
a, b = obj.get_data()
np.testing.assert_array_equal(a, np.array([2, 50])) # 2 was originally in the __init__
np.testing.assert_array_equal(b, np.array([0.5, 40])) # 0.5 was originally in the __init__
mock_show.assert_called()
以避免阻塞执行。
{{1}}