嵌入式C单元测试框架unity-初体验

描述

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

嵌入式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目录下,这一部分是测试代码

mcu

配置头文件包含路径

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

mcu

依赖

默认依赖打印输出函数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_DECLARATION


extern void UNITY_OUTPUT_CHAR_HEADER_DECLARATION;


#endif


#endif

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

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

mcu

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

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

比如MDK工程中设置

mcu

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

测试1

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

代码中

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

mcu

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

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

运行程序打印如下

test/TestProductionCode.c:20:test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode:PASS


test/TestProductionCode.c:33:test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken:FAIL: Expected 1 Was 0


test/TestProductionCode.c:41:test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue:PASS


test/TestProductionCode.c:51:test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain:PASS


test/TestProductionCode.c:61:test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed:FAIL: Expected 0x00001234 Was 0x00005A5A


-----------------------


5 Tests 2 Failures 0 Ignored


FAIL

mcu

测试2

使用带2的代码

mcu

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 Purpose


test/TestProductionCode2.c:25:test_AnotherIgnoredTest:IGNORE: These Can Be Useful For Leaving Yourself Notes On What You Need To Do Yet


test/TestProductionCode2.c:30:test_ThisFunctionHasNotBeenTested_NeedsToBeImplemented:IGNORE


-----------------------


3 Tests 0 Failures 3 Ignored


OK

mcu

总结

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

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分