对于我的下一个嵌入式系统项目,我想接受单元测试。从技术上讲,它可能不是测试驱动的开发,但我至少想提前对单元测试进行测试,并进行全面的单元测试。
我正在使用IAR EWARM工具链。我正在考虑使用cmocka、unity或cunit。我正在学习使用µC/OS-III作为RTOS。
问题是:单元测试如何使用图中的RTOS?E.G:我应该禁用内核并将代码作为单线程应用程序进行单元测试,并截断所有/大多数内核调用,还是有更好的方法?
示例:在µC/OS-III中,入口点仍然是主要的。从main调用任何init代码,然后调用OSStart()开始多任务处理。因此,当我运行测试线束时,我无法调用OSStart()
#ifdef UNIT_TEST
test_runner();
#else
OSStart(&err);
#endif
然后,在任务中的所有应用程序代码中,我只需要模拟消息传递并延迟对内核的调用。
这是最好的方法吗。或者,我是否更适合启动内核,为我的测试运行程序创建一个任务,并将其中的所有任务作为一个线程运行,或者是否有其他一些好的方法,包括从测试工具中生成其他任务。
您似乎对单元测试有误解。您的代码是否使用RTOS并不相关,因为单元测试涉及到孤立地测试代码模块,即C函数。RTOS在测试期间不会运行。
单元测试还假定您正在针对一组定义代码功能的需求进行测试。大多数单元测试的目标是能够提供各种形式的代码覆盖。这包括语句、决策和多条件决策覆盖。
语句覆盖率表明您已经执行了函数中的每一行代码。
决策覆盖包括显示所有条件的两面(真/假)都被覆盖。
多条件决策覆盖(MCDC)用于测试复杂决策,即如果(a&&(b||c)),并确保覆盖所有变化。MCDC测试通常仅限于非常关键的应用,如航空电子设备,在这些应用中,故障可能会产生灾难性的结果。
子例程通常是存根的,即拦截和控制,以证明每个子例程都是按顺序调用的,并且传递的参数是正确的,并且各种返回值都正常工作。
我承认我对你提到的工具没有任何经验,但有很多商业单元测试工具可用,Cantata、LDRA TestBench、IBM Rational test Real Time和其他适合深度单元测试的工具。
RTOS本身也有商业解决方案。我的公司为µC/OS-II和µC/OSIII提供现成的单元和集成测试包。
斯科特已验证的软件
通常最好将某些抽象层对RTOS特定函数的调用隐藏在自己的软件堆栈中。如果您在哪里更改平台(包括RTOS),这将为您提供更好的可移植性。只需在一个地方更改API调用,就可以开始了。
进行这一步的额外抽象还有一个优点,这与这个答案有关:它使单元测试变得更容易!为了使代码可链接,您可以模拟对RTOS函数的所有调用,以便使用API的一些最小化实现在开发系统上运行测试!根据您的需要,这些模拟对象可以只验证传递的参数是否符合预期。或者对于简单的API调用,您甚至可以实现一些功能来进一步扩展对自己代码的测试。
显然,这仍然不能使您测试具有所有依赖项的整个代码。我想对于嵌入式系统来说,这根本不可能。但与不对使用RTOS API调用的模块进行任何单元测试相比,它已经走了很长的路。