编码注意事项
以上是从测试角度讨论如何建立单元测试执行环境的几种方案和测试策略的制定,不过,为单元测试的实施奠定坚实的基础的还是良好的程序设计。接下来从代码编写角度列举提高嵌入式软件的可测性的几点经验教训:
1、与硬件设备操作相关的需要与硬件操作无关的代码分离,这样与硬件操作相关的驱动代码可以独立在目标板上测试,当然逻辑简单也可不作测试;大部分与硬件操作无关的代码就容易实现跨平台移植测试。
2、中断响应函数功能尽量简单,这是因为中断响应相对不好测试,如果代码复杂,也不易定位错误,因为很多的开发环境或操作系统难以支持中断响应函数的断点调试。
3、系统调用及操作系统相关的操作做到与应用层分离,可以通过中间函数实现,比如虚拟操作系统函数,这样跨平台移植测试的时候只需将这些中间层函数修改就可以实现。
4、对数据类型的差异性也可通过宏定义来实现统一,对于库文件的差异也通过宏定义来实现上层代码的一致性。
5、使用静态代码检测工具,比如PC-Lint,以尽早发现代码缺陷。PC-Lint是在代码产生初期静态查找代码缺陷,更有利用错误定位和修改,因为软件开发阶段越早发现问题,解决问题花费的代价越小。因此,一般应该是静态检查通过后再实施动态测试。
嵌入式软件单元测试也是基于普通软件单元测试的理论,仍需遵守,以上是对嵌入式软件单元测试特别之处的经验总结,希望能对初涉嵌入式软件开发的朋友有所帮助,重视软件质量,提高嵌入式系统的可靠性。
void test_ xxx_driver (void) // 测试xxx驱动函数 { typedef struct _TEST_CASE // 测试用例结构体 { UINT8* pBuf; //读写缓冲区指针 int len; //读写数据长度 STATUS result; // 测试结果,OK或ERROR } TESTCASE; #define TEST_NUM 4 // 测试用例数 UINT8* rBuf; TESTCASE testCase[TEST_NUM]={ {0,DATA_MAX_LEN+1,ERROR}, // DATA_MAX_LEN指允许读写的最大长度 {"a",1,OK}, {"12",2,OK}, {0,DATA_MAX_LEN,OK} }; for (int i=0;i< TEST_NUM;i++) { if(write(testCase[i].pBuf,testCase[i].len) != testCase[i].result) // 写测试 LOG ("test write failed!"); if(read(rBuf,testCase[i].len) != testCase[i].result) // 读测试 LOG ("test read failed! "); if(bcmp(testCase[i].pBuf,rBuf,testCase[i].len) != 0) // 比较读写数据 LOG ("compare data failed! "); } } |