分享几个嵌入式软件单元测试框架_第1页
分享几个嵌入式软件单元测试框架_第2页
分享几个嵌入式软件单元测试框架_第3页
分享几个嵌入式软件单元测试框架_第4页
分享几个嵌入式软件单元测试框架_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

作为一名合格的嵌入式软件工程师,不仅需要写业务代码,还需

要写单元测试代码,这个时候,有一套单元测试框架就显得尤为重要。

软件开发中,每次需求的变更基本都需要改写代码,而代码变更

后就需要进行功能测试。

当然,在功能测试之前需要代码的单元测试,避免代码改动后部

分场景没有验证,最后出现各种问题。

通过测试框架快速完成代码的单元测试,不仅可以覆盖之前测试

的场景,也能快速反应问题在哪里。

常用的C语言测试框架有:

•Unity:一个小型的,开源的C语言测试框架,提供了用于测试

的基本结构和函数。简单好用,常用于嵌入式系统开发。

•CUnit:一个面向C语言测试的框架,使在简单,支持自动化测

试和手动测试。

•Check:适用于C语言的单元测试框架,使用简单,支持测试套

件,测试用例的管理,便于维护测试组件V

•GoogleTest:Google推出的C++测试框架,支持C语言,可以

跨平台,具有丰富的断言库和Mocks。

•cmocka:适用于C语言的单元测试框架,支持内存泄漏检测,

支持Mock函数和Stub函数等高级用法。

•criterion:基于C语言的单元测试框架,支持参数化测试和测

试用例依赖,具有良好的性能和易用性。

、Unity示例

这里介绍Unity,其他的大家感兴趣可以自行查阅,不同的单元

测试框架适用于不同的开发需求和场景。开发人员可以按照自己的项

目要求选择最适合的框架。

Unity最小可以只用到几个文件即可完成,把Unity源码目录下

的unity.。、unity.h、unit:y_internals.h三个文件复制至我

们的工程目录下进行编译即可,然后在测试文件代码中包含

unity.h

简单的示例

完成功能函数的验证:

「「____d」,::二L:.

|voidtearDovm()

//这里可以放置每个测试用例运行后的清理代码

|intAdd(inta,int匕)

returna+b

|voidtest_AddFun(void)

TEST_ASSERT_EQUAL_U工NT(6,Add(l,5));

TESTASSERTEQUALUINT(4,Add

TEST_ASSERT_EQUAL_UINT(-6,Add(-1,-5));

|intmain()|

UNITY_BEGIN();〃启动测试

RUN_TEST(test_AddFun);■

।:''ri:;

通过串口或终端打印内容为:

其中,自定义实现的C语言扩展库(cot)的容器功能函数都已

通过Unity添加了对应的单元测试用例,链接:

https://gitee.com/ccnst-zpc/cot

2、轻量级通用扩展库|

旨在打造一个C语言的通用扩展库。

1、介绍

支持多种容器实现,包括通用队列(包括不定长队列)、栈、双

向链表和动态数组功能

双向链表节点可动态创建(需要在初始化分配内存)或静态添加

动态数组在初始化分配的内存中最大限度地使用,支持随机访问(连

续地址)

支持定义序列化/反序列化的结构体功能

使用到了Boost库中的PP库功能宏语法:确保两边都需要保持

义文件结构体定义一致

移植了部分C++Boost库中的PP库功能

通过宏语法实现复杂的宏语言,灵活进行使用,在编译的时候生

成自己期望的代码

2、软件架构

目录说明:

cot

1—include

1—container//容器实现头文件

|—preprocessor//移植Boost库中的PP库头文件

||Lserialize//序列化/反序列化实现头文件

1—src

(—container//容器实现源文件

「serialize//序列化/反序列化实现源文件

|—test

(—container//容器实现测试代码

serialize//序列化/反序列化测试代码

Lunity//单元测试框架代码

3、使用说明

(1)容器类功能使用说明

双向链表使用方式demo:

intmain()

{

cotList_tlist;

cotListItem_tnodeBuf[10];

cotList_Init(&list,nodeBuf,10);

intdatal=10;

intdata2=20;

intdata3=30;

//头部增加元素

cotList_PushFront(&list,&datal);

//尾部增加元素

cotList_PushBack(&list,&data2);

//插入元素

cotList_Insert(&list,cotList_End(&list),&data3);

//使用迭代器遍历所有元素

for_list_each(item,list)

{

printf("=%d\n",*item_ptr(int,item));

)

//移除指定元素

cotList_Remove(&list,&data3);

//根据添加移除元素

cotList_RemoveIf(&list,OnRemoveCondition);

cotList_tlist2;

cotListItem_tnodeBuf2[3];

cotList_Init(&list2,nodeBuf2,3);

//链表内存交换

cotList_Swap(&listl,&list2);

return0;

动态数组使用方式demo:

intmain()

uint8_tbuf[20];

cotVector_tvector;

cotVector_Init(&vector?buf,sizeof(buf),sizeof(uint32_t));

//在尾部追加兀索

uint32_tdata=42;

cotVector_Push(&vector,&data);

data=56;

cotVector_Push(&vector,&data);

data=984;

cotVector_Push(&vector,&data);

//插入元素

uint32_tarrdata[2]={125,656};

cotVector_InsertN(&vector,2,&arrdata,2);

//删除两个元素

cotVector_RemoveN(&vector,1,2);

//根据添加删除元素

cotVector_RemoveIf(&vector,OnVectorRemoveCondition);

//打印数组中的数据内容

for(inti=0;i<cotVector_Size(&vector);i++)

printf("%02x",cotVector_Data(&vector)[i]);

}

return0;

}

双向队列(定长FIFO)使用方式demo:

intmain()

(

uint8_tbuf[10];

cotQueue_tqueue;

cotQueue_Init(&queue,buf,sizeof(buf),sizeof(int));

//在尾部追加元素

intdata=42;

cotQueue_Push(&queue,&data,sizeof(data));

data=895;

cotQueue_Push(aqueue,&data,sizeof(data));

//访问元素

int*pData=(int*)cotQueue_Front(&queue);

printf("val=%d\n",*pData);

//弹出首个元素

cotQueue_Pop(&queue);

return0;

队列(不定长FIFO)使用方式demo:

intmain()

uint8_tbuf[10];

cotIndQueue_tqueue;

cotIndQueue_Init(&queue,buf,sizeof(buf));

//在尾部追加元素

chardata=42;

cotIndQueue_Push(&queue,&data,sizeof(data));

intdatal=80;

cotIndQueue_Push(&queue,&data,sizeof(datal));

longdata2=-400;

cotIndQueue_Push(&queueJ&data,sizeof(data2));

〃访问兀素

size_tlength;

int*pData=(int*)cotIndQueue_Front(&queue,&length);

printf("val=%d\n",*pData,length);

//弹出首个元素

cotIndQueue_Pop(&queue);

return0;

单向栈使用方式demo:

intmain()

uint8_tbuf[10];

cotStack_tstack;

cotStack_Init(&stack,buf,sizeof(buf),sizeof(int));

//在顶部追加元素

intdata=42;

cotStack_Push(&stack,&data,sizeof(data));

data=895;

cotQueue_Push(&stack,&data,sizeof(data));

//访问元素

int*pData=(int*)cotStack_Top(&stack);

printf("val=%d\n",*pData);

//弹出顶部元素

cotStack_Pop(&stack);

return0;

}

(2)序列化/反序列化功能使用说明

可以定义一个公共头文件:

#ifndefSTRUCTH

#defineSTRUCTH

#include"serialize/serialize.h"

COT_DEFINE_STRUCT_TYPE(test_t,

((UINT16_T)(vail)(2))

((INT32_T)(val2)(1))

((UINT8,T)(val3)(D)

((INT16_T)(vaK)(D)

((DOUBLE_T)(val5)(D)

((INT16_T)(val6)(D)

((STRING_T)(szName)(100))

((DOUBLE_T)(val7)(D)

((FLOAT_T)(val8)(D)

((STRING_T)(szNamel)(100))

)

#endif//STRUCT_H

各个模块引用头文件使用:

#include"struct.h"

intmain()

{

uint8_tbuf[100];

〃序列化使用demo

COT_DEFINE_STRUCT_VARIABLE(test_t,test);

test.vall[0]=5;

test.vall[l]=89;

test.val2=-9;

test.val3=60;

test.val4=-999;

test.valS=5.6;

test.val6=200;

test.val7=-990.35145;

test.val8=-80.699;

sprintf(test.szName,"test56sgdgdfgdfgdf");

sprintf(test.szNamel,"sdfsdf");

intlength

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论