译者注:译者博客(http://blog.csdn.net/lin_strong),转载请保留这条。此为Unity手册的翻译,仅供学习交流使用,请勿用于商业用途。
翻译的资料是公开的,在docs/UnityAssertionsReference.md,我想应该不会有什么版权问题,如涉及版权问题,请联系我删除文章。
一个思考Unity的简单方式是把它想成一个丰富的断言集合,你可以用这个集合来约束你的
源码按照你想的方式工作。Unity提供了一个框架,你可以使用其以简单地组织和执行那些
在测试代码中的断言,断言与源码是分离的。
在它们的核心,断言是真理的一个确立 - 逻辑真理。这个东西和那个相等吗?这段精妙的代码
有这样的特性么?你明白了。断言是可执行的代码(看看这个大图以阅读差别)。一个失败的断言
会停止执行并通过一些合适的I/O口报告一个错误(例如:stdout、GUI、文件、闪灯)
基本上,想要动态验证的话,你唯一需要的就是单个断言机制。事实上,那就是C标准库中assert()宏
做的事。所以,为什么不干脆就用它算了?好吧,我们在报告上可以做的好的多。C的assert()
原本就很哑巴,并且特别处理不来普通数据类型如数组、数据结构等。并且,如果没有一些其他
支持,往C垃圾源码中扔一堆assert()
实在太诱人了。按照Unity的方式把测试和源码分开通常
会更加干净、更易于管理以及更有用。
断言一个简单的真相条件是有价值的,但是使用断言的上下文更有价值。比如,如果你知道
你在比较标志位而不是整数,那么为什么不使用那上下文以在一个断言失败时给予精准、可
读、位等级的反馈呢?
那就是Unity的断言集合做的事 - 捕获上下文以给你有用且有意义的断言失败信息。事实上,
断言本身也是可执行的文档,关于你源码中类型和值的文档。只要你的测试和你的源码保持
同步,并且所有的测试都能通过,你就有了你源码的一个详细且最新的目的与机制视图。并且
由于一个奇妙的秘密,良好测试的代码通常趋于良好的设计。
断言的参数约定通常遵循这个顺序:
TEST_ASSERT_X( {modifiers}, {expected}, actual, {size/count} )
很简单的断言可能只使用单个"actual"参数(比如一个简单的null检查)。
"Actual"是被测试的值,不像断言结构中的其他参数,它是唯一会出现在所有断言变体中的参数。
"Modifiers"是掩码、范围、标志位说明符、浮点位。
"Expected"是你期望的(emmm)与"actual"值进行比较的值;它被标记为可选参数是因为一些断言
仅仅需要单个"actual"参数(比如null检查)。
"Size/count"指的是如字符串长度、数组长度。
Unity的许多断言有明显的重复,同个数据类型许多断言都能处理。区别是失败信息的样子。
比如,一条断言的_HEX
变体会将这条断言的期望值与真实值打印为十六进制格式。
所有 断言都有一个把简单字符串信息作为最终参数的变体。你指定的字符串会在Unity输出
中被附加到断言失败信息中。
为了简明起见,带有一个消息参数的断言变体不会列在下面。只需要附加_MESSAGE
到下面参考
列表中任意断言名的后面并添加一个字符串作为最终参数就行。
示例:
TEST_ASSERT_X( {modifiers}, {expected}, actual, {size/count} )
消息化后就像这样…
TEST_ASSERT_X_MESSAGE( {modifiers}, {expected}, actual, {size/count}, message )
注意:
_MESSAGE
变体故意不支持printf
风格的格式化,因为许多嵌入式项目因多种原因不支持或printf
。如果需要的话,可以在断言前使用sprintf来组装一个复杂的失败消息。_ARRAY
断言(见以下)可能就能有效避免使用sprintf
。Unity为多种类型的数组提供了一个断言集合。下面是数组部分的文档。它和_MESSAGE
变体很像
,对于Unity中很多类型的断言你同样只要在名字后面加上_ARRAY
就能在整块内存上运行断言了。
TEST_ASSERT_EQUAL_TYPEX_ARRAY( expected, actual, {size/count} )
"Expected"是一个数组本身。
"Size/count"是一或两个指定数组元素个数的必要参数也可能是数组中元素的长度。
注意:
_MESSAGE
变体的约定仍能作用于array断言上。_ARRAY
断言的_MESSAGE
变体的名字_ARRAY_MESSAGE
结尾的。Unity为多种类型的数组提供了一个断言集合,同样可以只比较单个值。下面是Each Equal部分的
文档。它和_MESSAGE
变体很像,对于Unity中很多类型的断言你只要在名字中注入_EACH_EQUAL
就能在整块内存上运行断言了。
TEST_ASSERT_EACH_EQUAL_TYPEX( expected, actual, {size/count} )
"Expected"是要比较的单个值
"Actual"是一个数组,其中的每个元素都会与期望值比较。
"Size/count"是一或两个指定数组元素个数的必要参数也可能是数组中元素的长度。
注意:
_MESSAGE
变体的约定仍能作用于Each Equal断言上。对浮点数类型的支持是可配置的。这是说,通过定义合适的预处理器符号,单精度浮点数和
双精度浮点数可以在Unity代码中独立地启用或禁用。这对于没有浮点数运算支持的嵌入式
目标十分有用(即Unity在仅支持点定数的平台上不会编译出错)。详见Unity文档。
不是所有目标都支持64位宽度类型,甚至有些32位都不支持。定义合适的预处理器符合,然后
Unity就会在编译中隐藏所有超过了你目标平台最大宽度的操作。详见Unity文档。
TEST_FAIL()
这家伙最常用于一种特殊状况,即你的测试代码在一个简单的断言上执行逻辑。就是说,
实践中,TEST_FAIL()
总是会出现在一个条件代码块中。
示例:
TEST_IGNORE()
标记一个测试用例(即应该包含测试断言的函数)为忽视。通常这被用于标记未来要实现的一个
测试用例。如果其他断言在一个封装的测试用例中,一个被忽视的测试用例是有用的(详见Unity
文档)。
TEST_ASSERT (condition)
TEST_ASSERT_TRUE (condition)
TEST_ASSERT_FALSE (condition)
TEST_ASSERT_UNLESS (condition)
只是TEST_ASSERT_FALSE
的措辞的一些变化。TEST_ASSERT_UNLESS
在特定的条件语句或
测试结构中有助于增加语义上的可读性。
TEST_ASSERT_NULL (pointer)
TEST_ASSERT_NOT_NULL (pointer)
对于不支持大整型的构建目标,可以禁用大整型。比如,如果你的目标最多支持16位类型,
通过定义适当的符号,Unity可以配置为隐藏32和64位操作,这样就可以编译通过了(详见
Unity文档)。参考这篇文档后面的高级断言以获取怎么处理其他大小的建议。
TEST_ASSERT_EQUAL_INT (expected, actual)
TEST_ASSERT_EQUAL_INT8 (expected, actual)
TEST_ASSERT_EQUAL_INT16 (expected, actual)
TEST_ASSERT_EQUAL_INT32 (expected, actual)
TEST_ASSERT_EQUAL_INT64 (expected, actual)
TEST_ASSERT_EQUAL (expected, actual)
TEST_ASSERT_NOT_EQUAL (expected, actual)
TEST_ASSERT_EQUAL_UINT (expected, actual)
TEST_ASSERT_EQUAL_UINT8 (expected, actual)
TEST_ASSERT_EQUAL_UINT16 (expected, actual)
TEST_ASSERT_EQUAL_UINT32 (expected, actual)
TEST_ASSERT_EQUAL_UINT64 (expected, actual)
所有函数名中带有的_HEX
的断言都是无符号整型断言,它们产生的expected
和actual
值都是十六进制格式的。Unity输出是大端的。
TEST_ASSERT_EQUAL_HEX (expected, actual)
TEST_ASSERT_EQUAL_HEX8 (expected, actual)
TEST_ASSERT_EQUAL_HEX16 (expected, actual)
TEST_ASSERT_EQUAL_HEX32 (expected, actual)
TEST_ASSERT_EQUAL_HEX64 (expected, actual)
掩码及位等级的断言产生十六进制格式的输出。Unity输出是大端的。
TEST_ASSERT_BITS (mask, expected, actual)
仅比较expected
和actual
参数的掩码(即1)位。
TEST_ASSERT_BITS_HIGH (mask, actual)
断言actual
参数的掩码位为1。
TEST_ASSERT_BITS_LOW (mask, actual)
断言actual
参数的掩码为为0。
TEST_ASSERT_BIT_HIGH (bit, actual)
断言actual
参数的指定位为1。
TEST_ASSERT_BIT_LOW (bit, actual)
断言actual
参数的指定位为0。
这些断言验证actual
参数比threshold
(不含)小或大。比如,如果阈值为0,对于大于
的那个,断言在它为0或更小值时会失败。
TEST_ASSERT_GREATER_THAN (threshold, actual)
TEST_ASSERT_GREATER_THAN_INT (threshold, actual)
TEST_ASSERT_GREATER_THAN_INT8 (threshold, actual)
TEST_ASSERT_GREATER_THAN_INT16 (threshold, actual)
TEST_ASSERT_GREATER_THAN_INT32 (threshold, actual)
TEST_ASSERT_GREATER_THAN_UINT (threshold, actual)
TEST_ASSERT_GREATER_THAN_UINT8 (threshold, actual)
TEST_ASSERT_GREATER_THAN_UINT16 (threshold, actual)
TEST_ASSERT_GREATER_THAN_UINT32 (threshold, actual)
TEST_ASSERT_GREATER_THAN_HEX8 (threshold, actual)
TEST_ASSERT_GREATER_THAN_HEX16 (threshold, actual)
TEST_ASSERT_GREATER_THAN_HEX32 (threshold, actual)
TEST_ASSERT_LESS_THAN (threshold, actual)
TEST_ASSERT_LESS_THAN_INT (threshold, actual)
TEST_ASSERT_LESS_THAN_INT8 (threshold, actual)
TEST_ASSERT_LESS_THAN_INT16 (threshold, actual)
TEST_ASSERT_LESS_THAN_INT32 (threshold, actual)
TEST_ASSERT_LESS_THAN_UINT (threshold, actual)
TEST_ASSERT_LESS_THAN_UINT8 (threshold, actual)
TEST_ASSERT_LESS_THAN_UINT16 (threshold, actual)
TEST_ASSERT_LESS_THAN_UINT32 (threshold, actual)
TEST_ASSERT_LESS_THAN_HEX8 (threshold, actual)
TEST_ASSERT_LESS_THAN_HEX16 (threshold, actual)
TEST_ASSERT_LESS_THAN_HEX32 (threshold, actual)
这些断言验证expected
参数处于actual
参数的+/-delta
(含)之间。比如,如果期望值
是10,delta值是3,那如果给定值在7 - 13之外的话断言就会失败。
TEST_ASSERT_INT_WITHIN (delta, expected, actual)
TEST_ASSERT_INT8_WITHIN (delta, expected, actual)
TEST_ASSERT_INT16_WITHIN (delta, expected, actual)
TEST_ASSERT_INT32_WITHIN (delta, expected, actual)
TEST_ASSERT_INT64_WITHIN (delta, expected, actual)
TEST_ASSERT_UINT_WITHIN (delta, expected, actual)
TEST_ASSERT_UINT8_WITHIN (delta, expected, actual)
TEST_ASSERT_UINT16_WITHIN (delta, expected, actual)
TEST_ASSERT_UINT32_WITHIN (delta, expected, actual)
TEST_ASSERT_UINT64_WITHIN (delta, expected, actual)
TEST_ASSERT_HEX_WITHIN (delta, expected, actual)
TEST_ASSERT_HEX8_WITHIN (delta, expected, actual)
TEST_ASSERT_HEX16_WITHIN (delta, expected, actual)
TEST_ASSERT_HEX32_WITHIN (delta, expected, actual)
TEST_ASSERT_HEX64_WITHIN (delta, expected, actual)
TEST_ASSERT_EQUAL_PTR (expected, actual)
断言指针指向同个内存位置。
TEST_ASSERT_EQUAL_STRING (expected, actual)
断言以null结尾('\0'
)的字符串是一致的。如果字符串的长度不一样,或者在结束符前的
任何部分字符串不一样,断言就是失败。两个NULL字符串(即长度为0)被认为相等。
TEST_ASSERT_EQUAL_MEMORY (expected, actual, len)
断言由expected
指针和actual
指针所指向的内存中的内容是一致的。内存块的字节大小
由len
参数指定。
expected
和actual
参数都是数组。num_elements
指定了数组中要比较的元素数量。
_HEX
断言产生的失败信息会以十六进制打印expected和actual数组中的内容。
至于字符串数组的比较行为,见前面章节中对TEST_ASSERT_EQUAL_STRING
的注释。
要比较的数组中第一个不匹配的元素会导致断言失败。失败信息会说明比较失败的索引。
TEST_ASSERT_EQUAL_INT_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_INT8_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_INT16_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_INT32_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_INT64_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_UINT_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_UINT8_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_UINT16_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_UINT32_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_UINT64_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_HEX_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_HEX8_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_HEX16_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_HEX32_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_HEX64_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_PTR_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_STRING_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_MEMORY_ARRAY (expected, actual, len, num_elements)
len
是每个数组元素的字节大小。
expected
是单个值,actual
是数组。num_elements
指定数组中要比较的元素的个数。
_HEX
断言产生的失败信息会以十六进制打印expected和actual数组中的内容。
要比较的数组中第一个不匹配的元素会导致断言失败。失败信息会说明比较失败的数组索引。
TEST_ASSERT_EACH_EQUAL_INT (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_INT8 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_INT16 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_INT32 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_INT64 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_UINT (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_UINT8 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_UINT16 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_UINT32 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_UINT64 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_HEX (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_HEX8 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_HEX16 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_HEX32 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_HEX64 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_PTR (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_STRING (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_MEMORY (expected, actual, len, num_elements)
len
是每个数组元素的字节大小。
TEST_ASSERT_FLOAT_WITHIN (delta, expected, actual)
这些断言验证actual
参数处于expected
参数的+/-delta
之间。浮点数表示法的特性
导致没法保证准确的比较。
TEST_ASSERT_EQUAL_FLOAT (expected, actual)
断言actual
值与expected
值"接近到足以认为相等"。如果你对细节很好奇,详见高级断言
章节。在浮点数断言中隐藏用户指定的差值一方面是方便使用,另一方面也是CMock代码生成
约定的要求。
TEST_ASSERT_EQUAL_FLOAT_ARRAY (expected, actual, num_elements)
详见 数组断言 章节。注意,数组元素的单个单精度浮点数比较使用的是TEST_ASSERT_EQUAL_FLOAT
。
就是说,用户指定的差值比较值需要一个定制实现的单精度浮点数数组断言。
TEST_ASSERT_FLOAT_IS_INF (actual)
断言actual
参数等于正无穷的浮点数表示。
TEST_ASSERT_FLOAT_IS_NEG_INF (actual)
断言actual
参数等于负无穷的浮点数表示。
TEST_ASSERT_FLOAT_IS_NAN (actual)
断言actual
参数是一个非数字浮点数表示。
TEST_ASSERT_FLOAT_IS_DETERMINATE (actual)
断言actual
参数是一个可以用于数学运算的浮点数。就是说,actual
参数既不是正无穷,
又不是负无穷,还不是非数字浮点数。
TEST_ASSERT_FLOAT_IS_NOT_INF (actual)
断言actual
参数是一个值,而不是正无穷。
TEST_ASSERT_FLOAT_IS_NOT_NEG_INF (actual)
断言actual
参数是一个值,而不是负无穷。
TEST_ASSERT_FLOAT_IS_NOT_NAN (actual)
断言actual
参数是一个值,而不是非数字浮点数表示。
TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE (actual)
断言actual
参数不可用于数学运算。就是说,actual
参数不是正无穷,就是负无穷,
或是非数字浮点数。
TEST_ASSERT_DOUBLE_WITHIN (delta, expected, actual)
这些断言验证actual
参数处于expected
参数的+/-delta
之间。浮点数表示法的特性
导致没法保证准确的比较。
TEST_ASSERT_EQUAL_DOUBLE (expected, actual)
断言actual
值与expected
值"接近到足以认为相等"。如果你对细节很好奇,详见高级断言
章节。在浮点数断言中隐藏用户指定的差值一方面是方便使用,另一方面也是CMock代码生成
约定的要求。
TEST_ASSERT_EQUAL_DOUBLE_ARRAY (expected, actual, num_elements)
详见 数组断言 章节。注意,数组元素的单个双精度浮点数比较使用的是TEST_ASSERT_EQUAL_DOUBLE
。
就是说,用户指定的差值比较值需要一个定制实现的双精度浮点数数组断言。
TEST_ASSERT_DOUBLE_IS_INF (actual)
断言actual
参数等于正无穷的浮点数表示。
TEST_ASSERT_DOUBLE_IS_NEG_INF (actual)
断言actual
参数等于负无穷的浮点数表示。
TEST_ASSERT_DOUBLE_IS_NAN (actual)
断言actual
参数是一个非数字浮点数表示。
TEST_ASSERT_DOUBLE_IS_DETERMINATE (actual)
断言actual
参数是一个可以用于数学运算的浮点数。就是说,actual
参数既不是正无穷,
又不是负无穷,还不是非数字浮点数。
TEST_ASSERT_DOUBLE_IS_NOT_INF (actual)
断言actual
参数是一个值,而不是正无穷。
TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF (actual)
断言actual
参数是一个值,而不是负无穷。
TEST_ASSERT_DOUBLE_IS_NOT_NAN (actual)
断言actual
参数是一个值,而不是非数字浮点数表示。
TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE (actual)
断言actual
参数不可用于数学运算。就是说,actual
参数不是正无穷,就是负无穷,
或是非数字浮点数。
这个章节帮助你理解怎么处理一些你可能会遇到的更有技巧性的断言。带你瞥一眼Unity的
断言机制引擎下的一些细节。如果你是那种喜欢刨根知底的人,那这章节很适合你。如果不
是的话,当你需要的时候再来读这个章节吧。
如你也许知道的,直接检查一对浮点数相等实在太扯淡了,简直是zz。浮点数值常能以多种
方式表示,特别是对一个值进行一系列运算后。初始化一个变量为2.0很可能导致浮点数表示
法记为 2 x 20,但是一系列数学运算后可能导致记为 8 x 2-2,这也表示2这个值。有时候
重复的运算会导致相等运算失败。
所以Unity不直接比较浮点数相等。它会检查两个浮点数是否"十分接近"。如果你让Unity使
用默认配置,“十分接近"等价于"在一个或两个有效bit内”。在底层,TEST_ASSERT_EQUAL_FLOAT
实际上是delta
参数在运行时计算的TEST_ASSERT_FLOAT_WITHIN
。对于单精度,delta是
期望值乘以0.00001,则会产生在期望值周围一个很小比例的范围。
如果你期望的值为20,000.0,delta则算出来是0.2。所以任何19,999.8与20,000.2之间的值
都能通过相等检查。实践证明这大致是单精度浮点数单个bit的范围,
所以当是0的时候怎么办呢? 0 - 可以用许多种方式表示 - 甚至比其他浮点值还多的方式。
不管是0 x 20 还是 0 x 263,它都是0,对吧?幸运地是,如果你用任意两个0相减,差值
都还是0,它仍然会落在0加减一个差值的范围内。所以这个方法仍然有用!
双精度浮点数使用一个小得多的乘数,同样大约一个bit的误差。
如果你不喜欢这个范围,想要让你的浮点数相等断言不那么严格,你可以修改这些乘数,定义
UNITY_FLOAT_PRECISION和UNITY_DOUBLE_PRECISION的值就行。详见Unity文档。
"搞笑"的是,在C这个标准中,如整型这么基础的东西居然会根据目标平台而变化。根据C的标准,
一个int
的大小是目标的自然寄存器大小,并且至少16位且为字节的整数倍。它还保证
以下大小排序:
char <= short <= int <= long <= long long
int
最常见的是32位。在嵌入式中,大部分情况下int
是16位。极少微控制器是24位
整型,但它仍然完美满足标准C。
让事情更有趣的是,有一些编译器和目标遇到了更困难的选择。如果自然寄存器的大小是
10位或12位的话怎么办?显然它们无法同时满足至少16位以及匹配自然寄存器大小这 两个 条件。
在这些情况下,它们通常选择自然寄存器大小,然后就变成了这样:
char (8 bit) <= short (12 bit) <= int (12 bit) <= long (16 bit)
啊…哈。这明显违背了一两个规则…但是它们不得不违背一些规则,所以它们做了个选择。
当C99标准出现时,它引入了多种标准大小类型。它还引入了用于拉取整型最大/最小值的宏。
这太赞了!不幸的是,许多嵌入式编译器并没有使用C99类型(有时是因为它们遇到了如上描述
的奇怪的寄存器大小。有时是因为它们不喜欢它?)。
Unity的目标从一开始就是要支持每个微控制器或微处理器与C编译器的组合。随着时间的流逝,
我们真的很接近这个目标呢。但是如果你想要在一些更古怪的目标上高效地使用Unity的话,
有一些你需要意识到的窍门。
首先,当将Unity配置到一个新目标上时,你应该特别关注下用于自动检测类型的(可用)宏,
或手动配置它们。你可以在Unity的文档中获得相关信息。
当你突然需要处理一些怪异的东西,如24位int
时怎么办呢?最简单的解决方案是使用大一号
的尺寸。如果你有24位的int
,将Unity配置为使用32位的整型。如果你有一个12位的int
,
配置Unity使用16位的。注意以下两个事情:
TEST_ASSERT_INT_WITHIN
。这样的断言可能会int
,可能你会遇到错误的失败。你总可以回归最简单的TEST_ASSERT
并自己做运算。Find The Latest of This And More at ThrowTheSwitch.org
Unity断言参考手册
背景和综述
超浓缩版
Unity的成分很多,但它主要是断言
One way to think of Unity is simply as a rich collection of assertions you can
use to establish whether your source code behaves the way you think it does.
Unity provides a framework to easily organize and execute those assertions in
test code separate from your source code.
一个思考Unity的简单方式是把它想成一个丰富的断言集合,你可以用这个集合来约束你的
源码按照你想的方式工作。Unity提供了一个框架,你可以使用其以简单地组织和执行那些
在测试代码中的断言,断言与源码是分离的。
断言是什么
At their core, assertions are an establishment of truth - boolean truth. Was this
thing equal to that thing? Does that code doohickey have such-and-such property
or not? You get the idea. Assertions are executable code (to appreciate the big
picture on this read up on the difference between
[link:Dynamic Verification and Static Analysis]). A failing assertion stops
execution and reports an error through some appropriate I/O channel (e.g.
stdout, GUI, file, blinky light).
在它们的核心,断言是真理的一个确立 - 逻辑真理。这个东西和那个相等吗?这段精妙的代码
有这样的特性么?你明白了。断言是可执行的代码(看看这个大图以阅读差别)。一个失败的断言
会停止执行并通过一些合适的I/O口报告一个错误(例如:stdout、GUI、文件、闪灯)
Fundamentally, for dynamic verification all you need is a single assertion
mechanism. In fact, that’s what the assert() macro in C’s standard library
is for. So why not just use it? Well, we can do far better in the reporting
department. C’s assert()
is pretty dumb as-is and is particularly poor for
handling common data types like arrays, structs, etc. And, without some other
support, it’s far too tempting to litter source code with C’s assert()
's. It’s
generally much cleaner, manageable, and more useful to separate test and source
code in the way Unity facilitates.
基本上,想要动态验证的话,你唯一需要的就是单个断言机制。事实上,那就是C标准库中assert()宏
做的事。所以,为什么不干脆就用它算了?好吧,我们在报告上可以做的好的多。C的assert()
原本就很哑巴,并且特别处理不来普通数据类型如数组、数据结构等。并且,如果没有一些其他
支持,往C垃圾源码中扔一堆assert()
实在太诱人了。按照Unity的方式把测试和源码分开通常
会更加干净、更易于管理以及更有用。
Unity的断言:有用的信息 和 免费的源码文档
Asserting a simple truth condition is valuable, but using the context of the
assertion is even more valuable. For instance, if you know you’re comparing bit
flags and not just integers, then why not use that context to give explicit,
readable, bit-level feedback when an assertion fails?
断言一个简单的真相条件是有价值的,但是使用断言的上下文更有价值。比如,如果你知道
你在比较标志位而不是整数,那么为什么不使用那上下文以在一个断言失败时给予精准、可
读、位等级的反馈呢?
That’s what Unity’s collection of assertions do - capture context to give you
helpful, meaningful assertion failure messages. In fact, the assertions
themselves also serve as executable documentation about types and values in your
source code. So long as your tests remain current with your source and all those
tests pass, you have a detailed, up-to-date view of the intent and mechanisms in
your source code. And due to a wondrous mystery, well-tested code usually tends
to be well designed code.
那就是Unity的断言集合做的事 - 捕获上下文以给你有用且有意义的断言失败信息。事实上,
断言本身也是可执行的文档,关于你源码中类型和值的文档。只要你的测试和你的源码保持
同步,并且所有的测试都能通过,你就有了你源码的一个详细且最新的目的与机制视图。并且
由于一个奇妙的秘密,良好测试的代码通常趋于良好的设计。
断言的约定及配置
命名和参数约定
The convention of assertion parameters generally follows this order:
断言的参数约定通常遵循这个顺序:
TEST_ASSERT_X( {modifiers}, {expected}, actual, {size/count} )
The very simplest assertion possible uses only a single “actual” parameter (e.g.
a simple null check).
很简单的断言可能只使用单个"actual"参数(比如一个简单的null检查)。
“Actual” is the value being tested and unlike the other parameters in an
assertion construction is the only parameter present in all assertion variants.
“Modifiers” are masks, ranges, bit flag specifiers, floating point deltas.
“Expected” is your expected value (duh) to compare to an “actual” value; it’s
marked as an optional parameter because some assertions only need a single
“actual” parameter (e.g. null check).
“Size/count” refers to string lengths, number of array elements, etc.
"Actual"是被测试的值,不像断言结构中的其他参数,它是唯一会出现在所有断言变体中的参数。
"Modifiers"是掩码、范围、标志位说明符、浮点位。
"Expected"是你期望的(emmm)与"actual"值进行比较的值;它被标记为可选参数是因为一些断言
仅仅需要单个"actual"参数(比如null检查)。
"Size/count"指的是如字符串长度、数组长度。
Many of Unity’s assertions are clear duplications in that the same data type
is handled by several assertions. The differences among these are in how failure
messages are presented. For instance, a _HEX
variant of an assertion prints
the expected and actual values of that assertion formatted as hexadecimal.
Unity的许多断言有明显的重复,同个数据类型许多断言都能处理。区别是失败信息的样子。
比如,一条断言的_HEX
变体会将这条断言的期望值与真实值打印为十六进制格式。
TEST_ASSERT_X_MESSAGE变体
All assertions are complemented with a variant that includes a simple string
message as a final parameter. The string you specify is appended to an assertion
failure message in Unity output.
所有 断言都有一个把简单字符串信息作为最终参数的变体。你指定的字符串会在Unity输出
中被附加到断言失败信息中。
For brevity, the assertion variants with a message parameter are not listed
below. Just tack on _MESSAGE
as the final component to any assertion name in
the reference list below and add a string as the final parameter.
为了简明起见,带有一个消息参数的断言变体不会列在下面。只需要附加_MESSAGE
到下面参考
列表中任意断言名的后面并添加一个字符串作为最终参数就行。
Example:
示例:
TEST_ASSERT_X( {modifiers}, {expected}, actual, {size/count} )
becomes messageified like thus…
消息化后就像这样…
TEST_ASSERT_X_MESSAGE( {modifiers}, {expected}, actual, {size/count}, message )
Notes:
_MESSAGE
variants intentionally do not support printf
style formattingprintf
for various reasons.sprintf
before the assertion to assemble a complex fail_ARRAY
sprintf
.注意:
_MESSAGE
变体故意不支持printf
风格的格式化,因为许多嵌入式项目因多种原因不支持或printf
。如果需要的话,可以在断言前使用sprintf来组装一个复杂的失败消息。_ARRAY
断言(见以下)可能就能有效避免使用sprintf
。TEST_ASSERT_X_ARRAY 变体
Unity provides a collection of assertions for arrays containing a variety of
types. These are documented in the Array section below. These are almost on par
with the _MESSAGE
variants of Unity’s Asserts in that for pretty much any Unity
type assertion you can tack on _ARRAY
and run assertions on an entire block of
memory.
Unity为多种类型的数组提供了一个断言集合。下面是数组部分的文档。它和_MESSAGE
变体很像
,对于Unity中很多类型的断言你同样只要在名字后面加上_ARRAY
就能在整块内存上运行断言了。
TEST_ASSERT_EQUAL_TYPEX_ARRAY( expected, actual, {size/count} )
“Expected” is an array itself.
“Size/count” is one or two parameters necessary to establish the number of array
elements and perhaps the length of elements within the array.
"Expected"是一个数组本身。
"Size/count"是一或两个指定数组元素个数的必要参数也可能是数组中元素的长度。
Notes:
_MESSAGE
variant convention still applies here to array assertions. The_MESSAGE
variants of the _ARRAY
assertions have names ending with_ARRAY_MESSAGE
.注意:
_MESSAGE
变体的约定仍能作用于array断言上。_ARRAY
断言的_MESSAGE
变体的名字_ARRAY_MESSAGE
结尾的。TEST_ASSERT_EACH_EQUAL_X变体
Unity provides a collection of assertions for arrays containing a variety of
types which can be compared to a single value as well. These are documented in
the Each Equal section below. these are almost on par with the _MESSAGE
variants of Unity’s Asserts in that for pretty much any Unity type assertion you
can inject _EACH_EQUAL and run assertions on an entire block of memory.
Unity为多种类型的数组提供了一个断言集合,同样可以只比较单个值。下面是Each Equal部分的
文档。它和_MESSAGE
变体很像,对于Unity中很多类型的断言你只要在名字中注入_EACH_EQUAL
就能在整块内存上运行断言了。
TEST_ASSERT_EACH_EQUAL_TYPEX( expected, actual, {size/count} )
“Expected” is a single value to compare to.
“Actual” is an array where each element will be compared to the expected value.
“Size/count” is one of two parameters necessary to establish the number of array
elements and perhaps the length of elements within the array.
"Expected"是要比较的单个值
"Actual"是一个数组,其中的每个元素都会与期望值比较。
"Size/count"是一或两个指定数组元素个数的必要参数也可能是数组中元素的长度。
Notes:
_MESSAGE
variant convention still applies here to Each Equal assertions.注意:
_MESSAGE
变体的约定仍能作用于Each Equal断言上。配置
浮点数支持是可选的
Support for floating point types is configurable. That is, by defining the
appropriate preprocessor symbols, floats and doubles can be individually enabled
or disabled in Unity code. This is useful for embedded targets with no floating
point math support (i.e. Unity compiles free of errors for fixed point only
platforms). See Unity documentation for specifics.
对浮点数类型的支持是可配置的。这是说,通过定义合适的预处理器符号,单精度浮点数和
双精度浮点数可以在Unity代码中独立地启用或禁用。这对于没有浮点数运算支持的嵌入式
目标十分有用(即Unity在仅支持点定数的平台上不会编译出错)。详见Unity文档。
最大数据宽度是可配置的。
Not all targets support 64 bit wide types or even 32 bit wide types. Define the
appropriate preprocessor symbols and Unity will omit all operations from
compilation that exceed the maximum width of your target. See Unity
documentation for specifics.
不是所有目标都支持64位宽度类型,甚至有些32位都不支持。定义合适的预处理器符合,然后
Unity就会在编译中隐藏所有超过了你目标平台最大宽度的操作。详见Unity文档。
基础Fail和Ignore
TEST_FAIL()
This fella is most often used in special conditions where your test code is
performing logic beyond a simple assertion. That is, in practice, TEST_FAIL()
will always be found inside a conditional code block.
这家伙最常用于一种特殊状况,即你的测试代码在一个简单的断言上执行逻辑。就是说,
实践中,TEST_FAIL()
总是会出现在一个条件代码块中。
Examples:
示例:
TEST_IGNORE()
Marks a test case (i.e. function meant to contain test assertions) as ignored.
Usually this is employed as a breadcrumb to come back and implement a test case.
An ignored test case has effects if other assertions are in the enclosing test
case (see Unity documentation for more).
标记一个测试用例(即应该包含测试断言的函数)为忽视。通常这被用于标记未来要实现的一个
测试用例。如果其他断言在一个封装的测试用例中,一个被忽视的测试用例是有用的(详见Unity
文档)。
布尔值
TEST_ASSERT (condition)
TEST_ASSERT_TRUE (condition)
TEST_ASSERT_FALSE (condition)
TEST_ASSERT_UNLESS (condition)
A simple wording variation on TEST_ASSERT_FALSE
.The semantics of
TEST_ASSERT_UNLESS
aid readability in certain test constructions or
conditional statements.
只是TEST_ASSERT_FALSE
的措辞的一些变化。TEST_ASSERT_UNLESS
在特定的条件语句或
测试结构中有助于增加语义上的可读性。
TEST_ASSERT_NULL (pointer)
TEST_ASSERT_NOT_NULL (pointer)
(所有大小的)有符号和无符号整型
Large integer sizes can be disabled for build targets that do not support them.
For example, if your target only supports up to 16 bit types, by defining the
appropriate symbols Unity can be configured to omit 32 and 64 bit operations
that would break compilation (see Unity documentation for more). Refer to
Advanced Asserting later in this document for advice on dealing with other word
sizes.
对于不支持大整型的构建目标,可以禁用大整型。比如,如果你的目标最多支持16位类型,
通过定义适当的符号,Unity可以配置为隐藏32和64位操作,这样就可以编译通过了(详见
Unity文档)。参考这篇文档后面的高级断言以获取怎么处理其他大小的建议。
TEST_ASSERT_EQUAL_INT (expected, actual)
TEST_ASSERT_EQUAL_INT8 (expected, actual)
TEST_ASSERT_EQUAL_INT16 (expected, actual)
TEST_ASSERT_EQUAL_INT32 (expected, actual)
TEST_ASSERT_EQUAL_INT64 (expected, actual)
TEST_ASSERT_EQUAL (expected, actual)
TEST_ASSERT_NOT_EQUAL (expected, actual)
TEST_ASSERT_EQUAL_UINT (expected, actual)
TEST_ASSERT_EQUAL_UINT8 (expected, actual)
TEST_ASSERT_EQUAL_UINT16 (expected, actual)
TEST_ASSERT_EQUAL_UINT32 (expected, actual)
TEST_ASSERT_EQUAL_UINT64 (expected, actual)
(所有大小的)十六进制无符号整型
All _HEX
assertions are identical in function to unsigned integer assertions
but produce failure messages with the expected
and actual
values formatted
in hexadecimal. Unity output is big endian.
所有函数名中带有的_HEX
的断言都是无符号整型断言,它们产生的expected
和actual
值都是十六进制格式的。Unity输出是大端的。
TEST_ASSERT_EQUAL_HEX (expected, actual)
TEST_ASSERT_EQUAL_HEX8 (expected, actual)
TEST_ASSERT_EQUAL_HEX16 (expected, actual)
TEST_ASSERT_EQUAL_HEX32 (expected, actual)
TEST_ASSERT_EQUAL_HEX64 (expected, actual)
掩码及位等级的断言
Masked and bit-level assertions produce output formatted in hexadecimal. Unity
output is big endian.
掩码及位等级的断言产生十六进制格式的输出。Unity输出是大端的。
TEST_ASSERT_BITS (mask, expected, actual)
Only compares the masked (i.e. high) bits of expected
and actual
parameters.
仅比较expected
和actual
参数的掩码(即1)位。
TEST_ASSERT_BITS_HIGH (mask, actual)
Asserts the masked bits of the actual
parameter are high.
断言actual
参数的掩码位为1。
TEST_ASSERT_BITS_LOW (mask, actual)
Asserts the masked bits of the actual
parameter are low.
断言actual
参数的掩码为为0。
TEST_ASSERT_BIT_HIGH (bit, actual)
Asserts the specified bit of the actual
parameter is high.
断言actual
参数的指定位为1。
TEST_ASSERT_BIT_LOW (bit, actual)
Asserts the specified bit of the actual
parameter is low.
断言actual
参数的指定位为0。
整数小于/大于
These assertions verify that the actual
parameter is less than or greater
than threshold
(exclusive). For example, if the threshold value is 0 for the
greater than assertion will fail if it is 0 or less.
这些断言验证actual
参数比threshold
(不含)小或大。比如,如果阈值为0,对于大于
的那个,断言在它为0或更小值时会失败。
TEST_ASSERT_GREATER_THAN (threshold, actual)
TEST_ASSERT_GREATER_THAN_INT (threshold, actual)
TEST_ASSERT_GREATER_THAN_INT8 (threshold, actual)
TEST_ASSERT_GREATER_THAN_INT16 (threshold, actual)
TEST_ASSERT_GREATER_THAN_INT32 (threshold, actual)
TEST_ASSERT_GREATER_THAN_UINT (threshold, actual)
TEST_ASSERT_GREATER_THAN_UINT8 (threshold, actual)
TEST_ASSERT_GREATER_THAN_UINT16 (threshold, actual)
TEST_ASSERT_GREATER_THAN_UINT32 (threshold, actual)
TEST_ASSERT_GREATER_THAN_HEX8 (threshold, actual)
TEST_ASSERT_GREATER_THAN_HEX16 (threshold, actual)
TEST_ASSERT_GREATER_THAN_HEX32 (threshold, actual)
TEST_ASSERT_LESS_THAN (threshold, actual)
TEST_ASSERT_LESS_THAN_INT (threshold, actual)
TEST_ASSERT_LESS_THAN_INT8 (threshold, actual)
TEST_ASSERT_LESS_THAN_INT16 (threshold, actual)
TEST_ASSERT_LESS_THAN_INT32 (threshold, actual)
TEST_ASSERT_LESS_THAN_UINT (threshold, actual)
TEST_ASSERT_LESS_THAN_UINT8 (threshold, actual)
TEST_ASSERT_LESS_THAN_UINT16 (threshold, actual)
TEST_ASSERT_LESS_THAN_UINT32 (threshold, actual)
TEST_ASSERT_LESS_THAN_HEX8 (threshold, actual)
TEST_ASSERT_LESS_THAN_HEX16 (threshold, actual)
TEST_ASSERT_LESS_THAN_HEX32 (threshold, actual)
(所有大小的)整型范围
These assertions verify that the expected
parameter is within +/- delta
(inclusive) of the actual
parameter. For example, if the expected value is 10
and the delta is 3 then the assertion will fail for any value outside the range
of 7 - 13.
这些断言验证expected
参数处于actual
参数的+/-delta
(含)之间。比如,如果期望值
是10,delta值是3,那如果给定值在7 - 13之外的话断言就会失败。
TEST_ASSERT_INT_WITHIN (delta, expected, actual)
TEST_ASSERT_INT8_WITHIN (delta, expected, actual)
TEST_ASSERT_INT16_WITHIN (delta, expected, actual)
TEST_ASSERT_INT32_WITHIN (delta, expected, actual)
TEST_ASSERT_INT64_WITHIN (delta, expected, actual)
TEST_ASSERT_UINT_WITHIN (delta, expected, actual)
TEST_ASSERT_UINT8_WITHIN (delta, expected, actual)
TEST_ASSERT_UINT16_WITHIN (delta, expected, actual)
TEST_ASSERT_UINT32_WITHIN (delta, expected, actual)
TEST_ASSERT_UINT64_WITHIN (delta, expected, actual)
TEST_ASSERT_HEX_WITHIN (delta, expected, actual)
TEST_ASSERT_HEX8_WITHIN (delta, expected, actual)
TEST_ASSERT_HEX16_WITHIN (delta, expected, actual)
TEST_ASSERT_HEX32_WITHIN (delta, expected, actual)
TEST_ASSERT_HEX64_WITHIN (delta, expected, actual)
结构体和字符串
TEST_ASSERT_EQUAL_PTR (expected, actual)
Asserts that the pointers point to the same memory location.
断言指针指向同个内存位置。
TEST_ASSERT_EQUAL_STRING (expected, actual)
Asserts that the null terminated ('\0'
)strings are identical. If strings are
of different lengths or any portion of the strings before their terminators
differ, the assertion fails. Two NULL strings (i.e. zero length) are considered
equivalent.
断言以null结尾('\0'
)的字符串是一致的。如果字符串的长度不一样,或者在结束符前的
任何部分字符串不一样,断言就是失败。两个NULL字符串(即长度为0)被认为相等。
TEST_ASSERT_EQUAL_MEMORY (expected, actual, len)
Asserts that the contents of the memory specified by the expected
and actual
pointers is identical. The size of the memory blocks in bytes is specified by
the len
parameter.
断言由expected
指针和actual
指针所指向的内存中的内容是一致的。内存块的字节大小
由len
参数指定。
数组
expected
and actual
parameters are both arrays. num_elements
specifies the
number of elements in the arrays to compare.
expected
和actual
参数都是数组。num_elements
指定了数组中要比较的元素数量。
_HEX
assertions produce failure messages with expected and actual array
contents formatted in hexadecimal.
_HEX
断言产生的失败信息会以十六进制打印expected和actual数组中的内容。
For array of strings comparison behavior, see comments for
TEST_ASSERT_EQUAL_STRING
in the preceding section.
至于字符串数组的比较行为,见前面章节中对TEST_ASSERT_EQUAL_STRING
的注释。
Assertions fail upon the first element in the compared arrays found not to
match. Failure messages specify the array index of the failed comparison.
要比较的数组中第一个不匹配的元素会导致断言失败。失败信息会说明比较失败的索引。
TEST_ASSERT_EQUAL_INT_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_INT8_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_INT16_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_INT32_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_INT64_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_UINT_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_UINT8_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_UINT16_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_UINT32_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_UINT64_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_HEX_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_HEX8_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_HEX16_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_HEX32_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_HEX64_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_PTR_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_STRING_ARRAY (expected, actual, num_elements)
TEST_ASSERT_EQUAL_MEMORY_ARRAY (expected, actual, len, num_elements)
len
is the memory in bytes to be compared at each array element.
len
是每个数组元素的字节大小。
(数组与单个值)分别相等
expected
are single values and actual
are arrays. num_elements
specifies
the number of elements in the arrays to compare.
expected
是单个值,actual
是数组。num_elements
指定数组中要比较的元素的个数。
_HEX
assertions produce failure messages with expected and actual array
contents formatted in hexadecimal.
_HEX
断言产生的失败信息会以十六进制打印expected和actual数组中的内容。
Assertions fail upon the first element in the compared arrays found not to
match. Failure messages specify the array index of the failed comparison.
要比较的数组中第一个不匹配的元素会导致断言失败。失败信息会说明比较失败的数组索引。
TEST_ASSERT_EACH_EQUAL_INT (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_INT8 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_INT16 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_INT32 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_INT64 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_UINT (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_UINT8 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_UINT16 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_UINT32 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_UINT64 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_HEX (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_HEX8 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_HEX16 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_HEX32 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_HEX64 (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_PTR (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_STRING (expected, actual, num_elements)
TEST_ASSERT_EACH_EQUAL_MEMORY (expected, actual, len, num_elements)
len
is the memory in bytes to be compared at each array element.
len
是每个数组元素的字节大小。
单精度浮点数(如果启用)
TEST_ASSERT_FLOAT_WITHIN (delta, expected, actual)
Asserts that the actual
value is within +/- delta
of the expected
value.
The nature of floating point representation is such that exact evaluations of
equality are not guaranteed.
这些断言验证actual
参数处于expected
参数的+/-delta
之间。浮点数表示法的特性
导致没法保证准确的比较。
TEST_ASSERT_EQUAL_FLOAT (expected, actual)
Asserts that the ?actual?value is “close enough to be considered equal” to the
expected
value. If you are curious about the details, refer to the Advanced
Asserting section for more details on this. Omitting a user-specified delta in a
floating point assertion is both a shorthand convenience and a requirement of
code generation conventions for CMock.
断言actual
值与expected
值"接近到足以认为相等"。如果你对细节很好奇,详见高级断言
章节。在浮点数断言中隐藏用户指定的差值一方面是方便使用,另一方面也是CMock代码生成
约定的要求。
TEST_ASSERT_EQUAL_FLOAT_ARRAY (expected, actual, num_elements)
See Array assertion section for details. Note that individual array element
float comparisons are executed using T?EST_ASSERT_EQUAL_FLOAT?.That is, user
specified delta comparison values requires a custom-implemented floating point
array assertion.
详见 数组断言 章节。注意,数组元素的单个单精度浮点数比较使用的是TEST_ASSERT_EQUAL_FLOAT
。
就是说,用户指定的差值比较值需要一个定制实现的单精度浮点数数组断言。
TEST_ASSERT_FLOAT_IS_INF (actual)
Asserts that actual
parameter is equivalent to positive infinity floating
point representation.
断言actual
参数等于正无穷的浮点数表示。
TEST_ASSERT_FLOAT_IS_NEG_INF (actual)
Asserts that actual
parameter is equivalent to negative infinity floating
point representation.
断言actual
参数等于负无穷的浮点数表示。
TEST_ASSERT_FLOAT_IS_NAN (actual)
Asserts that actual
parameter is a Not A Number floating point representation.
断言actual
参数是一个非数字浮点数表示。
TEST_ASSERT_FLOAT_IS_DETERMINATE (actual)
Asserts that ?actual?parameter is a floating point representation usable for
mathematical operations. That is, the actual
parameter is neither positive
infinity nor negative infinity nor Not A Number floating point representations.
断言actual
参数是一个可以用于数学运算的浮点数。就是说,actual
参数既不是正无穷,
又不是负无穷,还不是非数字浮点数。
TEST_ASSERT_FLOAT_IS_NOT_INF (actual)
Asserts that actual
parameter is a value other than positive infinity floating
point representation.
断言actual
参数是一个值,而不是正无穷。
TEST_ASSERT_FLOAT_IS_NOT_NEG_INF (actual)
Asserts that actual
parameter is a value other than negative infinity floating
point representation.
断言actual
参数是一个值,而不是负无穷。
TEST_ASSERT_FLOAT_IS_NOT_NAN (actual)
Asserts that actual
parameter is a value other than Not A Number floating
point representation.
断言actual
参数是一个值,而不是非数字浮点数表示。
TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE (actual)
Asserts that actual
parameter is not usable for mathematical operations. That
is, the actual
parameter is either positive infinity or negative infinity or
Not A Number floating point representations.
断言actual
参数不可用于数学运算。就是说,actual
参数不是正无穷,就是负无穷,
或是非数字浮点数。
双精度浮点数(如果启用)
TEST_ASSERT_DOUBLE_WITHIN (delta, expected, actual)
Asserts that the actual
value is within +/- delta
of the expected
value.
The nature of floating point representation is such that exact evaluations of
equality are not guaranteed.
这些断言验证actual
参数处于expected
参数的+/-delta
之间。浮点数表示法的特性
导致没法保证准确的比较。
TEST_ASSERT_EQUAL_DOUBLE (expected, actual)
Asserts that the actual
value is “close enough to be considered equal” to the
expected
value. If you are curious about the details, refer to the Advanced
Asserting section for more details. Omitting a user-specified delta in a
floating point assertion is both a shorthand convenience and a requirement of
code generation conventions for CMock.
断言actual
值与expected
值"接近到足以认为相等"。如果你对细节很好奇,详见高级断言
章节。在浮点数断言中隐藏用户指定的差值一方面是方便使用,另一方面也是CMock代码生成
约定的要求。
TEST_ASSERT_EQUAL_DOUBLE_ARRAY (expected, actual, num_elements)
See Array assertion section for details. Note that individual array element
double comparisons are executed using TEST_ASSERT_EQUAL_DOUBLE
.That is, user
specified delta comparison values requires a custom implemented double array
assertion.
详见 数组断言 章节。注意,数组元素的单个双精度浮点数比较使用的是TEST_ASSERT_EQUAL_DOUBLE
。
就是说,用户指定的差值比较值需要一个定制实现的双精度浮点数数组断言。
TEST_ASSERT_DOUBLE_IS_INF (actual)
Asserts that actual
parameter is equivalent to positive infinity floating
point representation.
断言actual
参数等于正无穷的浮点数表示。
TEST_ASSERT_DOUBLE_IS_NEG_INF (actual)
Asserts that actual
parameter is equivalent to negative infinity floating point
representation.
断言actual
参数等于负无穷的浮点数表示。
TEST_ASSERT_DOUBLE_IS_NAN (actual)
Asserts that actual
parameter is a Not A Number floating point representation.
断言actual
参数是一个非数字浮点数表示。
TEST_ASSERT_DOUBLE_IS_DETERMINATE (actual)
Asserts that actual
parameter is a floating point representation usable for
mathematical operations. That is, the ?actual?parameter is neither positive
infinity nor negative infinity nor Not A Number floating point representations.
断言actual
参数是一个可以用于数学运算的浮点数。就是说,actual
参数既不是正无穷,
又不是负无穷,还不是非数字浮点数。
TEST_ASSERT_DOUBLE_IS_NOT_INF (actual)
Asserts that actual
parameter is a value other than positive infinity floating
point representation.
断言actual
参数是一个值,而不是正无穷。
TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF (actual)
Asserts that actual
parameter is a value other than negative infinity floating
point representation.
断言actual
参数是一个值,而不是负无穷。
TEST_ASSERT_DOUBLE_IS_NOT_NAN (actual)
Asserts that actual
parameter is a value other than Not A Number floating
point representation.
断言actual
参数是一个值,而不是非数字浮点数表示。
TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE (actual)
Asserts that actual
parameter is not usable for mathematical operations. That
is, the actual
parameter is either positive infinity or negative infinity or
Not A Number floating point representations.
断言actual
参数不可用于数学运算。就是说,actual
参数不是正无穷,就是负无穷,
或是非数字浮点数。
高级断言:那些巧妙的断言中的细节
This section helps you understand how to deal with some of the trickier
assertion situations you may run into. It will give you a glimpse into some of
the under-the-hood details of Unity’s assertion mechanisms. If you’re one of
those people who likes to know what is going on in the background, read on. If
not, feel free to ignore the rest of this document until you need it.
这个章节帮助你理解怎么处理一些你可能会遇到的更有技巧性的断言。带你瞥一眼Unity的
断言机制引擎下的一些细节。如果你是那种喜欢刨根知底的人,那这章节很适合你。如果不
是的话,当你需要的时候再来读这个章节吧。
EQUAL断言是怎么处理单精度和双精度浮点数的?
As you may know, directly checking for equality between a pair of floats or a
pair of doubles is sloppy at best and an outright no-no at worst. Floating point
values can often be represented in multiple ways, particularly after a series of
operations on a value. Initializing a variable to the value of 2.0 is likely to
result in a floating point representation of 2 x 20,but a series of
mathematical operations might result in a representation of 8 x 2-2
that also evaluates to a value of 2. At some point repeated operations cause
equality checks to fail.
如你也许知道的,直接检查一对浮点数相等实在太扯淡了,简直是zz。浮点数值常能以多种
方式表示,特别是对一个值进行一系列运算后。初始化一个变量为2.0很可能导致浮点数表示
法记为 2 x 20,但是一系列数学运算后可能导致记为 8 x 2-2,这也表示2这个值。有时候
重复的运算会导致相等运算失败。
So Unity doesn’t do direct floating point comparisons for equality. Instead, it
checks if two floating point values are “really close.” If you leave Unity
running with defaults, “really close” means “within a significant bit or two.”
Under the hood, TEST_ASSERT_EQUAL_FLOAT
is really TEST_ASSERT_FLOAT_WITHIN
with the delta
parameter calculated on the fly. For single precision, delta is
the expected value multiplied by 0.00001, producing a very small proportional
range around the expected value.
所以Unity不直接比较浮点数相等。它会检查两个浮点数是否"十分接近"。如果你让Unity使
用默认配置,“十分接近"等价于"在一个或两个有效bit内”。在底层,TEST_ASSERT_EQUAL_FLOAT
实际上是delta
参数在运行时计算的TEST_ASSERT_FLOAT_WITHIN
。对于单精度,delta是
期望值乘以0.00001,则会产生在期望值周围一个很小比例的范围。
If you are expecting a value of 20,000.0 the delta is calculated to be 0.2. So
any value between 19,999.8 and 20,000.2 will satisfy the equality check. This
works out to be roughly a single bit of range for a single-precision number, and
that’s just about as tight a tolerance as you can reasonably get from a floating
point value.
如果你期望的值为20,000.0,delta则算出来是0.2。所以任何19,999.8与20,000.2之间的值
都能通过相等检查。实践证明这大致是单精度浮点数单个bit的范围,
So what happens when it’s zero? Zero - even more than other floating point
values - can be represented many different ways. It doesn’t matter if you have
0 x 20 or 0 x 263.It’s still zero, right? Luckily, if you
subtract these values from each other, they will always produce a difference of
zero, which will still fall between 0 plus or minus a delta of 0. So it still
works!
所以当是0的时候怎么办呢? 0 - 可以用许多种方式表示 - 甚至比其他浮点值还多的方式。
不管是0 x 20 还是 0 x 263,它都是0,对吧?幸运地是,如果你用任意两个0相减,差值
都还是0,它仍然会落在0加减一个差值的范围内。所以这个方法仍然有用!
Double precision floating point numbers use a much smaller multiplier, again
approximating a single bit of error.
双精度浮点数使用一个小得多的乘数,同样大约一个bit的误差。
If you don’t like these ranges and you want to make your floating point equality
assertions less strict, you can change these multipliers to whatever you like by
defining UNITY_FLOAT_PRECISION and UNITY_DOUBLE_PRECISION. See Unity
documentation for more.
如果你不喜欢这个范围,想要让你的浮点数相等断言不那么严格,你可以修改这些乘数,定义
UNITY_FLOAT_PRECISION和UNITY_DOUBLE_PRECISION的值就行。详见Unity文档。
怎么处理整型大小非标准的目标呢?
It’s “fun” that C is a standard where something as fundamental as an integer
varies by target. According to the C standard, an int
is to be the target’s
natural register size, and it should be at least 16-bits and a multiple of a
byte. It also guarantees an order of sizes:
"搞笑"的是,在C这个标准中,如整型这么基础的东西居然会根据目标平台而变化。根据C的标准,
一个int
的大小是目标的自然寄存器大小,并且至少16位且为字节的整数倍。它还保证
以下大小排序:
char <= short <= int <= long <= long long
Most often, int
is 32-bits. In many cases in the embedded world, int
is
16-bits. There are rare microcontrollers out there that have 24-bit integers,
and this remains perfectly standard C.
int
最常见的是32位。在嵌入式中,大部分情况下int
是16位。极少微控制器是24位
整型,但它仍然完美满足标准C。
To make things even more interesting, there are compilers and targets out there
that have a hard choice to make. What if their natural register size is 10-bits
or 12-bits? Clearly they can’t fulfill both the requirement to be at least
16-bits AND the requirement to match the natural register size. In these
situations, they often choose the natural register size, leaving us with
something like this:
让事情更有趣的是,有一些编译器和目标遇到了更困难的选择。如果自然寄存器的大小是
10位或12位的话怎么办?显然它们无法同时满足至少16位以及匹配自然寄存器大小这 两个 条件。
在这些情况下,它们通常选择自然寄存器大小,然后就变成了这样:
char (8 bit) <= short (12 bit) <= int (12 bit) <= long (16 bit)
Um… yikes. It’s obviously breaking a rule or two… but they had to break SOME
rules, so they made a choice.
啊…哈。这明显违背了一两个规则…但是它们不得不违背一些规则,所以它们做了个选择。
When the C99 standard rolled around, it introduced alternate standard-size types.
It also introduced macros for pulling in MIN/MAX values for your integer types.
It’s glorious! Unfortunately, many embedded compilers can’t be relied upon to
use the C99 types (Sometimes because they have weird register sizes as described
above. Sometimes because they don’t feel like it?).
当C99标准出现时,它引入了多种标准大小类型。它还引入了用于拉取整型最大/最小值的宏。
这太赞了!不幸的是,许多嵌入式编译器并没有使用C99类型(有时是因为它们遇到了如上描述
的奇怪的寄存器大小。有时是因为它们不喜欢它?)。
A goal of Unity from the beginning was to support every combination of
microcontroller or microprocessor and C compiler. Over time, we’ve gotten really
close to this. There are a few tricks that you should be aware of, though, if
you’re going to do this effectively on some of these more idiosyncratic targets.
Unity的目标从一开始就是要支持每个微控制器或微处理器与C编译器的组合。随着时间的流逝,
我们真的很接近这个目标呢。但是如果你想要在一些更古怪的目标上高效地使用Unity的话,
有一些你需要意识到的窍门。
First, when setting up Unity for a new target, you’re going to want to pay
special attention to the macros for automatically detecting types
(where available) or manually configuring them yourself. You can get information
on both of these in Unity’s documentation.
首先,当将Unity配置到一个新目标上时,你应该特别关注下用于自动检测类型的(可用)宏,
或手动配置它们。你可以在Unity的文档中获得相关信息。
What about the times where you suddenly need to deal with something odd, like a
24-bit int
? The simplest solution is to use the next size up. If you have a
24-bit int
, configure Unity to use 32-bit integers. If you have a 12-bit
int
, configure Unity to use 16 bits. There are two ways this is going to
affect you:
当你突然需要处理一些怪异的东西,如24位int
时怎么办呢?最简单的解决方案是使用大一号
的尺寸。如果你有24位的int
,将Unity配置为使用32位的整型。如果你有一个12位的int
,
配置Unity使用16位的。注意以下两个事情:
TEST_ASSERT_INT_WITHIN
.Such assertions might wrapint
in the wrong place, and you could experience false failures. You canTEST_ASSERT
and do the operations yourself.TEST_ASSERT_INT_WITHIN
。这样的断言可能会int
,可能你会遇到错误的失败。你总可以回归最简单的TEST_ASSERT
并自己做运算。Find The Latest of This And More at ThrowTheSwitch.org