Come faccio a testare le procedure matematiche con sfumature unitarie?

2

Sto scrivendo del codice per una simulazione scientifica e mi piacerebbe davvero usarlo come un'opportunità per fare pratica con alcuni test unitari. Capisco l'idea dei test in teoria, ma non riesco proprio a vedere come applicarlo al mio problema per dimostrare che un risultato matematico viene fuori correttamente.

Ad esempio, una grande parte del mio algoritmo consiste nel fare una convoluzione numerica per spostare e alterare un segnale; poiché ho solo campioni discreti di un tale segnale, ho bisogno di ricorrere a una procedura di interpolazione prima di fare qualsiasi pezzo della convoluzione. Convincere me stesso le opere di interpolazione è abbastanza facile graficamente (tracciare analiticamente una funzione conosciuta e tracciare l'interpolazione sopra di essa), ma molto molto difficile numericamente (dipende già frequenza di campionamento e ordine di interpolazione --- entrambi possono dare variazioni significative nell'errore dell'interpolazione).

Naturalmente posso solo dire "per questo segnale, frequenza di campionamento e ordine di interpolazione le cose concordano con una precisione di epsilon", ma sembra che una porzione così piccola dello spazio di test non valga la pena di essere eseguita. Quali sono alcune tecniche che posso usare per convincermi che cose come l'interpolazione (o inversioni di matrice, o integrazioni numeriche, o ...) funzionano un po 'più in generale?

    
posta Connor Glosser 28.12.2016 - 16:56
fonte

2 risposte

4

I test sono sempre solo esempi: non possono mai dimostrare correttezza. Ma anche se lo spazio del test è vasto, possiamo estrarre molto valore da alcuni esempi ben scelti. Molti input sono fondamentalmente equivalenti tra loro, con solo un piccolo cambiamento di un valore tra loro. Possiamo raggruppare tutti gli input simili in una classe di equivalenza e quindi testare solo un'istanza di quella classe di equivalenza.

L'istanza della classe di equivalenza può essere scelta più o meno a caso, ma i casi limite tendono ad essere i più importanti, perché è probabile che ci siano bug in casi limite. Ha quindi senso testare attorno al valore minimo e massimo per ogni parametro.

Esistono vari criteri di copertura del test che ci dicono quanto sono efficaci i nostri test. Uno di questi criteri è coverage statement : quale percentuale di dichiarazioni è stata eseguita dalla suite di test? Se mancano delle istruzioni, possiamo costruire casi di test per esercitare un particolare percorso di codice. A seconda del tuo linguaggio di programmazione, ci dovrebbero essere già strumenti per calcolare la copertura del test.

Creando tali test, creiamo confidenza sul fatto che il programma stia facendo ciò che pensiamo stia facendo. Creando una suite di test automatizzata, possiamo assicurarci al clic di un pulsante che il comportamento non è cambiato, ad esempio dopo aver apportato una modifica non correlata. In particolare, questa confidenza ci consente di ridefinire il codice più avanti nel progetto.

Andando avanti, è una buona idea esprimere i requisiti come casi di test. Ogni volta che al programma mancano alcune funzionalità o quando il comportamento del programma è diverso dalle nostre aspettative, dovremmo scrivere un test che asserisca le nostre aspettative. Quindi possiamo scrivere il codice per far passare il test. Questa è una tecnica semplice per far crescere la suite di test nel tempo e impedire regressioni: una modifica al sistema reintroduce un problema già risolto in precedenza.

Non tutti i test devono eseguire uno scenario completo. Se ci sono singole funzioni all'interno del progetto che consideri ad alto rischio (cioè non sono immediatamente ovvie), allora dovresti testarle direttamente. Ciò richiede che la funzione sia isolata dal suo ambiente (nessuna variabile globale, nessuna funzione di chiamata in cui non si è certi se siano corretti). Per le funzioni matematiche come le operazioni con le matrici, probabilmente questo è già il caso, quindi sono abbastanza facili da testare. Ancora: costruisci le classi di equivalenza e prova con esempi interessanti da queste classi di equivalenza.

    
risposta data 28.12.2016 - 17:28
fonte
1

Il modo in cui vado a provare pezzi così complicati è questo:

  • elenca tutti i casi limite che la funzione / metodo deve coprire (che avrebbe dovuto essere già fatto)
  • crea manualmente questi casi di test (ad es. nel tuo caso: usa un input casuale, esegui la funzione su di esso e rivedi il risultato manualmente).
    • un test case con no edge case
    • tanti casi di test quanti sono i casi limite in cui ogni caso copre esattamente un caso limite
    • casi di test con combinazioni comuni e / o importanti di casi limite (poiché, con molti casi limite, si finisce con un gran casino di casi di test se si vogliono coprire tutte le possibili combinazioni di casi limite)
risposta data 28.12.2016 - 17:07
fonte

Leggi altre domande sui tag