C++ 谷歌测试中数组的比较?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1460703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:04:05  来源:igfitidea点击:

Comparison of arrays in google test?

c++unit-testinggoogletest

提问by Tobias Furuholm

I am looking to compare two arrays in google test. In UnitTest++ this is done through CHECK_ARRAY_EQUAL. How do you do it in google test?

我想在谷歌测试中比较两个数组。在 UnitTest++ 中,这是通过 CHECK_ARRAY_EQUAL 完成的。你如何在谷歌测试中做到这一点?

回答by vava

I would really suggest looking at Google C++ Mocking Framework. Even if you don't want to mock anything, it allows you to write rather complicated assertions with ease.

我真的建议看看Google C++ Mocking Framework。即使您不想模拟任何内容,它也允许您轻松编写相当复杂的断言。

For example

例如

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

There's plenty of matchersfor every possible situations, and you can combine them to achieve almost anything.

每种可能的情况都有很多匹配器,您可以将它们组合起来实现几乎任何事情。

Did I tell you that ElementsAreneeds only iteratorsand size()method on a class to work? So it not only works with any container from STL but with custom containers also.

我告诉你,ElementsAre只需要iteratorssize()方法上的一类工作?因此,它不仅适用于 STL 中的任何容器,还适用于自定义容器。

Google Mock claims to be almost as portable as Google Test and frankly I don't see why you wouldn't use it. It is just purely awesome.

Google Mock 声称几乎和 Google Test 一样便携,坦率地说,我不明白你为什么不使用它。这简直太棒了。

回答by B?ови?

If you just need to check if the arrays are equal, then the brute force also works :

如果您只需要检查数组是否相等,那么蛮力也有效:

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

// initialize arr1 and arr2

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

However, this doesn't tell you which element differs.

但是,这并不能告诉您哪个元素不同。

回答by Matt Liberty

If you want to compare a c-style array pointer to an array using Google Mock, you can go through std::vector. For example:

如果要使用 Google Mock 将 c 样式的数组指针与数组进行比较,可以通过 std::vector。例如:

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 also accepts pointer and length which allow comparison of two c-style array pointers. For example:

Google Mock 的 ElementsAreArray 也接受允许比较两个 c 样式数组指针的指针和长度。例如:

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

I spent far too long trying to piece this together. Thanks to this StackOverlow postfor the reminder on std::vector iterator initialization. Note that this method will copy the buffer array elements into the std::vector before the comparison.

我花了太长时间试图将其拼凑起来。感谢这篇 StackOverlow 帖子对 std::vector 迭代器初始化的提醒。请注意,此方法将在比较之前将缓冲区数组元素复制到 std::vector 中。

回答by Николай Русскин

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

来源

回答by Seth Johnson

I had the exact same question, so I wrote a couple of macros that do comparisons between two generic containers. It's extensible to ANY container that has const_iterator, begin, and end. If it fails, it will display a verbose message of where the array went wrong and will do so for every element that fails; it will make sure they're the same length; and the location in your code that it reports as failing is the same line where you call EXPECT_ITERABLE_EQ( std::vector< double >, a, b).

我有完全相同的问题,所以我写了几个宏来比较两个通用容器。它是可扩展到具有任何容器const_iteratorbeginend。如果失败,它将显示一个详细的消息,指出数组出错的地方,并对每个失败的元素执行此操作;它将确保它们的长度相同;并且您的代码中报告为失败的位置与您调用EXPECT_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 )

Hope this works for you (and that you actually check this answer two months after your question was submitted).

希望这对您有用(并且您在提交问题两个月后实际检查了此答案)。

回答by nietaki

I ran into a similar problem with comparing arrays in google test.

我在比较google test 中的数组时遇到了类似的问题。

Since I needed comparison with basic void*and char*(for low-level code testing), I don't thing either google mock(which I'm also using in the project) or Seth's great macro could help me in the particular situation. I wrote the following macro:

由于我需要与基本void*char*(用于低级代码测试)进行比较,我不认为google mock(我也在项目中使用)或 Seth 的伟大宏可以在特定情况下帮助我。我写了以下宏:

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

The casts are there to make the macro usable when comparing void*to other stuff:

void*与其他东西相比,演员表可以使宏可用:

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

Tobias in the comments suggested casting void*to char*and using EXPECT_STREQ, a macro I somehow missed before - which looks like a better alternative.

Tobias 在评论中建议转换void*char*并使用EXPECT_STREQ,这是我之前不知怎么错过的一个宏 - 这看起来是一个更好的选择。

回答by astraujums

Below is an assertion I wrote to compare [fragments of] two floating point arrays:

下面是我为比较两个浮点数组的[片段]而写的断言:

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

Usage within the Google Testing Framework is this:

Google 测试框架中的用法是这样的:

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

In case of an error, something like the following output is produced:

如果出现错误,则会产生类似于以下输出的内容:

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

For thorough discussion on comparing floating point values in general, please see this.

有关一般比较浮点值的深入讨论,请参阅

回答by Wintermute

I used a classic loop through all elements. You can use SCOPED_TRACE to read out in which iteration the array elements differ. This provides you with additional information compared to some other approaches and is easy to read.

我在所有元素中使用了经典循环。您可以使用 SCOPED_TRACE 读出数组元素在哪个迭代中不同。与其他一些方法相比,这为您提供了更多信息,并且易于阅读。

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