2010-07-06 21 views
7

Sto scrivendo una piccola utility per il calcolo di una formula matematica complessa (usando la libreria di comuni-matematica per l'integrazione e la ricerca delle radici). Stavo cercando di scriverlo nello stesso modo di una normale applicazione aziendale, tuttavia ho scoperto che sto ottenendo un numero sempre maggiore di classi. Per ottenere il primo passo dei calcoli (1 linea formula con 2 integrali), ho già scritto 3 classi per ogni piccolo bit del calcolo, in modo che io possa usare l'iniezione di dipendenza e prendere in giro correttamente tutte le chiamate a commons-math. È piuttosto fuori controllo, finirò con 20 lezioni per un problema che potrebbe essere risolto su due schermi in una classe (senza test di unità). Quale sarebbe il tuo approccio preferito? Sono molto tentato di affidarmi solo all'accettazione e ai test di livello superiore per questo.Unit test codice matematico

+3

Parli di derisione commons-math. Non lo farei. La matematica dei comuni è un pezzo di codice solido e affidabile. Usalo nei tuoi test invece di prenderlo in giro. Semplifica le cose? – DJClayworth

+0

Se hai bisogno di prendere in giro 20 classi, forse le classi sono troppo strettamente accoppiate? (alta coesione). –

risposta

8

Non lasciare che il test crei un codice completamente inutilizzabile e incomprensibile. E non esagerare con l'essere funzionale con l'approccio orientato agli oggetti.

Si sta testando una funzione, vale a dire senza stato che produce lo stesso risultato per gli stessi argomenti. E penso che sia così che dovresti testarlo: dagli argomenti di tutte le possibili classi di equivalenza e asserisci il risultato.

+1

+1: sono d'accordo. Ma, qualunque cosa tu faccia, non omettere i test unitari su questa funzione separatamente. Se lo fai, te ne pentirai quando proverai a testare gli assemblaggi che lo includono. Scrivo da amara esperienza. –

4

In base alla mia esperienza, è necessario utilizzare il test unitario come controllo di integrità e un possibile controllo di regressione. Naturalmente, il test delle unità dovrebbe essere il più completo possibile, ma a volte è molto noioso farlo testare completamente la piena funzionalità del codice.

Le prove di unità non sono una prova formale. Non possono e non vogliono aggirare futuri bug e problemi con il tuo codice. Prova i casi d'uso comune del codice. Se hai bisogno di una grande quantità di affidabilità, dovrai creare un ampio repository di test di regressione. Fortunatamente, per problemi comuni, ci sono alcuni database online per questo genere di cose. TPLP per esempio, è un database di problemi (e soluzioni) per Theorem Provers.

Una tecnica che a volte funziona per me ... in genere in codice matematico, ci sono metodi "facili ma lenti" e metodi "veloci ma difficili da programmare". Quando scrivi il codice, vuoi usare il veloce ma difficile da scrivere (quindi ti aspetti bug). Quindi ... fai in modo veloce il sistema sotto test (SUT). Quando fai un test unitario, crea 1000 problemi casuali e risolvili con il metodo "facile ma lento". Quindi, esegui il SUT e assicurati che le risposte siano analoghe.

Supponendo ovviamente ... che la creazione di problemi casuali è un problema facile da risolvere. A volte lo è, a volte non lo è. È difficile dirlo senza che tu ci parli del codice matematico stesso. Ora ... questo porta TUTTI i casi? No. Ma otterrà i casi "comuni". E se un caso d'angolo si apre in pratica, avvolgilo in un Test unitario e sistemalo nella prossima versione del tuo codice.