Unity(纯C语言单元测试框架!不是那个Unity3d)Helper脚本参考文档

译者注:译者博客(http://blog.csdn.net/lin_strong),转载请保留这条。此为Unity手册的翻译,仅供学习交流使用,请勿用于商业用途。
翻译的资料是公开的,在docs/UnityHelperScriptsGuide.md,我想应该不会有什么版权问题,如涉及版权问题,请联系我删除文章。

Unity Helper 脚本

朋友的一点友情帮助

有时,成为一个高效的C程序员需要一些非C的东西。Unity项目包含了一些Ruby脚本,它们可以
让你过得好一点点。它们完全是可选的。如果你选择使用它们,自然你将需要一个Ruby副本。
安装最新版就好了,应该是没问题的。你可以在ruby-lang.org找到Ruby。

generate_test_runner.rb

你厌倦了在你的测试文件中创建自己的main函数了么?你添加新测试用例时老是忘了添加
对应的RUN_TEST调用么?你是否想要使用CMock或其他酷毙了的插件但却又不想要搞清楚
怎么创建自己的RUN_TEST宏?

那就对了,我们为你准备了很棒的脚本!

generate_test_runner脚本处理一个给定的测试文件并自动地创建一个独立的测试runner文件,
其中包含main以运行被扫描测试文件中的测试用例。然后你只需要把生成的runner添加到你的
文件列表中,编译、链接,然后欢呼!

这个脚本会搜索你的测试文件,寻找无输入参数和返回参数且函数名以"test"或"spec"开头的函数。
它会把每个符合条件的函数当做一个测试用例并为它们构建一个测试套件。比如,以下含有三个测试
用例:

void testVerifyThatUnityIsAwesomeAndWillMakeYourLifeEasier(void)
{
  ASSERT_TRUE(1);
}
void test_FunctionName_should_WorkProperlyAndReturn8(void) {
  ASSERT_EQUAL_INT(8, FunctionName());
}
void spec_Function_should_DoWhatItIsSupposedToDo(void) {
  ASSERT_NOT_NULL(Function(5));
}

有许多种方式可以运行这个脚本。第一种是从命令行:

ruby generate_test_runner.rb TestFile.c NameOfRunner.c

如果参数中只包含测试文件,脚本会把测试文件的名字加上"_Runner"作为生成文件的文件名。
下面这个例子会创建TestFile_Runner.c。

ruby generate_test_runner.rb TestFile.c

你可以添加一个YAML文件以配置额外选项。这个YAML文件使用与Unity和CMock
所用的相同的格式,特别方便。所以如果你已经在使用YAML文件了,你可以简单地传递同一个
文件到生成器脚本中。

ruby generate_test_runner.rb TestFile.c my_config.yml

YAML文件my_config.yml的内容可以和下面的示例长得很像。如果你想要知道这些选项是
做什么的,你会喜欢这篇文档的下一章节。

:unity:
  :includes:
    - stdio.h
    - microdefs.h
  :cexception: 1
  :suit_setup: "blah = malloc(1024);"
  :suite_teardown: "free(blah);"

如果你想要强迫生成的测试runner include一个或更多个头文件,你只需要在命令行中包含它们。
如果需要的话,只用确保它们在YAML文件 之后

ruby generate_test_runner.rb TestFile.c my_config.yml extras.h

另一种方式,特别是如果你在使用Ruby管理你的构建 - 很可能是基于Ruby的构建工具Rake -
直接就需要这个脚本。之前说的那些可以包含在YAML文件中的东西都可以作为hash的一部分传递
给脚本。我们这次直接通过Ruby代码传递与上面完全相同需求集看看:

require "generate_test_runner.rb"
options = {
  :includes => ["stdio.h", "microdefs.h"],
  :cexception => 1,
  :suite_setup => "blah = malloc(1024);",
  :suite_teardown => "free(blah);"
}
UnityTestRunnerGenerator.new.run(testfile, runner_name, options)

如果你在一个构建脚本(如一个Rakefile)中有多个文件要生成,你也许想实例化一个带有你的选项
的生成器对象,并在之后调用它来生成一个个runner。像这样:

gen = UnityTestRunnerGenerator.new(options)
test_files.each do |f|
  gen.run(f, File.basename(f,'.c')+"Runner.c"
end
generate_test_runner.rb接受的选项

当运行generate_test_runner时可用以下选项。你可以将其作为Ruby hash直接传递,或者
将它们写在一个YAML文件中,以下同时描述了这两种方式。在examples路径中,示例3的
Rakefile示例中就使用了一个Ruby hash。

:includes

这个选项指明要被#include到你的runner C文件顶上的文件名清单。你可以使用它来引入
定制类型或其他在你生成的runner中都需要的东西。

:suite_setup

这个选项定义了要在 任何 测试用例执行 执行的C代码。

可选的,如果你的C编译器支持weak符号,你可以不设置这个选项并在你的测试套件中提供一个
void suiteSetUp(void)函数。链接器将会寻找这个符号并最终找到一个 Unity-提供的 桩。

:suite_teardown

这个选项定义了要在 任何 测试用例执行完成 执行的C代码。一个整数变量num_failures
可以用于诊断。这个代码应该以一个return语句结束;返回值将变成main的退出代码。你可以
直接返回num_failures

可选的,如果你的C编译器支持weak符号,你可以不设置这个选项并在你的测试套件中提供一个
int suiteTearDown(int num_failures)函数。链接器将会寻找这个符号并最终找到一个
Unity-提供的 桩。

:enforce_strict_ordering

如果你在CMock中启用了严格调用顺序特性(见CMock文档),那你应该要定义这个选项。这会生成
使得所有东西能顺畅运行所需的额外的变量。如果你提供了与CMock配置中使用的同个YAML文件,
那直接就能配置好生成器了。

:externc

如果你在混用C和CPP且希望你的测试runner在生成时自动地包含extern "C"支持,应该定义这个
选项。

:mock_prefix:mock_suffix

对于每个included到主测试文件中且以给定mock前缀开头、给定mock后缀结尾(不包括文件扩展)
的文件,Unity会自动地生成对Init, Verify 和 Destroy的调用。默认的,Unity假设Mock为前缀,
没有后缀。

:plugins

这个选项指明要使用的插件的数组(当然,数组可以包含单个插件)。你可以在这里启用CException
支持,这样就会在每个测试中添加对于未处理异常的检查并在探测到问题时报错。使用Ruby启用这
个特性:

:plugins => [ :cexception ]

或在yaml文件中启用:

:plugins:
  -:cexception

如果你在使用CMock,很可能你已经传递了一个插件数组给CMock了。你可以在这使用同个数组。
这个脚本会忽略那些不需要额外支持的插件。

unity_test_summary.rb

一个Unity测试文件包含一个或多个测试用例函数。每个测试用例可能会通过、失败或忽略。
每个测试文件会独立运行并为它自己的测试集产生结果。一个工程几乎总会包含许多测试文件。
因此,测试套件由许多散落在多个测试文件中的测试用例组成。这个脚本会汇总各个测试文件
结果以生成一个总结。输出包括运行了多少测试,忽略了多少个以及失败了多少个。另外,输出
还包含一个关于具体哪个测试被忽略或失败了的清单。你可以在examples路径下发现一个好
例子。这个例子工程中故意忽视及使一些测试失败,在总结报告中生成了对应的信息。

如果你想要其他(更漂亮的?)输出格式,看看Ceedling构建工具项目(ceedling.sourceforge.net),
它使用Unity和CMock并支持xunit风格的xml以及其他东西。

这个脚本假设存在以扩展名.testpass.testfail结尾的文件。这些文件的内容是根据
每个测试文件中测试的通过或未通过的结果进行的一个汇总。脚本会搜索一个特定的路径以
寻找这些文件,打开发现的每个文件,转换结果,合并并打印总结。像这样从命令行调用它。

ruby unity_test_summary.rb build/test/

可选地,你可以指定一个根路径。当你在你工具的配置中使用相对路径但你想要拉取总结到
一个像Eclipse这样的IDE中创建可点击的快捷方式时,这很有用。

ruby unity_test_summary.rb build/test/ ~/projects/myproject/

或者,如果你更多地使用Windows:

ruby unity_test_summary.rb build\teat\ C:\projects\myproject\

当正确配置时,你将看到一个最终总结,像这样:

--------------------------
UNITY IGNORED TEST SUMMARY
--------------------------
blah.c:22:test_sandwiches_should_HaveBreadOnTwoSides:IGNORE

-------------------------
UNITY FAILED TEST SUMMARY
-------------------------
blah.c:87:test_sandwiches_should_HaveCondiments:FAIL:Expected 1 was 0
meh.c:38:test_soda_should_BeCalledPop:FAIL:Expected "pop" was "coke"

--------------------------
OVERALL UNITY TEST SUMMARY
--------------------------
45 TOTAL TESTS 2 TOTAL FAILURES 1 IGNORED

是不是很方便?

Find The Latest of This And More at ThrowTheSwitch.org


以下是中英对照版


Unity Helper Scripts

With a Little Help From Our Friends

朋友的一点友情帮助

Sometimes what it takes to be a really efficient C programmer is a little non-C.
The Unity project includes a couple of Ruby scripts for making your life just a tad
easier. They are completely optional. If you choose to use them, you’ll need a
copy of Ruby, of course. Just install whatever the latest version is, and it is
likely to work. You can find Ruby at ruby-lang.org.
有时,成为一个高效的C程序员需要一些非C的东西。Unity项目包含了一些Ruby脚本,它们可以
让你过得好一点点。它们完全是可选的。如果你选择使用它们,自然你将需要一个Ruby副本。
安装最新版就好了,应该是没问题的。你可以在ruby-lang.org找到Ruby。

generate_test_runner.rb

Are you tired of creating your own main function in your test file? Do you
keep forgetting to add a RUN_TEST call when you add a new test case to your
suite? Do you want to use CMock or other fancy add-ons but don’t want to figure
out how to create your own RUN_TEST macro?
你厌倦了在你的测试文件中创建自己的main函数了么?你添加新测试用例时老是忘了添加
对应的RUN_TEST调用么?你是否想要使用CMock或其他酷毙了的插件但却又不想要搞清楚
怎么创建自己的RUN_TEST宏?

Well then we have the perfect script for you!
那就对了,我们为你准备了很棒的脚本!

The generate_test_runner script processes a given test file and automatically
creates a separate test runner file that includes ?main?to execute the test
cases within the scanned test file. All you do then is add the generated runner
to your list of files to be compiled and linked, and presto you’re done!
generate_test_runner脚本处理一个给定的测试文件并自动地创建一个独立的测试runner文件,
其中包含main以运行被扫描测试文件中的测试用例。然后你只需要把生成的runner添加到你的
文件列表中,编译、链接,然后欢呼!

This script searches your test file for void function signatures having a
function name beginning with “test” or “spec”. It treats each of these
functions as a test case and builds up a test suite of them. For example, the
following includes three test cases:
这个脚本会搜索你的测试文件,寻找无输入参数和返回参数且函数名以"test"或"spec"开头的函数。
它会把每个符合条件的函数当做一个测试用例并为它们构建一个测试套件。比如,以下含有三个测试
用例:

void testVerifyThatUnityIsAwesomeAndWillMakeYourLifeEasier(void)
{
  ASSERT_TRUE(1);
}
void test_FunctionName_should_WorkProperlyAndReturn8(void) {
  ASSERT_EQUAL_INT(8, FunctionName());
}
void spec_Function_should_DoWhatItIsSupposedToDo(void) {
  ASSERT_NOT_NULL(Function(5));
}

You can run this script a couple of ways. The first is from the command line:
有许多种方式可以运行这个脚本。第一种是从命令行:

ruby generate_test_runner.rb TestFile.c NameOfRunner.c

Alternatively, if you include only the test file parameter, the script will copy
the name of the test file and automatically append “_Runner” to the name of the
generated file. The example immediately below will create TestFile_Runner.c.
如果参数中只包含测试文件,脚本会把测试文件的名字加上"_Runner"作为生成文件的文件名。
下面这个例子会创建TestFile_Runner.c。

ruby generate_test_runner.rb TestFile.c

You can also add a YAML file to configure extra options.
Conveniently, this YAML file is of the same format as that used by Unity and
CMock. So if you are using YAML files already, you can simply pass the very same
file into the generator script.
你可以添加一个YAML文件以配置额外选项。这个YAML文件使用与Unity和CMock
所用的相同的格式,特别方便。所以如果你已经在使用YAML文件了,你可以简单地传递同一个
文件到生成器脚本中。

ruby generate_test_runner.rb TestFile.c my_config.yml

The contents of the YAML file my_config.yml could look something like the
example below. If you’re wondering what some of these options do, you’re going
to love the next section of this document.
YAML文件my_config.yml的内容可以和下面的示例长得很像。如果你想要知道这些选项是
做什么的,你会喜欢这篇文档的下一章节。

:unity:
  :includes:
    - stdio.h
    - microdefs.h
  :cexception: 1
  :suit_setup: "blah = malloc(1024);"
  :suite_teardown: "free(blah);"

If you would like to force your generated test runner to include one or more
header files, you can just include those at the command line too. Just make sure
these are after the YAML file, if you are using one:
如果你想要强迫生成的测试runner include一个或更多个头文件,你只需要在命令行中包含它们。
如果需要的话,只用确保它们在YAML文件 之后

ruby generate_test_runner.rb TestFile.c my_config.yml extras.h

Another option, particularly if you are already using Ruby to orchestrate your
builds - or more likely the Ruby-based build tool Rake - is requiring this
script directly. Anything that you would have specified in a YAML file can be
passed to the script as part of a hash. Let’s push the exact same requirement
set as we did above but this time through Ruby code directly:
另一种方式,特别是如果你在使用Ruby管理你的构建 - 很可能是基于Ruby的构建工具Rake -
直接就需要这个脚本。之前说的那些可以包含在YAML文件中的东西都可以作为hash的一部分传递
给脚本。我们这次直接通过Ruby代码传递与上面完全相同需求集看看:

require "generate_test_runner.rb"
options = {
  :includes => ["stdio.h", "microdefs.h"],
  :cexception => 1,
  :suite_setup => "blah = malloc(1024);",
  :suite_teardown => "free(blah);"
}
UnityTestRunnerGenerator.new.run(testfile, runner_name, options)

If you have multiple files to generate in a build script (such as a Rakefile),
you might want to instantiate a generator object with your options and call it
to generate each runner afterwards. Like thus:
如果你在一个构建脚本(如一个Rakefile)中有多个文件要生成,你也许想实例化一个带有你的选项
的生成器对象,并在之后调用它来生成一个个runner。像这样:

gen = UnityTestRunnerGenerator.new(options)
test_files.each do |f|
  gen.run(f, File.basename(f,'.c')+"Runner.c"
end
Options accepted by generate_test_runner.rb:

generate_test_runner.rb接受的选项

The following options are available when executing generate_test_runner. You
may pass these as a Ruby hash directly or specify them in a YAML file, both of
which are described above. In the examples directory, Example 3’s Rakefile
demonstrates using a Ruby hash.
当运行generate_test_runner时可用以下选项。你可以将其作为Ruby hash直接传递,或者
将它们写在一个YAML文件中,以下同时描述了这两种方式。在examples路径中,示例3的
Rakefile示例中就使用了一个Ruby hash。

:includes

This option specifies an array of file names to be #include'd at the top of
your runner C file. You might use it to reference custom types or anything else
universally needed in your generated runners.
这个选项指明要被#include到你的runner C文件顶上的文件名清单。你可以使用它来引入
定制类型或其他在你生成的runner中都需要的东西。

:suite_setup

Define this option with C code to be executed before any test cases are run.
这个选项定义了要在 任何 测试用例执行 执行的C代码。

Alternatively, if your C compiler supports weak symbols, you can leave this
option unset and instead provide a void suiteSetUp(void) function in your test
suite. The linker will look for this symbol and fall back to a Unity-provided
stub if it is not found.
可选的,如果你的C编译器支持weak符号,你可以不设置这个选项并在你的测试套件中提供一个
void suiteSetUp(void)函数。链接器将会寻找这个符号并最终找到一个 Unity-提供的 桩。

:suite_teardown

Define this option with C code to be executed after all test cases have
finished. An integer variable num_failures is available for diagnostics.
The code should end with a return statement; the value returned will become
the exit code of main. You can normally just return num_failures.
这个选项定义了要在 任何 测试用例执行完成 执行的C代码。一个整数变量num_failures
可以用于诊断。这个代码应该以一个return语句结束;返回值将变成main的退出代码。你可以
直接返回num_failures

Alternatively, if your C compiler supports weak symbols, you can leave this
option unset and instead provide a int suiteTearDown(int num_failures)
function in your test suite. The linker will look for this symbol and fall
back to a Unity-provided stub if it is not found.
可选的,如果你的C编译器支持weak符号,你可以不设置这个选项并在你的测试套件中提供一个
int suiteTearDown(int num_failures)函数。链接器将会寻找这个符号并最终找到一个
Unity-提供的 桩。

:enforce_strict_ordering

This option should be defined if you have the strict order feature enabled in
CMock (see CMock documentation). This generates extra variables required for
everything to run smoothly. If you provide the same YAML to the generator as
used in CMock’s configuration, you’ve already configured the generator properly.
如果你在CMock中启用了严格调用顺序特性(见CMock文档),那你应该要定义这个选项。这会生成
使得所有东西能顺畅运行所需的额外的变量。如果你提供了与CMock配置中使用的同个YAML文件,
那直接就能配置好生成器了。

:externc

This option should be defined if you are mixing C and CPP and want your test
runners to automatically include extern “C” support when they are generated.
如果你在混用C和CPP且希望你的测试runner在生成时自动地包含extern "C"支持,应该定义这个
选项。

:mock_prefix and :mock_suffix

Unity automatically generates calls to Init, Verify and Destroy for every file
included in the main test file that starts with the given mock prefix and ends
with the given mock suffix, file extension not included. By default, Unity
assumes a Mock prefix and no suffix.
对于每个included到主测试文件中且以给定mock前缀开头、给定mock后缀结尾(不包括文件扩展)
的文件,Unity会自动地生成对Init, Verify 和 Destroy的调用。默认的,Unity假设Mock为前缀,
没有后缀。

:plugins

This option specifies an array of plugins to be used (of course, the array can
contain only a single plugin). This is your opportunity to enable support for
CException support, which will add a check for unhandled exceptions in each
test, reporting a failure if one is detected. To enable this feature using Ruby:
这个选项指明要使用的插件的数组(当然,数组可以包含单个插件)。你可以在这里启用CException
支持,这样就会在每个测试中添加对于未处理异常的检查并在探测到问题时报错。使用Ruby启用这
个特性:

:plugins => [ :cexception ]

Or as a yaml file:
或在yaml文件中启用:

:plugins:
  -:cexception

If you are using CMock, it is very likely that you are already passing an array
of plugins to CMock. You can just use the same array here. This script will just
ignore the plugins that don’t require additional support.
如果你在使用CMock,很可能你已经传递了一个插件数组给CMock了。你可以在这使用同个数组。
这个脚本会忽略那些不需要额外支持的插件。

unity_test_summary.rb

A Unity test file contains one or more test case functions. Each test case can
pass, fail, or be ignored. Each test file is run individually producing results
for its collection of test cases. A given project will almost certainly be
composed of multiple test files. Therefore, the suite of tests is comprised of
one or more test cases spread across one or more test files. This script
aggregates individual test file results to generate a summary of all executed
test cases. The output includes how many tests were run, how many were ignored,
and how many failed. In addition, the output includes a listing of which
specific tests were ignored and failed. A good example of the breadth and
details of these results can be found in the examples directory. Intentionally
ignored and failing tests in this project generate corresponding entries in the
summary report.
一个Unity测试文件包含一个或多个测试用例函数。每个测试用例可能会通过、失败或忽略。
每个测试文件会独立运行并为它自己的测试集产生结果。一个工程几乎总会包含许多测试文件。
因此,测试套件由许多散落在多个测试文件中的测试用例组成。这个脚本会汇总各个测试文件
结果以生成一个总结。输出包括运行了多少测试,忽略了多少个以及失败了多少个。另外,输出
还包含一个关于具体哪个测试被忽略或失败了的清单。你可以在examples路径下发现一个好
例子。这个例子工程中故意忽视及使一些测试失败,在总结报告中生成了对应的信息。

If you’re interested in other (prettier?) output formats, check into the
Ceedling build tool project (ceedling.sourceforge.net) that works with Unity and
CMock and supports xunit-style xml as well as other goodies.
如果你想要其他(更漂亮的?)输出格式,看看Ceedling构建工具项目(ceedling.sourceforge.net),
它使用Unity和CMock并支持xunit风格的xml以及其他东西。

This script assumes the existence of files ending with the extensions
.testpass and .testfail.The contents of these files includes the test
results summary corresponding to each test file executed with the extension set
according to the presence or absence of failures for that test file. The script
searches a specified path for these files, opens each one it finds, parses the
results, and aggregates and prints a summary. Calling it from the command line
looks like this:
这个脚本假设存在以扩展名.testpass.testfail结尾的文件。这些文件的内容是根据
每个测试文件中测试的通过或未通过的结果进行的一个汇总。脚本会搜索一个特定的路径以
寻找这些文件,打开发现的每个文件,转换结果,合并并打印总结。像这样从命令行调用它。

ruby unity_test_summary.rb build/test/

You can optionally specify a root path as well. This is really helpful when you
are using relative paths in your tools’ setup, but you want to pull the summary
into an IDE like Eclipse for clickable shortcuts.
可选地,你可以指定一个根路径。当你在你工具的配置中使用相对路径但你想要拉取总结到
一个像Eclipse这样的IDE中创建可点击的快捷方式时,这很有用。

ruby unity_test_summary.rb build/test/ ~/projects/myproject/

Or, if you’re more of a Windows sort of person:
或者,如果你更多地使用Windows:

ruby unity_test_summary.rb build\teat\ C:\projects\myproject\

When configured correctly, you’ll see a final summary, like so:
当正确配置时,你将看到一个最终总结,像这样:

--------------------------
UNITY IGNORED TEST SUMMARY
--------------------------
blah.c:22:test_sandwiches_should_HaveBreadOnTwoSides:IGNORE

-------------------------
UNITY FAILED TEST SUMMARY
-------------------------
blah.c:87:test_sandwiches_should_HaveCondiments:FAIL:Expected 1 was 0
meh.c:38:test_soda_should_BeCalledPop:FAIL:Expected "pop" was "coke"

--------------------------
OVERALL UNITY TEST SUMMARY
--------------------------
45 TOTAL TESTS 2 TOTAL FAILURES 1 IGNORED

How convenient is that?
是不是很方便?

Find The Latest of This And More at ThrowTheSwitch.org

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值