2016-12-15 6 views
7

Czy istnieje jakaś struktura testowa jednostki Catch C++ do porównywania wektorów std :: opartych na zmiennoprzecinkach? Wiem, że mogę porównać rozmiar obu kontenerów i każdego elementu (używając Approx), ale jest to niechlujne.Testuj zmiennoprzecinkowe std :: wektor z C++ Catch

Porównanie typów integralnych wektor działa poprawnie.

Teraz muszę użyć takiej konstrukcji

REQUIRE(computed.size() == expected.size()); 
for (size_t i = 0; i < computed.size(); ++i) 
    REQUIRE(computed[i] == Approx(expected[i])); 

Ale chciałbym używać jednej liniowej (ona pracuje dla integralnych typach):

REQUIRE(computed == expected); 
+1

Na czym polega problem z dokładnym porównaniem? –

+0

Błędy zaokrąglania – miqelm

+0

Jeśli błędy zaokrąglania są niespójne między przebiegami, jednostka testuje lepszy raport. –

Odpowiedz

0

Możesz napisać

CHECK_THAT(actual, EqualsApprox(expected)); 

przy użyciu tego niestandardowego narzędzia Matcher:

#include <vector> 
#include <functional> 

#include <catch.hpp> 

template<typename T, typename Compare> 
struct CompareMatcher 
     : Catch::Matchers::Impl::MatcherBase<std::vector<T>, std::vector<T> > { 

    CompareMatcher(const std::vector<T> &comparator, const Compare &compare) 
      : m_comparator(comparator), 
       m_compare(compare) {} 

    bool match(const std::vector<T> &v) const CATCH_OVERRIDE { 
     if (m_comparator.size() != v.size()) { 
      return false; 
     } 
     for (size_t i = 0; i < v.size(); ++i) { 
      if (!m_compare(m_comparator[i], v[i])) { 
       return false; 
      } 
     } 
     return true; 
    } 

    virtual std::string describe() const CATCH_OVERRIDE { 
     return "Equals: " + Catch::toString(m_comparator); 
    } 

    const std::vector<T> &m_comparator; 
    Compare const &m_compare; 
}; 

template<typename T, typename C> 
CompareMatcher<T, C> 
Compare(const std::vector<T> &comparator, const C &compare) { 
    return CompareMatcher<T, C>(comparator, compare); 
} 

auto EqualsApprox(const std::vector<double> &comparator) { 
    return Compare(comparator, [=](double actual, double expected) { 
     return actual == Approx(expected); 
    }); 
} 

TEST_CASE("example", "[]") { 
    SECTION("passes") { 
     std::vector<double> actual {0, 1.00001}; 
     std::vector<double> expected {0, 1}; 
     CHECK_THAT(actual, EqualsApprox(expected)); 
    } 
    SECTION("fails") { 
     std::vector<double> actual {0, 1.0001}; 
     std::vector<double> expected {0, 1}; 
     CHECK_THAT(actual, EqualsApprox(expected)); 
    } 
} 
+0

Jak to jest ostateczne "EqualsApprox" nie jest również szablonem? – aschepler

+0

"Ok." Używa "podwójnego". – maiermic