Come posso confrontare correttamente i valori doppi per l'uguaglianza in un test unitario?

19

Ho recentemente progettato un modulo di serie temporali in cui le mie serie temporali sono essenzialmente SortedDictionnary<DateTime, double> .

Ora vorrei creare dei test unitari per assicurarmi che questo modulo funzioni sempre e produca i risultati attesi.

Un'operazione comune è calcolare le prestazioni tra i punti delle serie temporali.

Quindi quello che faccio è creare una serie temporale con, ad esempio, {1.0, 2.0, 4.0} (in alcune date) e mi aspetto che il risultato sia {100%, 100%}.

Il fatto è che se creo manualmente una serie temporale con i valori {1.0, 1.0} e controllo l'uguaglianza (confrontando ogni punto), il test non passerà, poiché ci saranno sempre imprecisioni quando si lavora con i binari rappresentazioni di numeri reali.

Quindi, ho deciso di creare la seguente funzione:

private static bool isCloseEnough(double expected, double actual, double tolerance=0.002)
{
    return squaredDifference(expected, actual) < Math.Pow(tolerance,2);
}

C'è un altro modo comune di affrontare un caso del genere?

    
posta SRKX 07.02.2012 - 14:41
fonte

3 risposte

5

Come suggerito da RichardM, se non si utilizza NUnit, il modo migliore sembra utilizzare Assert.AreEqual (double, double, double) , dove l'ultimo è la precisione.

    
risposta data 07.02.2012 - 15:45
fonte
10

Posso pensare ad altri due modi per affrontare questo problema:

Puoi utilizzare Is.InRange :

Assert.That(result, Is.InRange(expected-tolerance, expected+tolerance));

Puoi utilizzare Math.Round :

Assert.That(Math.Round(result, sigDigits), Is.EqualTo(expected));

Penso che entrambi i modi siano più espressivi di una funzione dedicata, perché il lettore può vedere esattamente cosa sta succedendo con il tuo numero prima che venga confrontato con il valore previsto.

    
risposta data 07.02.2012 - 14:56
fonte
3

Dipende da cosa fai con i numeri. Se stai testando un metodo che dovrebbe per es. selezionare un valore appropriato da un set di input basato su alcuni criteri, quindi è necessario testare l'uguaglianza rigorosa. Se stai facendo calcoli in virgola mobile, di solito dovrai testare con una tolleranza diversa da zero. Quanto è grande la tolleranza dipende dai calcoli, ma con una doppia precisione un buon punto di partenza è scegliere la tolleranza 1 em-14 relativa per i calcoli semplici e 1E-8 (tolleranza) per quelli più complicati. YMMV naturalmente, ed è necessario aggiungere qualche piccola tolleranza assoluta se il risultato previsto è 0.

    
risposta data 07.02.2012 - 16:49
fonte

Leggi altre domande sui tag