unittest unitarias pruebas integracion hacer como automatizadas python matplotlib python-unittest

unitarias - pruebas de integracion python



¿Cómo puedo escribir pruebas unitarias contra el código que usa matplotlib? (2)

Estoy trabajando en un programa de python (2.7) que produce una gran cantidad de figuras de matplotlib diferentes (los datos no son aleatorios). Estoy dispuesto a implementar algunas pruebas (utilizando unittest) para estar seguro de que las cifras generadas son correctas. Por ejemplo, almaceno la figura esperada (datos o imagen) en algún lugar, ejecuto mi función y comparo el resultado con la referencia. Hay alguna forma de hacer esto ?


En mi experience , las pruebas de comparación de imágenes terminan causando más problemas de los que valen. Este es especialmente el caso si desea ejecutar una integración continua en múltiples sistemas (como TravisCI) que pueden tener fuentes ligeramente diferentes o fondos de dibujo disponibles. Puede ser un montón de trabajo mantener las pruebas aprobadas incluso cuando las funciones funcionan perfectamente correctamente. Además, las pruebas de esta manera requieren mantener las imágenes en su repositorio de git, lo que puede llevar rápidamente a que el repositorio se hinche si cambia el código con frecuencia.

En mi opinión, un enfoque mejor es (1) asumir que matplotlib realmente dibujará la figura correctamente y (2) realizar pruebas numéricas contra los datos devueltos por las funciones de trazado. (También puede encontrar estos datos dentro del objeto Axes si sabe dónde buscar).

Por ejemplo, digamos que quieres probar una función simple como esta:

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)

Su prueba de unidad entonces podría verse como

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))

O equivalente,

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))


Matplotlib tiene una infraestructura de prueba . Por ejemplo:

import numpy as np import matplotlib from matplotlib.testing.decorators import image_comparison import matplotlib.pyplot as plt @image_comparison(baseline_images=[''spines_axes_positions'']) def test_spines_axes_positions(): # SF bug 2852168 fig = plt.figure() x = np.linspace(0,2*np.pi,100) y = 2*np.sin(x) ax = fig.add_subplot(1,1,1) ax.set_title(''centered spines'') ax.plot(x,y) ax.spines[''right''].set_position((''axes'',0.1)) ax.yaxis.set_ticks_position(''right'') ax.spines[''top''].set_position((''axes'',0.25)) ax.xaxis.set_ticks_position(''top'') ax.spines[''left''].set_color(''none'') ax.spines[''bottom''].set_color(''none'')

De la docs :

La primera vez que se ejecuta esta prueba, no habrá una imagen de referencia con la cual compararla, por lo que la prueba fallará. Copie las imágenes de salida (en este caso result_images / test_category / spines_axes_positions. *) Al subdirectorio correcto del árbol baseline_images en el directorio de origen (en este caso lib / matplotlib / tests / baseline_images / test_category). Al volver a ejecutar las pruebas, ahora deben pasar.