Niedawno zaprojektowałem moduł szeregów czasowych, w którym moje szeregi czasowe są zasadniczo SortedDictionnary<DateTime, double>
.
Teraz chciałbym utworzyć testy jednostkowe, aby upewnić się, że ten moduł zawsze działa i daje oczekiwany wynik.
Częstą operacją jest obliczanie wydajności między punktami w szeregu czasowym.
Więc tworzę szereg czasowy, powiedzmy {1.0, 2.0, 4.0} (w niektórych terminach), i spodziewam się, że wynik wyniesie {100%, 100%}.
Chodzi o to, że jeśli ręcznie utworzę szereg czasowy z wartościami {1.0, 1.0} i sprawdzę równość (porównując każdy punkt), test nie przejdzie, ponieważ zawsze będą niedokładności podczas pracy z reprezentacjami binarnymi rzeczywistych liczby.
Dlatego postanowiłem utworzyć następującą funkcję:
private static bool isCloseEnough(double expected, double actual, double tolerance=0.002)
{
return squaredDifference(expected, actual) < Math.Pow(tolerance,2);
}
Czy istnieje inny wspólny sposób radzenia sobie z takim przypadkiem?
źródło
Assert.That(result, Is.InRange(expected-tolerance, expected+tolerance));
zawiedzie, jeślitolerance/abs(expected) < 1E-16
.abs(expected)
będą to cyfry od jednej do podwójnej cyfry. Przyjąłem również tolerancję w okolicach 1E-9. Przy tych założeniach to rzeczywiście uproszczone podejście może ci dobrze służyć (używamIs.InRange
w moich testach).Jak sugerował RichardM, jeśli nie korzystasz z NUnit, najlepszym sposobem wydaje się użycie Assert.AreEqual (podwójne, podwójne, podwójne) , gdzie ostatnia to precyzja.
źródło
To zależy od tego, co zrobisz z liczbami. Jeśli testujesz metodę, która ma np. Wybrać odpowiednią wartość z zestawu danych wejściowych na podstawie niektórych kryteriów, powinieneś przetestować pod kątem ścisłej równości. Jeśli wykonujesz obliczenia zmiennoprzecinkowe, zwykle będziesz musiał przetestować z niezerową tolerancją. To, jak duża jest tolerancja, zależy od obliczeń, ale przy podwójnej precyzji dobrym punktem wyjścia jest wybór tolerancji względnej 1E-14 dla prostych obliczeń i 1E-8 (tolerancja) dla bardziej skomplikowanych. YMMV oczywiście i musisz dodać małą absolutną tolerancję, jeśli oczekiwany wynik to 0.
źródło