其他
【连载】嵌入式测试驱动开发(2)
/***简单说点东西***/
可能大部分工程师私底下都会传递着这样一句话“代码三分写七分调”,可想而知大部分工程师他们花费在调试程序的时间上面是非常长的,那么既然代码是我们写的,我们有没有办法谢写代码的同时,能够尽量减少或者避免bug,同时也缩短了调试时间了,那么测试驱动程序的开发就为这种问题的解决提供了提供了可能!
那么我们如何进行测试驱动开发呢?对所要进行测试的产品代码又应该具有怎样的要求呢?下面我们将为读者一解答这个问题,并且一个实例来进行描述!
/***程序的模块化***/
我们上一小节说过,测试驱动程序开发能够减少代码的耦合,并且代码的可移植性更好;其中最主要的一点就是需要被测代码具有一个比较好的模块化设计。比如说最简单的我们所写的加法函数是一个运算的一个封装,我们便能够通过调用测试软件框架中的函数直接进行测试!那么我们进行模块化设计需要注意哪些呢?
1)首先第一点我们需要抽象数据类型,
方法1:我们可以在对应的.c文件中把数据定义为静态变量,然后再对应的. h文件通过相应的函数接口供外部使用!
方法2:会把数据定义为一个结构体指针,各个模块的数据都需要在这个结构体指针中提取,比如说定义了一个定义了一个车子的属性结构体指针typedef struct _tag_Car *pCar;那么我们要过得车子的最快速度speed成员,我们只需要封装一个函数uint16_t sGetCarSpeed(pCar car);这样我都传入我们的数据指针便可以过得对应的的小车速度!方法二的主要的作用就是为了隐藏数据!
2)把.c文件作为接口的实现,把.h文件作为我们的接口文件!同时注意需要有相关对模块类数据进行初始化以及清理的函数!
3)测试文件单独作为一个模块,为了保证测试代码与产品代码分离。
如果我们模块化设计能够注意以上几点便能够更好的进行接下来的测试驱动程序开发!
/***开始测试驱动开发***/
1)首先我们需要明确我们模块或者是任务的一个需求,并且构造一张测试列表,比如说我们需要写一个LED驱动程序,现在两个LED灯,1、LED灯能独立控制;2、LED灯能亮灭;3、能够读取LED状态。先简单的实现这三个测试!(那么以后假如说我们要实现一个非常比较复杂的测试项目,就需要把测试项目分解成更多小的测试来进行测试)。测试列表越是全面,最终输出的代码质量应该是越高!
2)unity测试框架下的led驱动程序伪代码,
//创建一个led驱动测试组
TEST_GROUP(led_drv)
TEST_SETUP(led_drv){
//建立测试驱动相关资源初始化
}
TEST_TEAR_DOWN(led_drv){
//释放测试驱动相关资源
}
TEST(led_drv,ledtest){
//测试失败,测试代码
TEST_FAIL_MESSAGE("led test fail");
}
TEST_GROUP_RUNNER(led_drv){
RUN_TEST_CASE(led_drv,ledtest);
}
void RunAllTests(void){
RUN_TEST_GROUP(led_drv);
}
最后我们在主程序中调用最终unity函数
UnityMain(argc,argv,RunAllTests);
这样我们最终不过串口来输出相关的调试信息,比如说有多少个错误,有多少个警告,有多少个测试是否成功等等。让我们上面的伪代码程序就会输出1 test,1 fail,0 ignred,这里我就不一一列举!大家可以自行在开发版中使用unity测试框架测试输出!
嗯,最后总结一下,就如上一节所说的,其实只要明确了测试的项目,我们只需要使用测试软件框架进行测试即可!相对还是比较简单!所以重点还是放在我们的模块号设计上和我们的测试需求上面!
我们可能有时候还要想一想,说我们要测试一个LED点亮了,如何在测试驱动程序中体现呢?那还需要我们用眼睛观察以后然后手动输入吗?显然不是!我们下期继续将为大家讲解这部分的内容!
好了,这里是公众号“最后一个bug”,我是未知bug,感谢各位的关注,也欢迎各位评论留言!谢谢!