我正在寻找比较谷歌测试中的两个数组。在 UnitTest++ 中,这是通过 CHECK_ARRAY_EQUAL 完成的。你如何在谷歌测试中做到这一点?
10 回答
我真的建议看看Google C++ Mocking Framework。即使您不想模拟任何东西,它也允许您轻松编写相当复杂的断言。
例如
//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), _));
每种可能的情况都有很多匹配器,您可以将它们组合起来以实现几乎任何目标。
我有没有告诉过你ElementsAre
只需要iterators
和size()
方法在一个类上工作吗?所以它不仅适用于 STL 的任何容器,也适用于自定义容器。
Google Mock 声称几乎与 Google Test 一样便携,坦率地说,我不明白您为什么不使用它。这简直太棒了。
如果您只需要检查数组是否相等,那么蛮力也可以:
int arr1[10];
int arr2[10];
// initialize arr1 and arr2
EXPECT_TRUE( 0 == std::memcmp( arr1, arr2, sizeof( arr1 ) ) );
但是,这并不能告诉您哪个元素不同。
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;
}
如果您想使用 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 的 ElementsAreArray 还接受允许比较两个 c 样式数组指针的指针和长度。例如:
ASSERT_THAT(std::vector<uint8_t>(buffer, buffer + buffer_size),
::testing::ElementsAreArray(buffer, buffer_size));
我花了太长时间试图把它拼凑起来。感谢这个 StackOverflow 帖子提醒 std::vector 迭代器初始化。请注意,此方法将在比较之前将缓冲区数组元素复制到 std::vector 中。
我有完全相同的问题,所以我写了几个宏来比较两个通用容器。它可以扩展到任何具有const_iterator
、begin
和end
. 如果失败,它将显示数组出错的详细消息,并对每个失败的元素执行此操作;它将确保它们的长度相同;并且它报告为失败的代码中的位置是您调用的同一行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 )
希望这对您有用(并且您在提交问题两个月后实际上检查了此答案)。
我在比较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]);\
}\
}
void*
与其他东西比较时,演员表可以使宏可用:
void* retrieved = ptr->getData();
EXPECT_EQ(6, ptr->getSize());
EXPECT_ARRAY_EQ(char, "data53", retrieved, 6)
评论中的 Tobias 建议转换void*
为char*
并使用EXPECT_STREQ
,这是我以前不知何故错过的宏——这看起来是一个更好的选择。
我在所有元素中使用了经典循环。您可以使用 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]);
}
下面是我写的一个断言来比较两个浮点数组的[片段]:
/* 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();
}
Google 测试框架中的用法是这样的:
EXPECT_TRUE(AreFloatingPointArraysEqual(expectedArray, actualArray, lengthToCompare));
如果出现错误,将产生类似于以下输出的内容:
..\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
有关比较一般浮点值的全面讨论,请参阅 此。
我所做的是对向量进行列表初始化准备打印并比较两个字符串。
像这样的东西:
std::stringstream expected;
expected_triangles << expected_vector;
std::stringstream output;
o_triangles << output_vector;
EXPECT_EQ(o_triangles.str(), expected_triangles.str());
为此,您需要定义:
///
/// \brief operator << print a vector in a list-initialization friendly format
/// \param out
/// \param point
/// \return
///
template <typename T>
std::ostream &operator<<(std::ostream &out, std::vector<T> const &vector)
{
out << "{";
if (!vector.empty())
{
out << vector[0];
}
for (size_t i = 1; i < vector.size(); i++)
{
out << ", " << vector[i];
}
out << "}";
return out;
}
从实时数据创建测试用例也非常方便,因为您只需要记录数据,然后使用它来初始化您的测试数组。
使用今天的版本,您只需operator<<
为您的枚举类类型声明,但与枚举在同一命名空间中(请参阅https://github.com/google/googletest/blob/main/docs/advanced.md#teaching-googletest -如何打印你的价值观)
namespace Foo
{
enum class Bar
{
Hello,
Goodbye,
};
// In the same namespace !!
inline std::ostream& operator<<(std::ostream& os, const Bar& v)
{
switch (v)
{
case Bar::Hello: os << "Hello"; break;
case Bar::Goodbye: os << "Goodbye"; break;
}
return os;
}
}
TEST(Suite, Demo1)
{
using namespace Foo;
vector<Bar> vec1 = { Bar::Hello, Bar::Goodbye };
vector<Bar> vec2 = { Bar::Goodbye };
ASSERT_EQ(vec1, vec2);
}
test.cpp(106): error: Expected equality of these values:
vec1
Which is: { Hello, Goodbye }
vec2
Which is: { Goodbye }
[ FAILED ] Suite.Demo1 (1 ms)
``