Sto lavorando su un programma python (2.7) che produce un sacco di figure matplotlib diverse (i dati non sono casuali). Sono disposto a implementare alcuni test (utilizzando l'unittest) per essere sicuri che le cifre generate siano corrette. Ad esempio, memorizzo la figura attesa (dati o immagine) in qualche punto, eseguo la mia funzione e confronta il risultato con il riferimento. C'è un modo per fare questo ?Come posso scrivere test unitari contro codice che usa matplotlib?
risposta
Nel mio experience, i test di confronto immagini finiscono per portare più problemi di quanti ne valgano. Questo è particolarmente vero se si desidera eseguire l'integrazione continua su più sistemi (come TravisCI) che potrebbero avere font leggermente diversi o backend di disegno disponibili. Può essere molto impegnativo mantenere il test superato anche quando le funzioni funzionano perfettamente. Inoltre, il test in questo modo richiede il mantenimento di immagini nel repository git, che può rapidamente portare al deposito in modo eccessivo se si modifica il codice spesso.
Un approccio migliore secondo me è (1) presupporre che matplotlib stia effettivamente disegnando correttamente la figura e (2) esegua test numerici contro i dati restituiti dalle funzioni di tracciamento. (. È inoltre possibile sempre trovare questi dati all'interno dell'oggetto Axes
se si sa dove guardare)
Ad esempio, dire che si vuole testare una semplice funzione come questa:
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)
vostro unit test potrebbe quindi assomigliare
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, equivalentemente,
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 ha un testing infrastructure. Per esempio:
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')
Dal docs:
La prima volta che si esegue il test, non ci sarà alcuna immagine di base per confrontare contro, quindi il test avrà esito negativo. Copia le immagini di output (in in questo caso result_images/test_category/spines_axes_positions. *) Nella sottodirectory corretta dell'albero baseline_images nella directory di origine (in questo caso lib/matplotlib/tests/baseline_images/test_category). Quando riesegui i test, dovrebbero ora passare.
ho provato la tua strada e ho avuto una e rror. In matplotlib.testing.decorators esiste un "import matplotlib.tests" che produce un ImportError: nessun modulo chiamato test. Ho fatto qualche ricerca e in effetti non esiste un modulo di test nei miei file matplolib e la documentazione dice pochissimi su di esso. Qualcuno sa come risolverlo? –
- 1. Come scrivere test unitari per il codice Meteor lato server?
- 2. Come possiamo eseguire i test unitari contro la manipolazione DOM?
- 3. Test unitari con codice EF First DataContext
- 4. Esempi di test unitari?
- 5. Test unitari o test funzionali?
- 6. Come scrivere test contro l'input dell'utente in Go
- 7. Come posso scrivere test unitari per le funzioni di clojure private?
- 8. Esegui test unitari per codice non di produzione?
- 9. Con quale frequenza dovremmo scrivere i test unitari?
- 10. Rifacimento pratico con test unitari
- 11. Test unitari con Automake
- 12. Test unitari in C++
- 13. Come posso eseguire xUnit Test unitari con VS2015 Preview?
- 14. Test unitari con singleton
- 15. Come posso compilare manualmente il codice Cython che usa C++?
- 16. Test unitari con Mockito
- 17. Test unitari NHibernate UserTypes
- 18. test unitari per screen-scraping?
- 19. Altri bug nei test unitari rispetto al codice di produzione
- 20. Come posso falsificare HttpContext per i test unitari?
- 21. Test unitari e test di accettazione
- 22. matplotlib che usa twinx e twiny insieme (come il twinxy)
- 23. Che cosa si usa per scrivere Vai
- 24. Come scrivere prima il test dell'unità e poi il codice?
- 25. Come gestire i test unitari in F #?
- 26. Devo scrivere Test unitari per le operazioni CRUD quando ho già test di integrazione?
- 27. Dove conservare i test unitari?
- 28. Dimensioni tipiche dei test unitari rispetto al codice di prova
- 29. Test unitari nel codice di rilascio della produzione?
- 30. Come scrivere test unitari automatizzati per il processore di annotazione java?
Con la soluzione, è necessario restituire il risultato della trama. C'è un modo per fare la stessa cosa senza doverlo restituire? "Catturando" il fico? La mia trama funziona "return" void per ora, se è l'unico modo in cui posso cambiare ma mi piacerebbe non farlo. –
Guarda il secondo esempio, mostra come puoi introspettare l'oggetto degli assi per trovare tutti i dati che vengono utilizzati per disegnare la trama al suo interno. – mwaskom
@mwaskom Qualche esperienza nell'esecuzione di test su mpl.collection che hai aggiunto esplicitamente? per esempio. 'Ax.add_collection (PatchCollection (...))'? –