Szukam porównania dwóch tablic w teście Google. W UnitTest ++ odbywa się to poprzez CHECK_ARRAY_EQUAL. Jak to robisz w teście Google?
źródło
Szukam porównania dwóch tablic w teście Google. W UnitTest ++ odbywa się to poprzez CHECK_ARRAY_EQUAL. Jak to robisz w teście Google?
Naprawdę sugerowałbym przyjrzenie się Google C ++ Mocking Framework . Nawet jeśli nie chcesz z niczego kpić, pozwala z łatwością pisać skomplikowane twierdzenia.
Na przykład
//checks that vector v is {5, 10, 15}
ASSERT_THAT(v, ElementsAre(5, 10, 15));
//checks that map m only have elements 1 => 10, 2 => 20
ASSERT_THAT(m, ElementsAre(Pair(1, 10), Pair(2, 20)));
//checks that in vector v all the elements are greater than 10 and less than 20
ASSERT_THAT(v, Each(AllOf(Gt(10), Lt(20))));
//checks that vector v consist of
// 5, number greater than 10, anything.
ASSERT_THAT(v, ElementsAre(5, Gt(10), _));
Jest mnóstwo dopasowań na każdą możliwą sytuację i możesz je łączyć, aby osiągnąć prawie wszystko.
Czy mówiłem ci, że ElementsAre
potrzeba tylko iterators
i size()
metody na zajęciach do pracy? Dzięki temu działa nie tylko z dowolnym kontenerem z STL, ale także z niestandardowymi kontenerami.
Google Mock twierdzi, że jest prawie tak przenośny, jak Google Test i szczerze mówiąc nie rozumiem, dlaczego miałbyś go nie używać. To jest po prostu niesamowite.
ElementsAreArray
lepiej jest porównać tablice, ponieważElementsAre
ma limit 10 elementów.EXPECT_THAT(v, ElementsAreArray(u));
którego korzystałem częściej niż obecne przykłady.Jeśli chcesz tylko sprawdzić, czy tablice są równe, działa również brutalna siła:
int arr1[10]; int arr2[10]; // initialize arr1 and arr2 EXPECT_TRUE( 0 == std::memcmp( arr1, arr2, sizeof( arr1 ) ) );
Jednak to nie mówi, który element się różni.
źródło
Jeśli chcesz porównać wskaźnik tablicy w stylu c z tablicą za pomocą Google Mock, możesz przejść przez std :: vector. Na przykład:
uint8_t expect[] = {1, 2, 3, 42}; uint8_t * buffer = expect; uint32_t buffer_size = sizeof(expect) / sizeof(expect[0]); ASSERT_THAT(std::vector<uint8_t>(buffer, buffer + buffer_size), ::testing::ElementsAreArray(expect));
Google Mock's ElementsAreArray akceptuje również wskaźnik i długość, które umożliwiają porównanie dwóch wskaźników tablicy w stylu c. Na przykład:
ASSERT_THAT(std::vector<uint8_t>(buffer, buffer + buffer_size), ::testing::ElementsAreArray(buffer, buffer_size));
Spędziłem zbyt dużo czasu próbując to poskładać. Dzięki temu postowi StackOverflow dla przypomnienia o inicjalizacji iteratora std :: vector. Zauważ, że ta metoda skopiuje elementy tablicy buforów do std :: vector przed porównaniem.
źródło
buffer_size
, na który wartość zwrócona z testowanego kodu jest nieprawidłowo ustawiana(size_t)-1
, co nie jest rzadkim błędem, wówczas konstruktor wektorowy spróbuje utworzyć bardzo duży wektor! Program testowy może zostać zabity z powodu limitu zasobów lub błędu braku pamięci lub po prostu zwykłej awarii zamiast niepowodzenia asercji testowej. W C ++ 20 używaniestd::span
zamiast wektora powinno temu zapobiegać, ponieważ nie ma potrzeby kopiowania bufora do nowego kontenera.ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length"; for (int i = 0; i < x.size(); ++i) { EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i; }
Źródło
źródło
Miałem dokładnie to samo pytanie, więc napisałem kilka makr, które porównują dwa ogólne kontenery. To rozszerzalny do dowolnego pojemnika, który ma
const_iterator
,begin
iend
. Jeśli to się nie powiedzie, wyświetli szczegółowy komunikat o tym, gdzie tablica poszła źle, i zrobi to dla każdego elementu, który zawiódł; upewni się, że są tej samej długości; a lokalizacja w kodzie, którą zgłasza jako awaria, to ta sama linia, w której dzwoniszEXPECT_ITERABLE_EQ( std::vector< double >, a, b)
.//! Using the google test framework, check all elements of two containers #define EXPECT_ITERABLE_BASE( PREDICATE, REFTYPE, TARTYPE, ref, target) \ { \ const REFTYPE& ref_(ref); \ const TARTYPE& target_(target); \ REFTYPE::const_iterator refIter = ref_.begin(); \ TARTYPE::const_iterator tarIter = target_.begin(); \ unsigned int i = 0; \ while(refIter != ref_.end()) { \ if ( tarIter == target_.end() ) { \ ADD_FAILURE() << #target " has a smaller length than " #ref ; \ break; \ } \ PREDICATE(* refIter, * tarIter) \ << "Containers " #ref " (refIter) and " #target " (tarIter)" \ " differ at index " << i; \ ++refIter; ++tarIter; ++i; \ } \ EXPECT_TRUE( tarIter == target_.end() ) \ << #ref " has a smaller length than " #target ; \ } //! Check that all elements of two same-type containers are equal #define EXPECT_ITERABLE_EQ( TYPE, ref, target) \ EXPECT_ITERABLE_BASE( EXPECT_EQ, TYPE, TYPE, ref, target ) //! Check that all elements of two different-type containers are equal #define EXPECT_ITERABLE_EQ2( REFTYPE, TARTYPE, ref, target) \ EXPECT_ITERABLE_BASE( EXPECT_EQ, REFTYPE, TARTYPE, ref, target ) //! Check that all elements of two same-type containers of doubles are equal #define EXPECT_ITERABLE_DOUBLE_EQ( TYPE, ref, target) \ EXPECT_ITERABLE_BASE( EXPECT_DOUBLE_EQ, TYPE, TYPE, ref, target )
Mam nadzieję, że to zadziała dla Ciebie (i że faktycznie sprawdzasz tę odpowiedź dwa miesiące po przesłaniu pytania).
źródło
Podobny problem napotkałem podczas porównywania tablic w teście Google .
Ponieważ potrzebowałem porównania z podstawowym
void*
ichar*
(do niskopoziomowego testowania kodu), nie wydaje mi się, że albo google mock (którego również używam w projekcie), albo świetne makro Setha może mi pomóc w konkretnej sytuacji. Napisałem następujące makro:#define EXPECT_ARRAY_EQ(TARTYPE, reference, actual, element_count) \ {\ TARTYPE* reference_ = static_cast<TARTYPE *> (reference); \ TARTYPE* actual_ = static_cast<TARTYPE *> (actual); \ for(int cmp_i = 0; cmp_i < element_count; cmp_i++ ){\ EXPECT_EQ(reference_[cmp_i], actual_[cmp_i]);\ }\ }
Rzuty są po to, aby makro było użyteczne w porównaniu
void*
z innymi rzeczami:void* retrieved = ptr->getData(); EXPECT_EQ(6, ptr->getSize()); EXPECT_ARRAY_EQ(char, "data53", retrieved, 6)
Tobias w komentarzach sugerował odlewania
void*
dochar*
i korzystaniaEXPECT_STREQ
, makro, ja jakoś brakowało wcześniej - która wygląda jak lepszej alternatywy.źródło
EXPECT_STREQ
nie działa dla dowolnych tablic, które zawierają zero elementów. Nadal głosowałbym na rozwiązanie @nietaki.Poniżej znajduje się stwierdzenie, które napisałem, aby porównać [fragmenty] dwóch tablic zmiennoprzecinkowych:
/* See http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ for thorough information about comparing floating point values. For this particular application we know that the value range is -1 to 1 (audio signal), so we can compare to absolute delta of 1/2^22 which is the smallest representable value in a 22-bit recording. */ const float FLOAT_INEQUALITY_TOLERANCE = float(1.0 / (1 << 22)); template <class T> ::testing::AssertionResult AreFloatingPointArraysEqual( const T* const expected, const T* const actual, unsigned long length) { ::testing::AssertionResult result = ::testing::AssertionFailure(); int errorsFound = 0; const char* separator = " "; for (unsigned long index = 0; index < length; index++) { if (fabs(expected[index] - actual[index]) > FLOAT_INEQUALITY_TOLERANCE) { if (errorsFound == 0) { result << "Differences found:"; } if (errorsFound < 3) { result << separator << expected[index] << " != " << actual[index] << " @ " << index; separator = ", "; } errorsFound++; } } if (errorsFound > 0) { result << separator << errorsFound << " differences in total"; return result; } return ::testing::AssertionSuccess(); }
Sposób użycia w ramach testowania Google jest następujący:
W przypadku błędu generowane jest coś podobnego do następującego:
..\MyLibraryTestMain.cpp:145: Failure Value of: AreFloatingPointArraysEqual(expectedArray, actualArray, lengthToCompare) Actual: false (Differences found: 0.86119759082794189 != 0.86119747161865234 @ 14, -0.5552707314491272 != -0.55527061223983765 @ 24, 0.047732405364513397 != 0.04773232713341713 @ 36, 339 differences in total) Expected: true
Aby uzyskać dokładną dyskusję na temat ogólnego porównywania wartości zmiennoprzecinkowych, zobacz to .
źródło
Użyłem klasycznej pętli przez wszystkie elementy. Możesz użyć SCOPED_TRACE, aby odczytać, w której iteracji różnią się elementy tablicy. Zapewnia to dodatkowe informacje w porównaniu z niektórymi innymi podejściami i jest łatwe do odczytania.
for (int idx=0; idx<ui16DataSize; idx++) { SCOPED_TRACE(idx); //write to the console in which iteration the error occurred ASSERT_EQ(array1[idx],array2[idx]); }
źródło