【问题标题】:Google test compare pointer-arrays' content谷歌测试比较指针数组的内容
【发布时间】:2018-02-09 16:37:22
【问题描述】:

我是谷歌测试的新手,我发现的任何方法都没有奏效。

假设我有一个数组,然后是一个函数,它返回一个指向新数组的指针,我想比较这两个数组是否包含相同的元素。

例子:

int foo[] {1,2,3};
int* expected result = foo;
int* result = bar(foo);

//comparison
EXPECT_THAT(foo, testing::UnorderedElementsAreArray(result, 3));
//other way
EXPECT_THAT(foo, testing::ContainerEq(result));

这两种方式都不行(类似的尝试也奏效了)。

我想检查两个数组是否包含相同的元素,无论顺序如何。

我尝试了Comparison of arrays in google test? 中的方法,但都没有奏效。

“ElementsAreArray”是否是正确的比较器?

感谢您的帮助。

【问题讨论】:

  • 也许使用std::memcmp 并检查它返回的内容?
  • 这不是只有在两个数组中元素的顺序相同的情况下才有效吗?
  • 抱歉错过了那部分。那么不,你不能直接使用memcmp。调用您要测试的函数后,是否可以对任何数组进行重新排序?你能不能对它们进行排序?然后对它们进行排序并然后使用memcmp?
  • 哦该死的..这似乎是我想到的用例的有效解决方案..但是当我们这样做时,是否有更通用的解决方案?
  • 有一些 standard algorithm functions 可能会有所帮助,但如果您无法修改数组,那么您必须自己编写主要部分。

标签: c++ arrays pointers googletest gmock


【解决方案1】:

您尝试使用的 gtest 匹配器,testing::UnorderedElementsAreArraytesting::ContainerEq 仅适用于 STL 样式容器的对象。 见the documentation

您的 fooC-style arrayint。您的 expected_resultresult 是指向 int 的指针。这些都不是 STL 风格的容器, 并且指针在任何意义上都不是容器。

您要测试的问题是N 是否以expected_result 开头的整数 是从result 开始的N 整数的任何排列,其中N 是数字 数组中的元素数量foo

通过单个EXPECT... 调用测试该问题的唯一方法 是当您调用某个确切确定的函数时期望得到一个真实的结果 带有参数resultexpected_result 的问题并返回一个布尔判断(或可转换为布尔判断的东西)。

C++ 标准库(C++11 或更高版本)为此目的提供了一个通用函数:std::is_permutation, 您将按照图示应用:

#include <gtest/gtest.h>
#include <algorithm>

int * reverse(int in[], std::size_t len)
{
    int * permute = new int[len];
    std::reverse_copy(in,in + len,permute);
    return permute;
}

TEST(reverse,is_correct)
{
    int foo[] {1,2,3};
    int* expected_result = foo;
    std::size_t len = sizeof(foo)/sizeof(foo[0]);
    int* result = reverse(foo,len);
    EXPECT_TRUE(std::is_permutation(result,result + len,expected_result));
    delete [] result;
}

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

输出:

[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from reverse
[ RUN      ] reverse.is_correct
[       OK ] reverse.is_correct (0 sec)
[----------] 1 test from reverse (0 sec total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 1 test.

请注意,使用 C 风格的数组要求您通过以下方式管理堆内存 手:

    int * permute = new int[len];
    ...
    ...
    delete [] result

这在 C++ 中是对堆泄漏或堆损坏的无故邀请 错误。对于固定大小的数组,请使用std::array。 对于动态大小的数组,请使用std::vector。 这样更好:

#include <gtest/gtest.h>
#include <algorithm>
#include <array>

template<std::size_t N>
std::array<int,N> reverse(std::array<int,N> const & in)
{
    std::array<int,N> permute;
    std::reverse_copy(in.begin(),in.end(),permute.begin());
    return permute;
}

TEST(reverse,is_correct)
{
    std::array<int,3> foo {1,2,3};
    auto result = reverse(foo);
    EXPECT_TRUE(std::is_permutation(result.begin(),result.end(),foo.begin()));
}

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

而且,由于 std::arraystd::vector STL 风格的容器,你的 如果您使用其中任何一种,最初的尝试都会奏效:

#include <gmock/gmock.h>
#include <algorithm>
#include <array>

template<std::size_t N>
std::array<int,N> reverse(std::array<int,N> const & in)
{
    std::array<int,N> permute;
    std::reverse_copy(in.begin(),in.end(),permute.begin());
    return permute;
}

TEST(reverse,is_correct)
{
    std::array<int,3> foo {1,2,3};
    auto result = reverse(foo);
    EXPECT_THAT(foo,testing::UnorderedElementsAreArray(result));
}

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

【讨论】:

  • 谢谢你。这很棒,正是我想要的。所以我可以将我的指针包装到 STL 容器中,或者使用其他函数来比较它们。澄清一下,我在处理 GPU (CUDA) 上的动态大小数组并想要测试结果时使用了指针。
猜你喜欢
  • 2010-11-30
  • 1970-01-01
  • 2019-09-13
  • 2012-10-05
  • 2014-02-22
  • 2017-01-19
  • 1970-01-01
相关资源
最近更新 更多