如何对嵌入式代码进行单元测试?

How to make unit tests for embedded code?

本文关键字:单元测试 代码 嵌入式      更新时间:2023-10-16

我正在为C++的基于Cortex-M4的微控制器开发软件。我有很多高度依赖机器的代码(驱动程序等(。我有更高级的代码,它通过直接使用驱动程序紧密依赖于低级代码。示例:低级部分是例如。一个非常特定于硬件的UART驱动程序,一个高级部分是基于UART的通信协议。(该软件在"裸机"上运行,即下面没有操作系统。

此代码当前是紧密耦合的,因此不可进行单元测试。
我想让它可测试。

所以我想我应该创建一个低级部分的抽象,并使高级部分只依赖于抽象。然后,我可以创建单元测试将使用的抽象的模拟,以及在微控制器上运行的真实实现。

  • 这是一种正确的方法吗?
  • 如何创建这样的抽象?
    我发现的大多数来源都强烈反对在嵌入式系统中使用继承和virtual函数。还有什么其他方法?

所以,总而言之,我想创建一个硬件抽象层(HAL(,但我问怎么做?我应该在C++中使用virtual继承,还是有其他更好的方法?

对于C++,我建议使用一个接口,假设我们有一个HAL.hpp,在那里我们定义我们想要实现的纯虚拟函数:

class HAL
{
virtual void func1() = 0;
virtual void func2() = 0;
};

然后你可以让你的Mock.cpp实现这个,你可以有一个Real.cpp实现相同的:

Mock.cpp:
class Mock : HAL
{
virtual void func1(){ }
virtual void func2(){ }
}

现在另一种方法是你定义你的函数,就像HAL.h一样,在这里不提供任何实现:

void func1();
void func2();

然后,创建一个HAL.cpp,并在其中添加您希望在目标上看到的功能。将所有这些创建为称为 HAL 的库。将此库链接到主项目。

现在进行模拟和测试。为测试创建单独的项目。添加要测试但不链接 HAL 库的源。而是创建另一个源文件 Mock.cpp包含 HAL.h 并为其提供实现。通过这种方式,将调用 Mock 的实现,而不是来自 HAL 库的功能。

在模拟 HAL 的单独文件中创建微控制器 HAL。对于微控制器,请在项目中包括微控制器 HAL 源。对于单元测试系统,请在项目中包括模拟 HAL 源。

您还可以使用编译器宏定义在模拟 HAL 的各个部分切换,并切换出微控制器 HAL 的各个部分,从而在目标上进行测试。

您甚至可以使用调试器强制接口点上的值触发所有路径;使用代码覆盖率工具执行此操作会让您知道您是否已经执行了所有路径(如果需要,还可以使用 MC/DC(。这有时是模拟硬件故障或异常情况的唯一方法。