Strategie per unit testing e sviluppo test-driven


16

Sono un grande sostenitore dello sviluppo guidato dai test nell'informatica scientifica. La sua utilità in pratica è semplicemente sbalorditiva e allevia davvero i classici problemi che gli sviluppatori di codice conoscono. Tuttavia, ci sono difficoltà intrinseche nel testare codici scientifici che non si incontrano nella programmazione generale, quindi i testi TDD non sono estremamente utili come tutorial. Per esempio:

  • In generale non conosci una risposta esatta per un dato problema complesso a priori, quindi come puoi scrivere un test?

  • Il grado di parallelismo cambia; Di recente ho riscontrato un bug in cui l'utilizzo delle attività MPI come multiplo di 3 falliva, ma un multiplo di 2 ha funzionato. Inoltre, i framework di test comuni non sembrano molto compatibili con MPI a causa della natura stessa di MPI: è necessario rieseguire un binario di test per modificare il numero di attività.

  • I codici scientifici hanno spesso molte parti strettamente accoppiate, interdipendenti e intercambiabili. Abbiamo visto tutti il ​​codice legacy e sappiamo quanto sia allettante rinunciare a un buon design e utilizzare variabili globali.

  • Spesso un metodo numerico può essere un "esperimento", o il programmatore non capisce completamente come funziona e sta cercando di capirlo, quindi anticipare i risultati è impossibile.

Alcuni esempi di test che scrivo per codice scientifico:

  • Per gli integratori di tempo, utilizzare un semplice ODE con una soluzione esatta e verificare che l'integratore lo risolva entro una determinata precisione e l'ordine di accuratezza sia corretto eseguendo test con passi di dimensioni variabili.

  • Test di stabilità zero: verificare che un metodo con 0 limiti / condizioni iniziali rimanga a 0.

  • Test di interpolazione: data una funzione lineare, assicurarsi che un'interpolazione sia corretta.

  • Convalida legacy: isolare un blocco di codice in un'applicazione legacy che è nota per essere corretta ed estrarre alcuni valori discreti da utilizzare per i test.

Spesso viene fuori che non riesco a capire come testare correttamente un determinato blocco di codice, a parte tentativi ed errori manuali. Potete fornire alcuni esempi di test scritti per codice numerico e / o strategie generali per testare software scientifici?


Potresti, per favore, chiarire cosa intendi per test di interpolazione?
Dmitry Kabanov il

Risposte:


8

Metodo di soluzioni fabbricate .

Verificare attraverso studi di perfezionamento che il metodo raggiunga l'ordine teorico di accuratezza.

Conservazione della risposta. Riproduzione bit-saggia e saggia delle soluzioni.


Volevo menzionare MMS nel post originale; è buono per la verifica del codice, ma dal punto di vista del test unitario è del tutto inutile. Se questi test falliscono, non fornisce indizi su dove o perché.
Aurelio,

3
2×2×2

Gran parte della letteratura che ho visto sugli MMS è sostanzialmente una soluzione globale, ad esempio per problemi di CFD, una soluzione prodotta potrebbe essere un'analisi del profilo aerodinamico. Quando questo test fallisce, nella migliore delle ipotesi hai ridotto il colpevole a 5.000 righe di codice, quindi è abbastanza inutile per TDD - non hai idea di dove si verifichi il fallimento effettivo. Sono d'accordo che un problema 2x2x2 è estremamente prezioso e li uso molto spesso. Ma è abbastanza comune che io incontri problemi che si presentano solo con sistemi più grandi; Recentemente ho trovato un bug del compilatore ifort che si è manifestato solo in grandi problemi.
Aurelio,

@Aurelius: nessuna discussione qui. Dovresti avere una serie di test ed eseguirli tutti di frequente.
Bill Barth,

@Aurelius A valore nominale, MMS non è un test unitario, ma un test funzionale o di accettazione (cioè dell'intero sistema). Tuttavia, i codici hanno spesso fasi separate (o possono essere divise in esse). ad es. avanzamento, pressione, viscosità. Si potrebbe quindi testare solo una di queste fasi (una "unità"). Allo stesso modo, un codice potrebbe essere testato senza un BC e quindi con uno. Un amico ha fatto il suo dottorato di ricerca sui test unitari e ha calcolato che il vantaggio maggiore è stato che ti ha costretto a suddividere il programma in unità, quindi può essere testato in unità ... forse questo è più applicabile qui di quanto sembri inizialmente (e in altri modi che non conosco).
iperpallium

6

Bill ha già elencato alcuni metodi che rispondono alle tue preoccupazioni.

Affrontando il tuo terzo punto, no, non c'è motivo di introdurre un forte accoppiamento tra le parti. Al contrario: se le tue funzioni o classi hanno interfacce ben definite, sarà molto più facile scambiare, ad esempio, un risolutore lineare con un altro, o uno schema di time stepping. Basta resistere e quindi sarai in grado di testare questi componenti separatamente. Lo abbiamo fatto con deal.II per decenni.

Al quarto punto: se il tuo metodo è un esperimento, i tuoi esperimenti con il metodo costituiscono un test. Finché non si dispone di analisi, sarà necessario prendere questi risultati dei test come i migliori disponibili. Ma di solito, ci si aspetta, ad esempio, l'ordine di un metodo, oppure si sa che è esatto per una determinata classe di soluzioni, ad esempio i polinomi fino a un certo grado. La verifica che questi facciano parte degli esperimenti e, man mano che l'analisi migliora, è possibile aggiungere test.


1
Per aggiungere alla risposta di Guido, l'esperienza di cui parla è codificata nei ~ 3.000 test che eseguiamo in trattativa. II dopo ogni cambiamento: dealii.org/developer/development/… . Alla domanda su cosa fare se non si conosce la risposta esatta: scrivere comunque un test e lasciarlo confrontare oggi la risposta con la risposta di ieri (o ogni volta che si è scritto il test). Avere un modo per individuare le modifiche nell'output di un codice è utile anche se non si sa se hanno reso la risposta errata o corretta una risposta precedentemente errata.
Wolfgang Bangerth,

3

Di recente ho trovato questa tesi sul TDD in Scienze computazionali. Non l'ho ancora letto, quindi non ho idea se sia buono, ma spero che possa essere di qualche aiuto.

http://cyber.ua.edu/files/2014/12/u0015_0000001_0001551.pdf


1
Ho scremato alcune delle introduzioni e delle conclusioni, e ipotizzando un livello di qualità alla pari con la tesi di dottorato standard, questo spiega entrambi il processo (in modo di alto livello) e fornisce misurazioni reali sulla sua efficacia. Penso che questa sia una vera scoperta.
Godric Seer,

Il link è morto. Intendevi forse Nanthaamornphong, A. "L'efficacia dello sviluppo guidato dai test e delle tecniche di refactoring nella scienza computazionale e nello sviluppo di software di ingegneria". Dottorato di ricerca, Uni. Alabama (2014).
AlQuemist,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.