当前位置: 首页 > news >正文

如何对嵌入式软件进行单元测试

    ceedling就是一款嵌入式软件测试框架。ceedling是一个用ruby语言编写的C语言自动化测试框架,它集成了Cmock、UnityCexception等多个开源项目。在整个ceedling框架中,使用unity进行代码测试,使用CMock生成模拟函数,使用CException进行异常处理,ceedling本身可以理解为对这三个框架的整合,提供自动化配置、操作等,简化开发。

ceedling安装步骤

ceedling使用ruby开发脚本,使用gcc工具链编译,因此需要安装rubygcc

(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编写测试代码

  1. 在某一目录(英文目录)下,执行如下命令:

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"

  1. 新建文件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下。

http://www.xdnf.cn/news/1420687.html

相关文章:

  • 无重复字符的最长子串,leetCode热题100,C++实现
  • Vue3响应式陷阱:如何避免ref解构导致的响应式丢失
  • 电动自行车车架前叉振动、组合件冲击、把立管弯曲强度试验机等机械强度性能测试项目解析
  • 【趣味阅读】Python 文件头的秘密:从编码声明到 Shebang
  • Spring事务管理策略对比与性能优化实践指南
  • AI辅助论文写作,在《人工智能生成合成内容标识办法》出台后的新规则
  • HarmonyOS 应用开发深度实践:深入 Stage 模型与 ArkTS 声明式 UI
  • Linux - JDK安装
  • 刷题之链表oj题目
  • 突破超强回归模型,高斯过程回归!
  • 大语言模型对齐
  • VMware pro16(许可证)+centos 7超详细安装教程
  • MQ使用场景分析
  • 【RK3576】【Android14】PMIC电源管理
  • DVWA靶场通关笔记-SQL Injection Blind(SQL盲注 Impossible级别)
  • kubectl-etcd
  • 【C++】内存管理机制:从new到delete全解析
  • 植物中lncRNA鉴定和注释流程,代码(包含Identified,Classification,WGCNA.....)
  • 开发中使用——鸿蒙CoreSpeechKit语音识别
  • 基于MCP架构的OpenWeather API服务端设计与实现
  • C#在物联网GPS经纬度转换为百度地图地址
  • 亚马逊云代理商:如何选择适合的AWS EC2实例类型?
  • CVE Push Service | 高危漏洞实时情报自动化推送工具
  • Vue基础知识-使用监视属性watch和计算属性computed实现列表过滤+排序
  • 【golang长途旅行第35站】Redis
  • docker中的命令(六)
  • 针对redis中的热数据该怎么处理
  • ✝常用表格✝
  • Simulink库文件-一种低通滤波模块搭建方法
  • 【stm32】定时器(超详细)