谷歌测试中阵列的比较?

Tob*_*olm 70 c++ unit-testing googletest

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

vav*_*ava 103

我真的建议看看谷歌C++模拟框架.即使你不想模仿任何东西,它也允许你轻松地编写相当复杂的断言.

例如

//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), _));
Run Code Online (Sandbox Code Playgroud)

对于每种可能的情况都有很多匹配器,你可以将它们组合起来以实现几乎任何东西.

我有没有告诉过你,ElementsAre只需要iteratorssize()方法上的一类工作?所以它不仅适用于STL的任何容器,也适用于自定义容器.

谷歌模拟声称几乎像谷歌测试一样便携,坦率地说,我不明白为什么你不会使用它.这真是太棒了.

  • 我确实使用谷歌模拟.我同意这很棒.我从没想过会为C++看到类似的东西. (7认同)
  • `ElementsAreArray`更适合比较数组,因为`ElementsAre`的限制为10个元素. (2认同)
  • 请注意,您可能希望在测试中使用EXPECT_THAT而不是ASSERT_THAT. (2认同)

小智 18

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;
}
Run Code Online (Sandbox Code Playgroud)

来源

  • 我有点喜欢这个 它不需要将数据复制到 stl 容器,而且相当简单。将其包装在宏中以进行常见类型的数组比较(如向量或矩阵),很容易完成并完成工作。 (3认同)

BЈо*_*вић 16

如果你只需要检查数组是否相等,那么强力也可以:

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

// initialize arr1 and arr2

EXPECT_TRUE( 0 == std::memcmp( arr1, arr2, sizeof( arr1 ) ) );
Run Code Online (Sandbox Code Playgroud)

但是,这并不能告诉您哪个元素有所不同.

  • 嗯,知道差异就是重点. (3认同)

Mat*_*rty 13

如果你想使用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));
Run Code Online (Sandbox Code Playgroud)

Google Mock的ElementsAreArray也接受指针和长度,允许比较两个c风格的数组指针.例如:

ASSERT_THAT(std::vector<uint8_t>(buffer, buffer + buffer_size), 
            ::testing::ElementsAreArray(buffer, buffer_size));
Run Code Online (Sandbox Code Playgroud)

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


Set*_*son 9

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

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

  • 他们说(http://code.google.com/p/googletest/issues/detail?id=231)他们不鼓励添加宏,并且该功能在某种程度上在Google Mock框架中可用。 (2认同)

nie*_*aki 5

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

由于我需要与基本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]);\
    }\
    }
Run Code Online (Sandbox Code Playgroud)

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

  void* retrieved = ptr->getData();
  EXPECT_EQ(6, ptr->getSize());
  EXPECT_ARRAY_EQ(char, "data53", retrieved, 6)
Run Code Online (Sandbox Code Playgroud)

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

  • 我更喜欢将 void* 转换为 char* 并使用 EXPECT_STREQ。那也不行吗? (2认同)

小智 5

我在所有元素中使用了经典循环。您可以使用 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]);
}
Run Code Online (Sandbox Code Playgroud)