Tôi đang tìm cách so sánh hai mảng trong thử nghiệm của Google. Trong UnitTest ++, điều này được thực hiện thông qua CHECK_ARRAY_EQUAL. Làm thế nào để bạn làm điều đó trong thử nghiệm google?
Tôi đang tìm cách so sánh hai mảng trong thử nghiệm của Google. Trong UnitTest ++, điều này được thực hiện thông qua CHECK_ARRAY_EQUAL. Làm thế nào để bạn làm điều đó trong thử nghiệm google?
Câu trả lời:
Tôi thực sự khuyên bạn nên xem Google C ++ Mocking Framework . Ngay cả khi bạn không muốn chế nhạo bất cứ điều gì, nó cho phép bạn viết các xác nhận khá phức tạp một cách dễ dàng.
Ví dụ
//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), _));
Có rất nhiều công cụ phù hợp cho mọi tình huống có thể xảy ra và bạn có thể kết hợp chúng để đạt được hầu hết mọi thứ.
Tôi đã nói với bạn rằng ElementsAre
chỉ cần iterators
và size()
phương thức trên một lớp để hoạt động? Vì vậy, nó không chỉ hoạt động với bất kỳ vùng chứa nào từ STL mà còn với các vùng chứa tùy chỉnh.
Google Mock tuyên bố gần như di động như Google Test và thành thật mà nói, tôi không hiểu tại sao bạn không sử dụng nó. Nó chỉ hoàn toàn là tuyệt vời.
ElementsAreArray
tốt hơn là so sánh các mảng, vì ElementsAre
có giới hạn 10 phần tử.
testing::Matcher<std::string const&>::Matcher(char const*)
không được định nghĩa
EXPECT_THAT(v, ElementsAreArray(u));
mà tôi đã sử dụng nhiều hơn các ví dụ hiện tại.
Nếu bạn muốn so sánh con trỏ mảng kiểu c với một mảng bằng Google Mock, bạn có thể đi qua std :: vector. Ví dụ:
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 cũng chấp nhận con trỏ và độ dài cho phép so sánh hai con trỏ mảng kiểu c. Ví dụ:
ASSERT_THAT(std::vector<uint8_t>(buffer, buffer + buffer_size),
::testing::ElementsAreArray(buffer, buffer_size));
Tôi đã mất quá nhiều thời gian để cố gắng ghép nối điều này lại với nhau. Cảm ơn bài đăng StackOverflow này cho lời nhắc về khởi tạo trình lặp vectơ std ::. Lưu ý rằng phương thức này sẽ sao chép các phần tử mảng đệm vào vector std :: trước khi so sánh.
buffer_size
, giá trị được trả về từ mã đang được kiểm tra, được đặt không chính xác (size_t)-1
, đây không phải là một lỗi phổ biến, thì phương thức tạo vectơ sẽ cố gắng tạo ra một vectơ rất lớn! Chương trình thử nghiệm có thể bị giết do giới hạn tài nguyên hoặc lỗi hết bộ nhớ, hoặc chỉ là sự cố đơn thuần, chứ không phải là xác nhận thử nghiệm không thành công. Với C ++ 20, việc sử dụng std::span
thay vì vectơ sẽ ngăn chặn điều này, vì nó không cần sao chép bộ đệm vào một vùng chứa mới.
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;
}
Tôi đã có cùng một câu hỏi, vì vậy tôi đã viết một vài macro để so sánh giữa hai vùng chứa chung. Đó là mở rộng để chứa bất kỳ mà có const_iterator
, begin
và end
. Nếu không thành công, nó sẽ hiển thị một thông báo chi tiết về vị trí mảng bị lỗi và sẽ thực hiện như vậy cho mọi phần tử bị lỗi; nó sẽ đảm bảo rằng chúng có cùng chiều dài; và vị trí trong mã của bạn mà nó báo cáo là không thành công là cùng một dòng nơi bạn gọi 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 )
Hy vọng điều này hiệu quả với bạn (và bạn thực sự kiểm tra câu trả lời này hai tháng sau khi câu hỏi của bạn được gửi).
Tôi đã gặp phải một vấn đề tương tự khi so sánh các mảng trong thử nghiệm của Google .
Vì tôi cần so sánh với cơ bản void*
và char*
(để kiểm tra mã cấp thấp), tôi không nghĩ rằng google mock (mà tôi cũng đang sử dụng trong dự án) hoặc macro tuyệt vời của Seth có thể giúp tôi trong tình huống cụ thể. Tôi đã viết macro sau:
#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]);\
}\
}
Các phôi ở đó để làm cho macro có thể sử dụng được khi so sánh void*
với những thứ khác:
void* retrieved = ptr->getData();
EXPECT_EQ(6, ptr->getSize());
EXPECT_ARRAY_EQ(char, "data53", retrieved, 6)
Tobias trong các nhận xét đã đề xuất truyền void*
đến char*
và sử dụng EXPECT_STREQ
, một macro mà tôi đã bỏ qua bằng cách nào đó trước đây - có vẻ như một sự thay thế tốt hơn.
EXPECT_STREQ
không hoạt động đối với các mảng tùy ý chứa không phần tử. Tôi vẫn bỏ phiếu cho giải pháp của @nietaki.
Dưới đây là khẳng định tôi đã viết để so sánh [các đoạn của] hai mảng dấu phẩy động:
/* 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();
}
Cách sử dụng trong Khung thử nghiệm của Google là:
EXPECT_TRUE(AreFloatingPointArraysEqual(expectedArray, actualArray, lengthToCompare));
Trong trường hợp xảy ra lỗi, kết quả giống như sau sẽ được tạo ra:
..\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
Để thảo luận kỹ lưỡng về việc so sánh các giá trị dấu phẩy động nói chung, vui lòng xem phần này .
Tôi đã sử dụng một vòng lặp cổ điển qua tất cả các phần tử. Bạn có thể sử dụng SCOPED_TRACE để đọc ra các phần tử của mảng khác nhau trong lần lặp nào. Điều này cung cấp cho bạn thông tin bổ sung so với một số cách tiếp cận khác và rất dễ đọc.
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]);
}