2012-04-08 4 views
5

Przeczytałem this official document, nauczyłem się, jak wykonać Porównanie binarne i Porównanie ciągów.W jaki sposób program gtest porównuje wartości w dwóch tablicach?

ASSERT_EQ i ASSERT_STREQ nie mogły działać w przypadku porównania tablic.

Przykładowo

[email protected]:~/poc$ g++ -I${GTEST_DIR}/include insertion_sort.cpp insertion_sort_unittest.cpp /home/li/libgtest.a -lpthread -o inser_unit 
[email protected]:~/poc$ ./inser_unit 
[==========] Running 1 test from 1 test case. 
[----------] Global test environment set-up. 
[----------] 1 test from InsertionSortTest 
[ RUN  ] InsertionSortTest.Two 
insertion_sort_unittest.cpp:18: Failure 
Value of: two_sorted 
    Actual: { 2, 5 } 
Expected: two 
Which is: { 2, 5 } 
[ FAILED ] InsertionSortTest.Two (1 ms) 
[----------] 1 test from InsertionSortTest (1 ms total) 

[----------] Global test environment tear-down 
[==========] 1 test from 1 test case ran. (1 ms total) 
[ PASSED ] 0 tests. 
[ FAILED ] 1 test, listed below: 
[ FAILED ] InsertionSortTest.Two 

1 FAILED TEST 

insertion_sort_unittest.cpp

#include <limits.h> 
#include "insertionsort.h" 
#include "gtest/gtest.h" 

namespace{ 
    class InsertionSortTest : public ::testing::Test{ 
     protected: 
      InsertionSortTest() {} 
      virtual ~InsertionSortTest() {} 
      virtual void SetUp() {} 
      virtual void TearDown() {} 
    }; 

    TEST(InsertionSortTest, Two){ 
     int two[] = {5, 2}; 
     int two_sorted[] = {2, 5}; 
     insertionSort(two, 2); 
     EXPECT_EQ(two, two_sorted); 
    } 
} 

int main(int argc, char **argv){ 
    ::testing::InitGoogleTest(&argc, argv); 
    return RUN_ALL_TESTS(); 
} 

insertion_sort.cpp

#include "insertionsort.h" 
void insertionSort(int *data, int size){ 
    for (int i=1,j; i<size; i++){ 
     int key = data[i]; 
     for (j=i-1; j>=0; j--){ 
      if (data[j] > key){ 
       data[j+1]=data[j]; 
       data[j]=key; 
      } 
     } 
    } 
} 

insertionsort.h

#ifndef INSERTIONSORT_H_ 
#define INSERTIONSORT_H_ 
void insertionSort(int *data, int size); 
#endif 
+2

Może powinienem nauczyć się korzystać googlemock, znalazłem odpowiedź [tutaj] (http://stackoverflow.com/questions/1460703/comparison-of-arrays-in-google-test) i [tutaj] (http://code.google.com/p/googletest/issues/detail?id=231) – liweijian

Odpowiedz

13

Nie musisz dodawać zależności od googlemock, jeśli nie chcesz, możesz napisać własną prostą funkcję, która zwraca testing::AssertionResult, np.

template<typename T, size_t size> 
    ::testing::AssertionResult ArraysMatch(const T (&expected)[size], 
              const T (&actual)[size]){ 
     for (size_t i(0); i < size; ++i){ 
      if (expected[i] != actual[i]){ 
       return ::testing::AssertionFailure() << "array[" << i 
        << "] (" << actual[i] << ") != expected[" << i 
        << "] (" << expected[i] << ")"; 
      } 
     } 

     return ::testing::AssertionSuccess(); 
    } 

Następnie w teście, zadzwoń:

EXPECT_TRUE(ArraysMatch(two_sorted, two)); 
+0

Dzięki Fraser, bardzo mi pomagasz :) – liweijian

6

ASSERT_EQ porównuje swoje argumenty za pomocą operator==. W porównaniu z operator== działa dla std::vector, ale nie dla tablic C w C++. Powodem jest to, że przy próbie użycia wartości tablicy C w wyrażeniu, w większości przypadków wartość znika w wskaźnik wskazujący początek pamięci, w której przechowywana jest tablica. W końcu porównujesz dwa wskaźniki. W przypadku dwóch różnych tablic C wskaźniki te nigdy nie będą miały tej samej wartości.

Najłatwiejszym wyjściem jest użycie makra Google Mock: ASSERT_THAT i ContainerEq matchera. Zamiast ASSERT_EQ napisz

ASSERT_THAT(two, ContainerEq(two_sorted)); 
+0

Po prostu wyjaśnij - to nadal nie działa na C tablice, prawda? ponieważ nie ma gdzie przesłać długości tablicy (ów)? – dwanderson

+0

Ma - patrz https://github.com/google/googletest/blob/786564fa4a3c8e0f908acca32cce481de5481b9f/googlemock/test/gmock-matchers_test.cc#L4311. – VladLosev

+0

Och, nie ma mowy! Mógłbym przysiąc, że go wypróbowałem, ale będę musiał dwukrotnie sprawdzić. Może po prostu założyłem, że to nie zadziała. Dzięki za wskazanie tego! – dwanderson

1

Myślę, że wystarczy napisać tak samo.

EXPECT_EQ(memcmp(two, two_sorted, 2 * sizeof(int)), 0);

+0

wyjaśnić, dlaczego twoja odpowiedź działa? –