我试图找出,在CUnit中断言数组相等的最佳方法是什么。
我知道的documentation根本不包含任何与数组相关的内容。
到目前为止我考虑过的可能性:
循环遍历数组元素并使用CU_ASSERT_EQUAL
逐个检查。
只需在两个阵列上使用CU_ASSERT_EQUAL
即可。根据上述文档,这不应该有效,因为CU_ASSERT_EQUAL
只是转换为==
。实际上,以下测试会导致失败:
const uchar arr1[] = {1,2};
const uchar arr2[] = {1,2};
CU_ASSERT_EQUAL(arr1, arr2);
CU_ASSERT_NSTRING_EQUAL
似乎有效,但名称暗示它适用于字符串: const uchar arr1[] = {1,2};
const uchar arr2[] = {1,2};
CU_ASSERT_NSTRING_EQUAL(arr1, arr2, 2); /* succeeds: OK */
const uchar arr1[] = {1,3};
const uchar arr2[] = {1,2};
CU_ASSERT_NSTRING_EQUAL(arr1, arr2, 2); /* fails: OK */
我最倾向于使用CU_ASSERT_NSTRING_EQUAL
。
所以问题如下:
CU_ASSERT_NSTRING_EQUAL
的解决方案是否有任何缺点,除了(略微)误导性的名称? (我知道字符串只是数组,由\0
终止。)注意:在我能找到的相关question / answer中,还建议迭代元素(虽然我认为这不是我的问题的重复,因为它没有直接询问一般检查数组是否相等的最佳方法是什么。)
答案 0 :(得分:2)
我迟到了这个答案但是......
我在与数组相关的文档中找不到任何内容。这似乎是一个缺失的功能。但是你可以使用:
CU_ASSERT_EQUAL(0, memcmp(actual, expected, count));
在你的例子中,它将是:
CU_ASSERT_EQUAL(0, memcmp(arr1, arr2, 2));
答案 1 :(得分:1)
忽略名称中有STRING
并使用CU_ASSERT_NSTRING_EQUAL(actual, expected, count)的事实。特别是在您的情况下,断言可能是
//Assert that the arrays are the same size.
//If not, they can't have deep equality.
CU_ASSERT_EQUAL(sizeof(arr1), sizeof(arr2));
//Now assert byte-by-byte equality
//for the size of both arrays
CU_ASSERT_NSTRING_EQUAL(arr1, arr2, sizeof(arr1));
查看文档,您可以看到CU_ASSERT_NSTRING_EQUAL的语义含义是"断言实际和预期的第一个计数字符是相同的。" 回想一下{ {1}}只是内存中的一个字节。尽管您将char
到&arr1
的字节解释为无符号字符,但字符串比较是通过逐个递增字符并检查其字节值来完成的。对于&arr + (1 * sizeof(uchar))
,这会发生,直到遇到空字节,因为它是如何终止字符串的。对于CU_ASSERT_STRING_EQUAL(actual, expected)
,传递大小是因为您要检查CU_ASSERT_NSTRING_EQUAL(actual, expected, count)
- 字节,无论是否遇到空字节。数组中的类型可能大于count
,但它并不重要。在下面,它们仍然只是连续位于内存中的固定数量的字节。
请注意,这只有在您可以告诉单元测试框架要检查的对象大小时才有效。这需要使用char
检查对象,或者知道对象的大小并指向对象(回想一下sizeof()
指针总是相同的,无论指向的对象的大小如何-至)。对于动态大小的对象,这可能是不可能的。
也许。但是你需要对每个索引都有一个断言。同样,只有在编译时知道数组的大小(例如,由sizeof()
获取并且位于堆上的数组在编译时将具有未知大小的数组时,这才会起作用,因此for循环malloc
断言赢得了工作)。在你的情况下,这就是这样的事情
CU_ASSERT_EQUAL
问题是你的套件很快就会被大型阵列的断言所填充。您不想知道数组中的每个元素并不匹配...您想知道数组中的任何元素并且# 39; t匹配。一旦//Assert that the arrays are the same size
//If not, they can't have deep equality.
CU_ASSERT_EQUAL(sizeof(arr1), sizeof(arr2));
//Now assert index-by-index equality
for (size_t i=0; i < sizeof(arr1) / sizeof(uchar); i++)
CU_ASSERT_EQUAL(arr1[i], arr2[i]);
发现不匹配,测试就会失败。对于CU_ASSERT_NSTRING_EQUAL
断言的循环,情况并非如此。由于CUnit断言是作为宏实现的,因此没有要检查的返回值,以便您可以突破循环。即使你进行了单独的非断言比较,你仍然会留下在第一个非匹配索引之前完成的断言的痕迹。