我如何使用 Ceedling/Unity/Cmock 来测试嵌入式系统

How do I use Ceedling/Unity/Cmock to test embedded Systems

我是使用 ceedling 测试嵌入式系统的新手。我想知道在学习如何使用 ceedling 方面是否有一个好的起点。

我正在开发的项目是 CubeSat 项目的嵌入式系统,我们需要一种方法来测试我们的代码。

有很多方法可以进入它。我的偏好是克隆 ceedling (git clone https://github.com/ThrowTheSwitch/Ceedling.git && git submodule update --init --recursive) 和 运行 一个例子,看看它是如何工作的。

要使 examples/temp_sensor 正常工作,您需要进行三处修改:

  • project.yml - 插件,load_paths 应该是 ../../plugins
  • rakefile.rb - PROJECT_CEEDLING_ROOT 应该是 "../.."
  • lib/ceedling/rakefile.rb - 添加引用 diy/test
  • 的行

这是我在 master 上所做的修改的差异(git commit 09a04cb55a86):

diff --git a/examples/temp_sensor/project.yml b/examples/temp_sensor/project.yml
index ec9a45e..a327f5b 100644
--- a/examples/temp_sensor/project.yml
+++ b/examples/temp_sensor/project.yml
@@ -58,7 +58,7 @@

 :plugins:
   :load_paths:
-    - vendor/ceedling/plugins
+    - ../../plugins
   :enabled:
     - stdout_pretty_tests_report
     - module_generator
diff --git a/examples/temp_sensor/rakefile.rb b/examples/temp_sensor/rakefile.rb
index 1b534d2..82d2e64 100755
--- a/examples/temp_sensor/rakefile.rb
+++ b/examples/temp_sensor/rakefile.rb
@@ -1,4 +1,4 @@
-PROJECT_CEEDLING_ROOT = "vendor/ceedling"
+PROJECT_CEEDLING_ROOT = "../.."
 load "#{PROJECT_CEEDLING_ROOT}/lib/ceedling.rb"

 Ceedling.load_project
diff --git a/lib/ceedling/rakefile.rb b/lib/ceedling/rakefile.rb
index 37001ba..be6b620 100644
--- a/lib/ceedling/rakefile.rb
+++ b/lib/ceedling/rakefile.rb
@@ -9,6 +9,7 @@ CEEDLING_RELEASE = File.join(CEEDLING_ROOT, 'release')
 $LOAD_PATH.unshift( CEEDLING_LIB )
 $LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'unity/auto') )
 $LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'diy/lib') )
+$LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'diy/test') )
 $LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'cmock/lib') )
 $LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'deep_merge/lib') )

运行 运行ning rake test 来自 examples/temp_sensor.

的示例

您需要 ruby(用于 rake)并为 temp_sensor 示例安装 gcc。

一旦确定了 example/temp_sensor/rakefile.rbexample/temp_sensor/project.yml 文件的格式,关键工作就在 examples/temp_sensor/test/Test... 文件中。

您首先应该了解的是,Ceedling 或任何单元测试框架的首要目的是测试您的代码,并通过扩展您的最终项目。您通常使用某种基于标准的编译器在您的 PC 上测试您的代码,不一定是您的嵌入式系统的交叉编译器。您可以 运行 取消在目标上生成的测试,但您可能不想这样做。

James W. Grenning's Test Driven Development for Embedded C(Pragmatic Programmers)。

这方面最好的书(不完美但仍然不错)。

我有一个关于在旧 Windows here 下设置的个人 GIST。主要是关于在 windows.

上获得 Ruby 和 GCC 的笔记

在 Linux 下,Ceedling 非常容易设置并且 运行。

  1. 确认你有可用的 gcc
  2. 确认您有 ruby 和 gem
  3. gem 安装 ceedling
  4. 天花板

就是这样。 如果你正在适应一个新项目,你将需要 fiddle 和 project.yml 文件一起告诉 ceedling 你的源文件和包含文件在哪里,以及你希望你的测试文件去哪里。这在某些项目结构上可能具有挑战性,但如果所有其他方法都失败了,您只需按名称将所有文件夹放入 project.yml 文件中(不是最好的,但对于疯狂混乱的项目来说是最终的回退) 还有其他学习曲线的东西,比如 ceedling test_xxx.c 文件有点神奇,因为它们包含您的测试,但也像 linker 控制文件一样。假定 test_xxx.c 文件中的每个包含文件都有一个具有相同基本名称的相应翻译单元(.c 文件)。 Ceedling 将搜索它并将其编译到您的测试中。如果您想排除该代码但需要一些依赖项,您可以更改包含文件名以包含单词 mock 以自动模拟接口,因此 foo.h 变为 mock_foo.h 并将为所有创建模拟函数在 header 中找到的已声明函数。如果你没有 header/tranalation_unit 名称对,你可以告诉 ceedling 编译和 link 一个文件,方法是将文件的名称放在一个名为 TEST_FILE 的宏中。所以如果你没有 foo.h 但需要 foo.c:

TEST_FILE("foo.c")

Throw The Switch 页面上还有许多其他很棒的资源。 希望有所帮助。我从来不需要直接从 github 中提取该工具,但如果你想向他们发送补丁,我想这是另一种方式,但他们投入了很多工作来使其 friction-less 设置并开始使用,我会先从 ruby 方法开始。

旁注 module_generator 插件中现在有一些很酷的单元测试挂钩,可以自动生成用于测试的存根,这在目标测试期间可能非常有用。