Esistono framework di test per lo sviluppo di software numerici


10

Ho scoperto che gran parte della mia programmazione scientifica computazionale ha requisiti di test che non sono coperti da framework di test standard:

  1. Test dei tempi di calcolo

    • Per assicurarsi che gli algoritmi non rallentino. Potrei fare qualcosa del genere assureSmallerEqual(RuntimeWrapper(algorithm),53)ma vorrei che la soglia dei 53 secondi venisse ridotta continuamente mentre sto lavorando all'algoritmo, cioè qualcosa del genereassureSmallerEqual(RuntimeWrapper(algorithm),'previousbest+noisetolerance')
  2. Test delle prestazioni

    • Per assicurarsi che un algoritmo che abbia precedentemente trovato una buona approssimazione a una soluzione analitica trovi ancora una soluzione che sia almeno altrettanto buona o migliore. Ancora una volta, questo potrebbe essere emulato da un test di integrazione standard, ma vorrei che la tolleranza diminuisse continuamente mentre l'algoritmo migliora sempre meglio. Pensa a sostituire assureAlmostEqual(foo(),1,places=3)conassureAlmostEqual(foo(),1,places='previousbest')
  3. Test dei requisiti fisici

    • Per assicurarsi che gli algoritmi non abbiano improvvisamente bisogno di più memoria / spazio sul disco rigido. Molto simile a 1.
  4. Test dei requisiti astratti

    • Per assicurarsi che un algoritmo che ha funzionato bene con approssimazioni quadratiche non abbia improvvisamente bisogno di approssimazioni cubiche o che un algoritmo che ha funzionato bene con il passo 0.1 non abbia improvvisamente bisogno di 0,01 per stabilità. Ancora una volta, questi potrebbero essere emulati da test di integrazione standard, ma l'obiettivo è ricordare quale sia il parametro di requisito più piccolo che ha raggiunto un determinato obiettivo, quindi ciò richiederebbe un sacco di aggiornamento manuale. Ad esempio, se in foo(10)precedenza non avesse fatto eccezioni, mi piacerebbe che il framework assicurasse che funzioni foo(10)ancora e provare anche se foo(9)ora funziona (nel qual caso tutti i test futuri garantiranno che funzioni foo(9)ancora).

Si potrebbe sostenere che ciò che sto chiedendo non descrive i test nel senso di test unitari / di integrazione, dal momento che un aumento dei tempi di esecuzione, ad esempio, potrebbe essere accettabile in cambio di altri miglioramenti.
In pratica, tuttavia, so che avrei risparmiato molto tempo nel debug se avessi avuto la funzionalità di test sopra, perché nel 95% dei casi i requisiti e le prestazioni sono andati male a causa dei bug che ho introdotto. In effetti, so per certo che molti bug che ho scoperto (dopo aver perso molto tempo a controllare il mio codice) con librerie di software numerico esterno avrebbero potuto essere evitati in modo banale se i test di cui sopra fossero stati applicati rigorosamente.

PS

La domanda simile denominata /programming/34982863/framework-for-regression-testing-of-numerical-code non è un duplicato in quanto descrive funzionalità che sono più facilmente ottenibili con i framework di test di regressione standard.

La domanda Strategie per test unitari e sviluppo guidato dai test richiede strategie rispetto a un framework che aiuta a implementarle (e le strategie che chiede / che sono fornite nelle risposte sono diverse da quelle che descrivo qui, secondo me).


1
Il software numerico è per la simulazione o per l'analisi di dati sperimentali?
Matthew Gunther,

1
@mathewgunther Analisi numerica / Algebra numerica. Nessuna analisi dei dati
Bananach

1
So che molte grandi aziende di simulazione usano framework creati da soli. Fondamentalmente in pitone. È necessario disporre di casi di test che vengono avviati dagli script Python e scrivere alcuni risultati. Successivamente i risultati possono essere confrontati con un qualche tipo di riferimento e produrre un rapporto. Il test può essere automatizzato per l'esecuzione giornaliera o settimanale o mensile ecc. Non sono sicuro che esista un tipo di framework generel, dato che il software di simulazione è in qualche modo speciale nell'implementazione ecc.
vydesaster,

Risposte:


4

1. Questo tipo di test mi sembra poco definito perché le sue condizioni di test sono legate alla particolare macchina su cui sono stati eseguiti i test in fase di sviluppo. Uno dei punti di test è che l'esecuzione dei test sul mio laptop mi dice se c'è qualcosa che non va nel codice o nell'ambiente che ho impostato. I 53 secondi sono specifici per la tua macchina di sviluppo e il tempo di esecuzione aumenterà anche se la macchina di prova è sotto carico da altri carichi di lavoro o utenti. Non mi aspetto che i framework di test rispondano a questo: "la funzione viene eseguita sull'input in meno di 53 secondi" non è proprio una specifica di correttezza molto buona.

2. Penso che questo sia ambiguo e indesiderabile dal punto di vista del test del software per gli stessi motivi 1 , si perde la giustificazione del superamento o del fallimento del test del software.

3. Questo è abbastanza comune, lasciami descrivere una soluzione. Non è proprio il lavoro di un framework di test, ma è possibile utilizzare uno strumento separato come descritto nella domanda Unix SE Limitare l'utilizzo della memoria per un singolo processo Linux . Uno strumento standard da provare per primo è il ulimitcomando bash, che consente di eseguire un processo e assicurarsi che si arresti in modo anomalo se tenta di allocare troppa memoria. Pertanto, se si esegue lo runtestsscript con un limite di memoria, si arresta in modo anomalo e il framework di test dovrebbe essere in grado di gestirlo come un normale errore di test.

4. La maggior parte dei framework di test non pensare di unit test in questo modo a tutti . La suite di test viene eseguita (ad esempio, prima di eseguire il commit del codice sul master o prima della distribuzione) e il risultato è un sì o un no che indica se funziona. I framework di test non lo considerano parte del loro lavoro, ad esempio per tenere traccia dei progressi delle funzionalità, e non è in genere questo il test. Quello che faresti qui è scrivere due test expect_succeeds(foo(10)); expect_fails(foo(9)). Ogni volta vengono eseguiti entrambi i test e i successi e gli errori previsti vengono superati. Quando si implementa foo(9)e ha esito positivo, il test di errore previsto ora fallisce, quindi si riscriverebbeexpect_succeeds(foo(9))e questa è una caratteristica assolutamente standard di tutti i framework. Ma devi essere esplicito su quale comportamento ti aspetti, perché altrimenti va troppo contro le idee di base del test del software.

UNUNUNBperforms_better(foo_A(), foo_B())BUNBe (b) non ha più senso confrontare il codice con il modo in cui era un tempo, tutto il codice e i test sono ora immutabili e inequivocabili. Questo è simile nello spirito a come si potrebbero gestire le riscritture del sistema.

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.