2009-09-22 13 views

Antwort

72

Ich würde wirklich vorschlagen, Google C++ Mocking Framework zu betrachten. Selbst wenn Sie nichts vortäuschen wollen, können Sie ziemlich komplizierte Behauptungen mit Leichtigkeit schreiben.

Zum Beispiel

//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), _)); 

Es gibt viele matchers für alle möglichen Situationen, und Sie können sie kombinieren fast alles zu erreichen.

Habe ich Ihnen gesagt, dass ElementsAre braucht nur iterators und size() Methode auf eine Klasse zu arbeiten? Es funktioniert also nicht nur mit einem Container von STL, sondern auch mit eigenen Containern.

Google Mock behauptet fast so portabel wie Google Test zu sein und ehrlich gesagt sehe ich nicht, warum Sie es nicht verwenden würden. Es ist einfach nur genial.

+6

Ich benutze Google Mock. Und ich stimme zu, dass es großartig ist. Ich hätte nie erwartet, etwas ähnliches für C++ zu sehen. –

+1

"rein genial" lol Ich werde es auch ausprobieren –

+2

'ElementsAreArray' ist besser Arrays zu vergleichen, da 'ElementsAre' eine Grenze von 10 Elementen hat. –

9

Ich hatte genau die gleiche Frage, also schrieb ich ein paar Makros, die Vergleiche zwischen zwei generischen Containern machen. Es ist erweiterbar für jeden Container, der const_iterator, begin und end hat. Wenn es fehlschlägt, zeigt es eine ausführliche Nachricht an, wo das Array falsch gelaufen ist und wird dies für jedes Element tun, das fehlschlägt; es wird sicherstellen, dass sie gleich lang sind; und der Ort in Ihrem Code, der als fehlgeschlagen gemeldet wird, ist dieselbe Zeile, in der Sie EXPECT_ITERABLE_EQ(std::vector<double>, a, b) aufrufen.

Hoffen, dass dies für Sie funktioniert (und dass Sie diese Antwort tatsächlich zwei Monate nach dem Einreichen Ihrer Frage überprüfen).

+0

Das ist ein großer Ansatz ist! Vielleicht könntest du das googlen, damit sie es zum Framework hinzufügen? –

+1

Sie sagten (http://code.google.com/p/googletest/issues/detail?id=231), dass sie das Hinzufügen von Makros ablehnen, und diese Funktionalität ist in gewissem Umfang im Google Mock-Framework verfügbar. –

4

Ich stieß auf ein ähnliches Problem mit dem Vergleich von Arrays in google test.

Da ich brauchte Vergleich mit grundlegenden void* und char* (für Low-Level-Code Prüfung), weiß ich nicht, was entweder google Mock oder Seths große Makro (die ich auch im Projekt verwendet wird) könnten mir helfen in der besonderen Situation. Ich schrieb das folgende 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]);\ 
    }\ 
    } 

Die Modelle gibt es das Makro machen verwendbar, wenn void* auf andere Sachen zu vergleichen:

void* retrieved = ptr->getData(); 
    EXPECT_EQ(6, ptr->getSize()); 
    EXPECT_ARRAY_EQ(char, "data53", retrieved, 6) 

Tobias in den Kommentaren vorschlug void* zu char* Gießen und mit EXPECT_STREQ, ein Makro habe ich irgendwie verpasst - das sieht nach einer besseren Alternative aus.

+2

Ich würde es vorziehen, die void * zu einem char * und mit EXPECT_STREQ zu werfen. Würde das nicht auch funktionieren? –

+0

Einer der Gründe, warum ich meine Antwort veröffentlicht habe, war, dass ich hoffte, dass jemand eine bessere Alternative vorschlagen würde. Es scheint, dass Sie es getan haben, Tobias :) – nietaki

+0

Ich bin froh, dass ich helfen konnte :) –

3

Im Folgenden finden Sie eine Behauptung I [Fragmente] zwei Gleitkomma-Arrays zu vergleichen schrieb:

/* 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(); 
} 

Verwendung im Google Testing-Framework ist das:

EXPECT_TRUE(AreFloatingPointArraysEqual(expectedArray, actualArray, lengthToCompare)); 

Im Falle eines Fehlers, etwas wie die folgende Ausgabe wird produziert:

..\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 

Für eine gründliche Diskussion über den Vergleich Floati ng Punktwerte im Allgemeinen, siehe this.

12

Wenn Sie müssen nur prüfen, ob die Arrays gleich sind, dann wird die Brute-Force arbeitet auch:

int arr1[10]; 
int arr2[10]; 

// initialize arr1 and arr2 

EXPECT_TRUE(0 == std::memcmp(arr1, arr2, sizeof(arr1))); 

Doch diese Ihnen nicht sagen, welches Element unterscheidet.

+3

Nun, den Unterschied zu kennen, ist irgendwie der Punkt. – filmil

11

Wenn Sie einen Array-Zeiger im C-Stil mit Google Mock mit einem Array vergleichen möchten, können Sie std :: vector verwenden. Zum Beispiel:

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 Mocks ElementsAreArray akzeptiert auch Zeiger und Länge, die einen Vergleich von zwei c-Stil Array Zeiger erlauben. Zum Beispiel:

ASSERT_THAT(std::vector<uint8_t>(buffer, buffer + buffer_size), 
      ::testing::ElementsAreArray(buffer, buffer_size)); 

Ich verbrachte viel zu lange versucht, dies zusammen zu setzen. Danke an this StackOverlow post für die Erinnerung auf std :: Vektor-Iterator-Initialisierung. Beachten Sie, dass diese Methode die Puffer-Array-Elemente vor dem Vergleich in den std :: vector kopiert.

+0

Du bist mein Held! – slaadvak

2

Ich verwendete eine klassische Schleife durch alle Elemente. Mit SCOPED_TRACE können Sie auslesen, in welcher Iteration sich die Array-Elemente unterscheiden. Dies bietet Ihnen gegenüber anderen Ansätzen zusätzliche Informationen und ist leicht zu lesen.

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]); 
} 
4
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; 
} 

Source

+0

Ich mag das irgendwie. Es erfordert nicht das Kopieren der Daten in einen STL-Container, und es ist einfach ziemlich einfach. Das in einem Makro für einen üblichen Arrayvergleich (wie einen Vektor oder eine Matrix) zu verpacken, ist einfach erledigt und erledigt den Job. – johnb003