谷歌testing中的数组比较?
我期待在googletesting中比较两个数组。 在UnitTest ++中,这是通过CHECK_ARRAY_EQUAL完成的。 你如何在谷歌testing中做到这一点?
我真的build议看一下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的任何容器,而且也适用于定制的容器。
谷歌Mock声称几乎像谷歌testing一样便携,坦率地说,我不明白为什么你不会使用它。 这是纯粹的真棒。
如果你只是需要检查数组是否相等,那么蛮力也可以工作:
int arr1[10]; int arr2[10]; // initialize arr1 and arr2 EXPECT_TRUE( 0 == std::memcmp( arr1, arr2, sizeof( arr1 ) ) );
但是,这并不能告诉你哪个元素不同。
如果您想使用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));
我花了太长时间试图把它拼凑在一起。 感谢这个StackOverlow的提示,关于std :: vector迭代器的初始化。 请注意,这个方法会在比较之前将缓冲区数组元素复制到std :: vector中。
我有完全相同的问题,所以我写了两个macros,比较两个通用容器之间的比较。 它可以扩展到任何有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 )
希望这对你有用(而且你在提交问题两个月之后就会检查这个答案)。
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; }
资源
我遇到了一个类似的问题,比较谷歌testing中的数组。
因为我需要与基本的void*
和char*
(用于低级代码testing)进行比较,所以我不是谷歌模拟 (我也在项目中使用)或者塞特伟大的macros可以帮助我在特定情况下。 我写了下面这个macros:
#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*
和其他东西的时候,可以使用macros来使macros成为可用的:
void* retrieved = ptr->getData(); EXPECT_EQ(6, ptr->getSize()); EXPECT_ARRAY_EQ(char, "data53", retrieved, 6)
Tobias在评论中build议将void*
为char*
并使用EXPECT_STREQ
,这是我以前错过的一个macros – 这看起来更好一些。
下面是我写的一个断言,用来比较两个浮点数组的片段:
/* 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(); }
Googletesting框架中的用法是这样的:
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
有关通常比较浮点值的详细讨论,请参阅此 。
我用了所有元素的经典循环。 您可以使用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]); }