CUnit断言两个数组相等

时间:2016-11-07 21:06:06

标签: c arrays cunit

我试图找出,在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中,还建议迭代元素(虽然我认为这不是我的问题的重复,因为它没有直接询问一般检查数组是否相等的最佳方法是什么。)

2 个答案:

答案 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断言是作为宏实现的,因此没有要检查的返回值,以便您可以突破循环。即使你进行了单独的非断言比较,你仍然会留下在第一个非匹配索引之前完成的断言的痕迹。