Unity 用你来做嵌入式单元测试

Unity:专为嵌入式设计的 C 单元测试框架

🔗Unity 官方网站|🔗GitHub 项目

✅ 特点

  • 轻量级实现:核心仅由一个 .c 文件和两个头文件组成

  • 无依赖:不依赖标准库以外的组件,适合裸机环境

  • 丰富断言:支持整数、浮点、字符串、数组、位操作等多种断言

  • 跨平台:兼容 GCC、IAR、Clang、Green Hills、Microchip 等嵌入式编译器

  • 易集成:可与 Makefile、CMake、PlatformIO 等构建系统配合使用

📦 资源占用

  • 内存占用:极低,仅几 KB(取决于编译器优化和使用的断言数量)

  • 代码体积:核心代码 < 20KB,适合 8-bit MCU

🛠 示例断言

下面是一步步的详细指南,适合初学者:

🧰 第一步:准备环境

确保你已经在 WSL 中安装了以下工具:

bash

sudo apt update
sudo apt install build-essential git

📦 第二步:下载 Unity 框架

Unity 是由ThrowTheSwitch.org 提供的开源项目,你可以通过 Git 克隆它:

bash

git clone https://github.com/ThrowTheSwitch/Unity.git

你也可以只复制 src/unity.csrc/unity.h 到你的项目中,Unity 的核心就是这两个文件。

🗂️ 第三步:创建你的测试项目结构

推荐的项目结构如下:

my_project/
├── src/              # 你的源代码
│   └── calculator.c
├── test/             # 测试代码
│   └── test_calculator.c
├── unity/            # Unity 框架代码
│   └── unity.c, unity.h
└── Makefile          # 构建脚本

🧪 第四步:编写测试代码

示例 test/test_calculator.c

c

#include "unity.h"
#include "calculator.h"

void setUp(void) {}    // 每个测试前调用
void tearDown(void) {} // 每个测试后调用

void test_Addition(void) {
    TEST_ASSERT_EQUAL_INT(5, add(2, 3));
}

void test_Subtraction(void) {
    TEST_ASSERT_EQUAL_INT(1, subtract(3, 2));
}

int main(void) {
    UNITY_BEGIN();
    RUN_TEST(test_Addition);
    RUN_TEST(test_Subtraction);
    return UNITY_END();
}

🛠️ 第五步:编写 Makefile

示例 Makefile

makefile

CC = gcc
CFLAGS = -Iunity -Isrc -Itest

SRC = src/calculator.c
TEST = test/test_calculator.c
UNITY = unity/unity.c

TARGET = test_runner

all:
    $(CC) $(CFLAGS) $(SRC) $(TEST) $(UNITY) -o $(TARGET)
    ./$(TARGET)

clean:
    rm -f $(TARGET)

🚀 第六步:运行测试

在项目根目录下运行:

bash

make

你将看到类似输出:

test/test_calculator.c:10:test_Addition:PASS
test/test_calculator.c:14:test_Subtraction:PASS
-----------------------
2 Tests 0 Failures 0 Ignored
OK
CH341A编程器是一款广泛应用的通用编程设备,尤其在电子工程和嵌入式系统开发领域中,它被用来烧录各种类型的微控制器、存储器和其他IC芯片。这款编程器的最新版本为1.3,它的一个显著特点是增加了对25Q256等32M芯片的支持。 25Q256是一种串行EEPROM(电可擦可编程只读存储器)芯片,通常用于存储程序代码、配置数据或其他非易失性信息。32M在这里指的是存储容量,即该芯片可以存储32兆位(Mbit)的数据,换算成字节数就是4MB。这种大容量的存储器在许多嵌入式系统中都有应用,例如汽车电子、工业控制、消费电子设备等。 CH341A编程器的1.3版更新,意味着它可以与更多的芯片型号兼容,特别是针对32M容量的芯片进行了优化,提高了编程效率和稳定性。26系列芯片通常指的是Microchip公司的25系列SPI(串行外围接口)EEPROM产品线,这些芯片广泛应用于各种需要小体积、低功耗和非易失性存储的应用场景。 全功能版的CH341A编程器不仅支持25Q256,还支持其他大容量芯片,这意味着它具有广泛的兼容性,能够满足不同项目的需求。这包括但不限于微控制器、EPROM、EEPROM、闪存、逻辑门电路等多种类型芯片的编程。 使用CH341A编程器进行编程操作时,首先需要将设备通过USB连接到计算机,然后安装相应的驱动程序和编程软件。在本例中,压缩包中的"CH341A_1.30"很可能是编程软件的安装程序。安装后,用户可以通过软件界面选择需要编程的芯片类型,加载待烧录的固件或数据,然后执行编程操作。编程过程中需要注意的是,确保正确设置芯片的电压、时钟频率等参数,以防止损坏芯片。 CH341A编程器1.3版是面向电子爱好者和专业工程师的一款实用工具,其强大的兼容性和易用性使其在众多编程器中脱颖而出。对于需要处理25Q256等32M芯片的项目,或者26系列芯片的编程工作,CH341A编程器是理想的选择。通过持续的软件更新和升级,它保持了与现代电子技术同步,确保用户能方便地对各种芯片进行编程和调试。
内存分区情况的分析是嵌入式系统开发中的一个重要环节,特别是在资源有限的MCU(微控制器)环境中。标题提到的工具是一款专为分析Linux环境下的`gcc-map`文件设计的工具,这类文件在编译过程结束后生成,包含了程序在目标设备内存中的布局信息。这个工具可以帮助开发者理解程序在RAM、ROM以及FLASH等存储区域的占用情况,从而进行优化。 `gcc-map`文件通常包含以下关键信息: 1. **符号表**:列出所有定义的全局和静态变量、函数以及其他符号,包括它们的地址和大小。 2. **节区分配**:显示每个代码和数据节区在内存中的位置,比如.text(代码)、.data(已初始化数据)、.bss(未初始化数据)等。 3. **内存汇总**:总览所有节区的大小,有助于评估程序的整体内存需求。 4. **重定位信息**:显示了代码和数据如何在目标地址空间中定位。 该分析工具可能提供以下功能: 1. **可视化展示**:将内存分配以图形化方式呈现,便于直观理解。 2. **详细报告**:生成详细的分析报告,列出每个符号的大小和位置。 3. **比较功能**:对比不同编译版本或配置的`map`文件,查看内存使用的变化。 4. **统计分析**:计算各种内存区域的使用率,帮助识别潜在的优化点。 5. **自定义过滤**:允许用户根据需要筛选和关注特定的符号或节区。 虽然在MCU环境中,Keil IDE自带的工具可能更方便,因为它们通常针对特定的MCU型号进行了优化,提供更加细致的硬件相关分析。然而,对于通用的Linux系统或跨平台项目,这款基于`gcc-map`的分析工具提供了更广泛的适用性。 在实际使用过程中,开发者可以利用这款工具来: - **优化内存使用**:通过分析哪些函数或数据占用过多的内存,进行代码重构或调整链接器脚本以减小体积。 - **排查内存泄漏**:结合其他工具,比如动态内存检测工具,查找可能导致内存泄漏的部分。 - **性能调优**:了解代码执行时的内存分布,有助于提高运行效率。 - **满足资源限制**:在嵌入式系统中,确保程序能在有限的内存空间内运行。 总结来说,`gcc-amap`这样的工具对于深入理解程序的内存布局和资源消耗至关重要,它能帮助开发者出更明智的决策,优化代码以适应不同的硬件环境。在处理`map`文件时,开发者不仅能获取到程序的内存占用情况,还能进一步挖掘出可能的优化空间,从而提升系统的整体性能和效率。
### 如何在 Unity 中实现针对嵌入式系统的单元测试 #### 使用 Ceedling 构建环境 为了有效地进行嵌入式系统的单元测试,Ceedling 提供了一个完整的解决方案。该工具基于 Ruby 的 Rake 构建系统,能够简化项目的配置、代码生成以及测试执行流程[^1]。 #### 编写测试案例 编写测试案例时,开发者应遵循特定结构来确保可读性和维护性。对于每一个待测函数 `function_to_test`,创建对应的测试文件 `test_function_to_test.c` 并导入必要的头文件: ```c #include "unity.h" #include "../src/function_to_test.h" void setUp(void) { // 初始化操作前设置 } void tearDown(void) { // 清理工作后置处理 } ``` #### 测试具体功能 假设有一个简单的加法器函数 `add(int a, int b)` 需要被验证其行为是否正确,则可以在相应的测试文件中定义如下形式的方法来进行断言检查: ```c void test_add_should_return_sum_of_two_integers(void){ TEST_ASSERT_EQUAL_INT(7, add(3, 4)); } ``` 这里使用了 `TEST_ASSERT_EQUAL_INT()` 宏来比较预期的结果与实际返回值之间的差异;如果两者相匹配则表示此次调用成功通过了检验。 #### 处理外部依赖关系 当目标函数存在对外部资源或其它组件的引用时,可以通过引入 CMock 来模拟这些接口的行为模式而不必真正连接物理设备或其他复杂逻辑层面上的对象实例化过程[^2]。这有助于提高测试效率并减少不必要的干扰因素影响最终结论准确性。 #### 执行全部测试套件 完成上述准备工作之后,在终端窗口内切换至项目根目录位置并通过运行命令 `ceedling test:all` 启动整个批次内的所有测试任务。此时会依次经历编译源码片段、链接对象文件直至最后输出汇总报告等一系列动作步骤。 ```bash $ cd /path/to/project_root_directory $ ceedling test:all ``` 一旦所有指定条件均满足无误的情况下,将会看到类似于下面这样的总结信息展示于屏幕之上: ``` -------------------- OVERALL TEST SUMMARY -------------------- TESTED: X PASSED: Y FAILED: Z IGNORED: W ``` 其中X代表总共参与评估过的次数统计量;Y指代顺利过关的数量记录;Z对应失败情形下的计数结果;而W则是那些标记为忽略状态条目的集合体现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值