当前位置: 首页 > 资讯 >
嵌入式C单元测试框架unity-初体验
2023-06-08 13:10:07   来源:嵌入式USB开发

本文转自公众号,欢迎关注

嵌入式C单元测试框架unity-初体验 (qq.com)

前言

嵌入式领域,尤其是MCU领域,一般很少有使用单元测试框架,一般就是开发阶段开发人员按照自己的习惯和经验进行自测,然后就是系统集成测试,所以一般在单元测试这一环做的不是很规范。实际上我们在开发中应该要改善这种现状,加强单元测试的管理,避免单元测试纯凭开发人员是否有时间做,做到什么程度也是随缘。应该由测试来保证开发质量,避免依赖于个人,并且积累测试用例库,这样有助于产品迭代稳定,尤其是在BSP等领域,有一个好的测试框架和测试用例集能很好的完成芯片的验证,和生产测试等工作。


【资料图】

恰好有这样一个框架,专为嵌入式领域纯粹的C测试而生-unity,使用ANSI C编写,移植性好,资源占用少,就一个C文件和h文件,可以通过h进行一些配置,特别适合MCU开发等领域。

官网

http://www.throwtheswitch.org/

http://www.throwtheswitch.org/unity

下载源码

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

或者

https://github.com/ThrowTheSwitch/Unity/archive/master.zip

使用

http://www.throwtheswitch.org/unity

这个页面可以看到基本的介绍,浏览一下就知道个大概了,

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

下的README.md也可以先看一下。

先不管细节,不需要了解很多,不管三七二十一先用了再说。

这里使用某个MCU的开发板,MDK环境进行测试。

我们这里使用源码中的example_1进行测试。

添加代码

将下载的源码Unity\\src下的unity.c,unity.h,unity_internals.h

Unity\\examples下的unity_config.h

放到自己工程的unity目录下,这一部分是unity源码

Unity\\examples\\example_1\\src下的所有文件放置到自己工程的src目录下,这一部分是用户代码需要测试的

Unity\\examples\\example_1\\test下的所有文件放置到自己工程的test目录下,这一部分是测试代码

配置头文件包含路径

添加上述几个文件夹到头文件包含路径

依赖

默认依赖打印输出函数putchar

见unity_internals.h中

#ifndef UNITY_OUTPUT_CHAR/* Default to using putchar, which is defined in stdio.h */#include < stdio.h >#define UNITY_OUTPUT_CHAR(a) (void)putchar(a)#else/* If defined as something else, make sure we declare it here so it"s ready for use */#ifdef UNITY_OUTPUT_CHAR_HEADER_DECLARATIONextern void UNITY_OUTPUT_CHAR_HEADER_DECLARATION;#endif#endif

我们要根据自己的情况进行移植,

unity_config.h中配置以下宏,其中RS232_putc在我们自己的代码中实现

注意:需要在unity_internals.h中#define UNITY_INCLUDE_CONFIG_H 1

或者在工程配置中定义宏UNITY_INCLUDE_CONFIG_H,才会使用unity_config.h

比如MDK工程中设置

如果已经实现了标准输入输出重定向,有putchar则不需要使能这些宏,直接使用putchar。

测试1

example_1中有两个测试,一个是源码带2的一个是不带2的。

代码中

先将带2的相关代码不进行编译

将TestProductionCode_Runner.c中的main函数名改为testrunner_main

在自己工程的main函数中调用该函数(先 extern int testrunner_main(void);申明下函数)

运行程序打印如下

test/TestProductionCode.c:20:test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode:PASStest/TestProductionCode.c:33:test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken:FAIL: Expected 1 Was 0test/TestProductionCode.c:41:test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue:PASStest/TestProductionCode.c:51:test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain:PASStest/TestProductionCode.c:61:test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed:FAIL: Expected 0x00001234 Was 0x00005A5A-----------------------5 Tests 2 Failures 0 IgnoredFAIL

测试2

使用带2的代码

TestProductionCode2_Runner.c中main函数名改为testrunner2_main

在自己的代码中调用

testrunner2_main

先 extern int testrunner2_main(void);申明该函数

运行看到输出如下

test/TestProductionCode2.c:20:test_IgnoredTest:IGNORE: This Test Was Ignored On Purposetest/TestProductionCode2.c:25:test_AnotherIgnoredTest:IGNORE: These CanBe Useful For Leaving Yourself Notes On What You Need To Do Yettest/TestProductionCode2.c:30:test_ThisFunctionHasNotBeenTested_NeedsToBeImplemented:IGNORE-----------------------3 Tests 0 Failures 3 IgnoredOK

总结

以上可以看到,unnity进行单元测试十分方便,移植也很简单,先进行一个初体验,后面再详细介绍其使用和设计原理。审核编辑:汤梓红

X 关闭

Copyright ©  2015-2022 生活头条网版权所有  备案号:沪ICP备2022005074号-20   联系邮箱:58 55 97 3@qq.com