如何将 CMock 单元测试框架与 Make 集成
Posted
技术标签:
【中文标题】如何将 CMock 单元测试框架与 Make 集成【英文标题】:How to integrate CMock unit test framework with Make 【发布时间】:2017-08-05 22:10:59 【问题描述】:有没有办法将我的项目切换为使用 rake 作为其构建系统?我有一个使用 Make 作为其构建系统的大型项目,并希望为单元测试添加 CMock 功能(我已经成功使用 Unity),但没有找到有关将 CMock 与 Makefile 集成的信息(相反,似乎世界刚刚如果他们希望 CMock 与他们的项目一起工作,则接受使用 Ruby 的 rake 作为他们的构建系统)。
我已经能够运行 CMock 示例测试,其中包括一个(似乎未完成?)“制作”示例。
我已将“make_example”中的测试代码修改为以下内容:
#include "mock_foo.h"
#include "unity.h"
void setUp(void)
void tearDown(void)
void test_main_should_initialize_foo(void)
foo_init_Ignore();
TEST_IGNORE_MESSAGE("TODO: Implement main!");
但是,当从带有 Makefile 的文件夹中运行“make”时,UNITY_LINE_TYPE 似乎是未定义的(例如,我的依赖链中缺少某些东西):
make
mkdir -p ./build
mkdir -p ./build/obj
ruby ../../scripts/create_makefile.rb --silent
cc -o build/test/obj/test_main.o -c test/test_main.c -DTEST -I ./src -I /home/user/Documents/gitrepos/cmock/vendor/unity/src -I /home/user/Documents/gitrepos/cmock/src -I ./build/test/mocks
In file included from test/test_main.c:1:0:
./build/test/mocks/mock_foo.h:27:27: error: unknown type name ‘UNITY_LINE_TYPE’
void foo_init_CMockExpect(UNITY_LINE_TYPE cmock_line);
^
build/test/MakefileTestSupport:29: recipe for target 'build/test/obj/test_main.o' failed
make: *** [build/test/obj/test_main.o] Error 1
有没有人使用 Makefiles 和 CMock 成功实施过项目?
【问题讨论】:
【参考方案1】:原来我是我自己的 vim/clang 格式配置的受害者。
make_example(虽然开箱即用不是很有用)确实使用 CMock 的模拟框架正确编译和运行测试如果 'unity.h' 导入放在之前你的测试实现中的'mock_xxx.h'(我确定在文档中的某个地方已经提到过)。
以下是一个工作测试的示例(从 cmock/examples/make_example 稍微修改了 test_main.c):
#include "unity.h"
#include "mock_foo.h"
void setUp(void)
void tearDown(void)
void test_main_should_initialize_foo(void)
foo_init_Expect();
foo_init();
但是,由于我的 vim/clang 格式设置为“SortIncludes: true”,我的包含被重新排序以生成:
#include "mock_foo.h" // <---- the mocks must be included *after* unity.h
#include "unity.h"
void setUp(void)
void tearDown(void)
void test_main_should_initialize_foo(void)
foo_init_Expect();
foo_init();
就像我在 vim 中的 :wq 一样。
这当然会导致 CMock 问题,因为它需要在尝试生成 mock_foo.h 之前弄清楚 unity.h 定义,所以我收到了上面发布的错误:
...
In file included from test/test_main.c:1:0:
./build/test/mocks/mock_foo.h:27:27: error: unknown type name ‘UNITY_LINE_TYPE’
void foo_init_CMockExpect(UNITY_LINE_TYPE cmock_line);
...
我的 Makefile(CMock 示例未涉及),供后人参考:
CC ?= gcc
BUILD_DIR ?= ./build
SRC_DIR ?= ./src
TEST_DIR ?= ./test
TEST_BUILD_DIR ?= $BUILD_DIR/test
TEST_MAKEFILE = $TEST_BUILD_DIR/MakefileTestSupport
OBJ ?= $BUILD_DIR/obj
OBJ_DIR = $OBJ
default: all
all: setup test $BUILD_DIR/main run
setup:
mkdir -p $BUILD_DIR
mkdir -p $OBJ
ruby ../../scripts/create_makefile.rb --silent
clean:
rm -rf $BUILD_DIR
$BUILD_DIR/main: $SRC_DIR/main.c $SRC_DIR/foo.c
$CC $< -o $@
run:
./build/main || true
test: setup
-include $TEST_MAKEFILE
我发现 UNITY_LINE_TYPE 是在 unity.h 中定义的,并注意了 unity.h 是如何包含在我的测试中的,发现它是在 'mock_foo.h 之后包含的' (对我来说还没有问题),然后与一些工作 rake 示例(在 ../temp_sensor 中)相比,我注意到所有 'unity.h' 包含在所有 'mock_xxx 之前.h' 包括(我还没有用 vim 接触过这些。)
不要让你的工具成为傻瓜。
【讨论】:
【参考方案2】:这个错误刚刚被修复:https://github.com/ThrowTheSwitch/CMock/pull/211
现在您不需要保持#include 指令的特定顺序。
【讨论】:
很高兴我再次检查了这个问题 - 很高兴知道问题已解决。谢谢!【参考方案3】:您的里程可能会有所不同,但我发现用换行符对我的包含进行分组会导致 clang-format 在组内排序,从而使我可以在开始时保留重要的标题。通常这也有一定的逻辑意义。
例如,在我的 test_xyz.c 文件中:
#include "unity.h"
#include "support/logging.h"
#include "crc.h"
#include "mock_unistd.h"
排序到:
#include "unity.h"
#include "crc.h"
#include "mock_unistd.h"
#include "support/logging.h"
【讨论】:
以上是关于如何将 CMock 单元测试框架与 Make 集成的主要内容,如果未能解决你的问题,请参考以下文章