? ? ceedling就是一款嵌入式軟件測試框架。ceedling是一個用ruby語言編寫的C語言自動化測試框架,它集成了Cmock、Unity和Cexception等多個開源項目。在整個ceedling框架中,使用unity進行代碼測試,使用CMock生成模擬函數,使用CException進行異常處理,ceedling本身可以理解為對這三個框架的整合,提供自動化配置、操作等,簡化開發。
一 ceedling安裝步驟
ceedling使用ruby開發腳本,使用gcc工具鏈編譯,因此需要安裝ruby和gcc。
(1)首先安裝ruby。ruby安裝包見《rubyinstaller-devkit-3.0.2-1-x64.zip》
(2)安裝 gcc。拷貝文件夾《mingw64》拷貝到目錄C:\Program Files\下。之后把路徑C:\Program Files\mingw64\bin添加到系統環境變量中。
驗證:gcc --version
(3)安裝ceedling,執行命令gem install ceedling,執行此命令需要連接外網。
??????????安裝完畢驗證:ceedling version
二 ceedling配置
?ceedling是通過project.yml來進行配置。project.yml解釋如下:
#項目元數據
:project:
??:use_exceptions: FALSE ??????????# 是否啟用 C++ 異常(C 項目一般 FALSE)
??:use_test_preprocessor: TRUE ???# 是否對測試文件也跑一遍預處理器
??:use_auxiliary_dependencies: TRUE
??:build_root: build ?????????????# 所有中間文件、目標文件、測試可執行文件都會放到 build/
??:test_file_prefix: test_ ???????# 測試源文件必須 test_ 開頭(可改)
# 路徑配置
:paths:
??:test:
????- test/** ???????????????????# 遞歸搜索 test 目錄下所有測試文件
??:source:
????- src/** ????????????????????# 被測源碼
??:include:
????- inc ???????????????????????# 公共頭文件
????- mocks ?????????????????????# 手動樁或額外包含路徑
- third_party/cmsis/include ?# 第三方庫
#工具鏈定義
:tools:
??:test_compiler:
????:executable: gcc ????????????# 可執行文件名(Windows 用 gcc.exe)
????:arguments:
??????- -std=c11 ????????????????# C 語言標準
??????- -Wall
??????- -Wextra
??????- -Werror ?????????????????# 把告警當錯誤
??????- -Wno-unused-parameter ???# 針對 Unity 生成代碼的告警
??????- -I"${':include'}" ???????# 展開 :paths:include 里的路徑
??????- -I"${':source'}"
??????- -DUNITY_INCLUDE_CONFIG_H # 告訴 Unity 使用 Ceedling 生成的配置
# 全局宏定義
:defines:
??:common: &common_defines ??????# 定義錨點,后面可以引用
????- UNIT_TEST
????- DEBUG=1
??:test:
????- *common_defines ???????????# 引用錨點
????- TEST ???????????????????????????????????# 僅在測試編譯時生效
??:release:
????- *common_defines
- NDEBUG ?????????????????????????????????# 發布版本去掉 assert
# CMock 配置
:cmock:
??:mock_prefix: mock_ ???????????# 生成的樁文件名前綴
??:when_no_prototypes: :warn ????# 如果頭文件沒有函數原型就告警
??:enforce_strict_ordering: TRUE # 是否嚴格要求函數調用順序
??:includes:
????- stddef.h ??????????????????# 每個樁文件都強制包含的頭
????- stdint.h
??:treat_inlines: :include ??????# 也 mock 聲明為 static inline 的函數
??:treat_externs: :exclude ??????# 不自動 mock extern 變量
??:plugins:
????- :ignore ???????????????????# 支持 ignore_args
????- :callback ?????????????????# 支持 callback 插件
- :expect_any_args ??????????# 支持 ExpectAnyArgs
#Unity 配置
:unity:
??:defines:
- UNITY_INCLUDE_DOUBLE ??????# 讓 Unity 支持 TEST_ASSERT_EQUAL_DOUBLE
# 插件(gcov / bullseye / xml 報告等)
:plugins:
??:enabled:
????- gcov ??????????????????????# 覆蓋率報告
????- xml_tests_report ??????????# 生成 JUnit XML 給 CI
????- stdout_pretty_tests_report # 彩色命令行輸出
??:gcov:
????:reports:
??????- HtmlDetailed ????????????# 生成 html
????:gcovr:
??????:html_medium_threshold: 75 # 覆蓋率 75% 以上標綠
??????:html_high_threshold: 90
# 環境變量
:environment:
??- :path:
??????- C:\tools\mingw64\bin ???# Windows 下額外 PATH
三 如何使用ceedling編寫測試代碼
- 在某一目錄(英文目錄)下,執行如下命令:
ceedling new my_project
目錄結構自動生成如下所示:
my_project
├─ src/ ??????????????#?放被測源碼
├─ test/ ?????????????#?放測試文件
├─ project.yml ???????# 配置文件
把你要測試的源文件(例i2c_dw_core.c)拷貝到src/目錄下,并且i2c_dw_core.c的頭文件導入更換為:
#include "i2c_dw_core.h"
#include "i2c_dw_core_cmock.h"
- 新建文件i2c_dw_core.h,內容如下所示:
#ifndef I2C_DW_CORE_H
#define I2C_DW_CORE_H
#include "base.h"
# 如下函數聲明是待測函數的聲明
int i2c_dw_init_master(struct dw_i2c_dev *dev);
void i2c_dw_xfer_msg(struct dw_i2c_dev *dev);
#endif
(3)新建文件i2c_dw_core_cmock.h內容如下所示:
#ifndef I2C_DW_CORE_CMOCK
#define I2C_DW_CORE_CMOCK
# 如下函數聲明是需要打樁的函數的聲明
void __i2c_dw_disable_nowait(struct dw_i2c_dev *dev);
void rt_completion_done(struct rt_completion *completion);
#endif
(4)在src/目錄下新建文件base.h(所有待測源文件的數據類型定義可以共用base.h),內容如下:
#ifndef BASE_H
#define BASE_H
# 開始添加待測文件用到的所有數據類型的定義
typedef unsigned int UINT32;
#endif
(5)生成文件test_i2c_dw_core.c,并在此文件中編寫測試代碼
執行命令ceedling module:create[i2c_dw_core]
在test/目錄下,打開文件test_i2c_dw_core.c進行測試代碼編寫。
首先在#include "i2c_dw_core.h"語句后添加如下一條語句: #include "mock_i2c_dw_core_cmock.h"
開始編寫測試代碼。。。
四 ceedling常用打樁宏及其用法
一般用前四個
(1)Func_Ignore()
??徹底忽略型
??Func要求:無返回值,如有返回值則不能使用此宏。有無入參均可。
??源文件調用多少次都放行。
(2)Func_IgnoreAndReturn(ret)
??忽略入參,但固定返回ret
??Func要求:有返回值。有無入參均可。
??源文件調用多少次都放行。
(3)Func_Expect(arg1, arg2, …)
??Func要求:無返回值,有入參。
??這個宏作用是告訴 CMock “下一次調用 Func 時,實參必須完全等于括號里的值,否則測試立即失敗”。參數按位置逐一比較。
??此宏只能匹配一次調用(調用后就被“消耗”掉)。
??如果函數還有返回值,需用 Func_ExpectAndReturn(arg1, arg2, …, ret)
(4)Func_ExpectAndReturn(a,b,ret)
??Func要求:有返回值,有入參。這個宏作用是期望下一次調用的參數必須嚴格匹配括號里的值,并且讓調用返回ret。參數個數、順序、值都必須完全一致
??此宏只能匹配一次調用(調用后就被“消耗”掉)。
(5)Func_ExpectAnyArgs()
??Func要求:無返回值,有入參。
??這個宏作用是告訴 CMock“下一次調用 Func 時,不管傳什么參數,都算通過”。
??只能匹配一次調用(調用后就被“消耗”掉)。
(6)Func_ExpectAnyArgsAndReturn(ret)
??Func要求:有返回值,有入參。
??這個宏作用是告訴CMock:“下一次調用 Func 時,參數完全無所謂,但必須返回ret”。
??此宏只能匹配一次調用(調用后就被“消耗”掉)。
五 執行單元測試用例
以管理員身份打開windows終端,然后進入工程目錄my_project
執行如下命令:
ceedling clean
ceedling test:test_i2c_dw_core.c???#僅執行測試代碼文件test_i2c_dw_core.c
ceedling gcov:test_i2c_dw_core.c???#生成測試報告,測試報告在目錄my_project\build\artifacts\gcov\gcovr下。
六 配置文件樣例
見鏈接??https://download.csdn.net/download/wanglei200708/91849738