我想使用Google Tests为我的嵌入式应用程序软件编写单元测试。
这些测试将在用C编写的应用软件上执行。应用软件使用的驱动程序(例如I2C
,SPI
),故障Assert用C语言编写。我的问题是:
1.从哪里开始比较好?我指的是我可以阅读的资源,以了解更多关于在嵌入式环境中使用Google Test的信息。
1.我该如何模拟我的驱动程序文件?例如,如果我有一个void read(uint8_t address)
函数,在我的I2C库中,我如何模拟这个函数,以便在我的C类中调用这个特定的函数?
1.这些用C编写的驱动程序文件也包含在我的C文件中。我试着编译一个裸测试文件,只包括我的C类头,并有编译问题,因为编译器找不到驱动程序头。如何避免此问题?
1.使用代码管理失败的Assert-在我的驱动程序库中失败的Assert,需要系统重置。如何在测试中模拟这一点?
2条答案
按热度按时间ryevplcw1#
我最近使用gTest(GoogleTest)为Arm Cortex-M3内核测试了一个FAT文件系统和引导加载程序实现,所以我将留下我的两分钱。
嵌入式软件测试存在无法通过模拟来复制硬件环境的问题。我做了三组测试:
A)单元测试(我在TDD中使用的)在我的PC上运行**。我使用这些测试来开发我的应用程序逻辑。这就是我需要嘲笑/戳的地方。我的公司使用硬件抽象层(HAL),这是我嘲笑的。如果你想写可测试的代码,最后一点是基本的。
不要直接访问寄存器,使用一个简单的HAL封装函数,它可以被模仿:
后者是可测试的,因为您将模拟
set_bit
函数,从而打破对硬件的依赖。B)对目标进行单元测试。这是一个比(A)小得多的测试集,但它仍然很有用,特别是在测试驱动程序和HAL函数时。这些测试背后的想法是,我可以正确地测试我将要模拟的函数。因为它在目标上运行,所以我需要它尽可能简单和轻量级,所以我使用MinUnit,这是一个C头文件。我已经在Cortex-M3内核和专有DSP代码(没有任何修改)上运行了MinUnit的目标测试。我在这里也使用了TDD。
C)集成测试。我在这里使用Python和Behave来构建、下载并在目标上运行整个应用程序。
回答您的问题:
1.正如其他人已经说过的,从gTest Primer开始,不要担心mock,只要掌握使用gTest的窍门就行了。Cpputest是一个很好的替代方案,它提供了一些内存检查(针对泄漏)。我比较喜欢使用gTest语法来派生设置类。Cpputest可以运行用gTest编写的测试。两者都是很好的框架。
1.我使用Fake Function Frakework来模拟和存根。它使用起来非常简单,并且它提供了一个好的mocking框架所期望的一切:设置不同的返回值、传递回调、检查参数调用历史等。我想给予Ceedling一个机会。到目前为止,FFF一直很棒。
1.我不会那么做的我用C编译器(在我的例子中是g)编译测试框架和我的测试,用C编译器(gcc)编译我的嵌入式代码,然后将它们链接在一起。从下面的例子中,你会看到我没有在C文件中包含C++头文件。在链接测试时,除了要模拟的函数的C源文件之外,您将链接所有内容。
使用代码管理失败的Assert-在我的驱动程序库中失败的Assert,需要系统重置。如何在测试中模拟这一点?
我会模仿reset函数,为“reset”添加一个回调函数。
假设您想要测试一个使用
read
函数的read_temperature
函数。下面是一个使用FFF进行模拟的gTest示例。hal_i2c.h
read_temperature.h
read_temp.c
test_i2c.cpp
对于包含测试类的更复杂的测试场景,可以在
SetUp()
方法中调用RESET_FAKE
。希望这有帮助!干杯!
cmssoen22#
1.我不知道有什么特别的参考资料可以用来使用Gtest进行裸机目标测试,但是一般来说,一个好的开始是阅读Gtest Primer,根据你的软件架构,甚至可能是Gmock documentation。后者在测试应用程序相关类而不仅仅是低级驱动程序时可能会很有用。
根据您当前是为目标平台还是测试平台进行编译,您可以使用其中的任何一个。
另一种选择是将C实现提升到C++,并为驱动程序编写一个类 Package 器。这将使您受益于C++的功能,并使用依赖注入,继承,CRTP等。