我想用谷歌测试为我的嵌入式应用软件编写单元测试。
这些测试将在应用软件上执行,应用软件是用C++编写的。应用软件使用的驱动程序(如。I2C,SPI),错误断言是用C编写的。我的问题是:
void read(uint8_t address)库中有一个I2C函数,我如何模拟这个函数,以便在我的C++类中调用这个特定的函数?发布于 2020-12-10 16:40:44
最近,我用gTest (GoogleTest)测试了一个用于Arm Cortex-M3内核的FAT文件系统和引导加载器实现,所以我将留下我的两分钱。
嵌入式软件测试存在这样的问题:不可能通过模拟复制HW环境。我想出了三套测试:
( A)在我的PCTDD上运行的单元测试(我在中使用)。我使用这些测试来开发应用程序逻辑。这就是我需要嘲弄/固执的地方。我的公司使用硬件抽象层(HAL),这正是我所嘲笑的。如果您想要编写可测试的代码,这最后一点是基本的。
/* this is not testable */
my_register->bit0 = 1;
/* this is also not testable */
*my_register |= BIT0;不要直接访问寄存器,使用可以模拟的简单HAL包装器功能:
/* this is testable */
void set_bit(uint32_t* reg, uint8_t bit)
{
*reg |= bit;
}
set_bit(my_register , BIT0);后者是可测试的,因为您将模拟set_bit函数,从而打破了对HW的依赖。
( B)对目标进行单元测试。这是一个比(A)小得多的测试集,但是它仍然非常有用,特别是对于测试驱动程序和HAL函数。这些测试背后的想法是,我可以正确地测试我将要模拟的函数。因为这是在目标上运行的,所以我需要尽可能简单和轻量级,所以我使用MinUnit,它是一个单一的C头文件。我在Cortex-M3核和专有的DSP代码上运行了MinUnit的目标测试(没有任何修改)。我在这里也用过TDD。
( C)综合测试。我使用Python并在这里进行操作,在目标上构建、下载和运行整个应用程序。
回答你的问题:
使用我的驱动程序库中的失败断言管理失败的断言,调用系统重置。我怎样才能在测试中模仿这个呢?
我会嘲笑重置函数,添加一个回调到“重置”您需要的任何东西。
假设您想测试使用read_temperature函数的read函数。下面是一个使用FFF进行模拟的gTest示例。
hal_i2c.h
/* HAL Low-level driver function */
uint8_t read(uint8_t address);read_temperature.h
/* Reads the temperature from the I2C sensor */
float read_temperature(void);read_temp.c
#include <hal_i2c.h>
float read_temperature(void)
{
unit8_t raw_value;
float temp;
/* Read the raw value from the I2C sensor */
raw_value = read(0xAB);
/* Convert the raw value */
temp = ((float)raw_value)/0.17+273;
return temp;
}test_i2c.cpp
#include <gtest/gtest.h>
#include <fff.h>
extern "C"
{
#include <hal_i2c.h>
#include <read_temperature.h>
}
DEFINE_FFF_GLOBALS;
// Create a mock for the uint8_t read(uint8_t address) function
FAKE_VALUE_FUNC(uint8_t , read, uint8_t);
TEST(I2CTest, test_read) {
// This clears the FFF counters for the fake read() function
RESET_FAKE(read);
// Set the raw temperature value
read_fake.return_val = 0xAB;
// Make sure that we read 123.4 degrees
ASSERT_EQ((float)123.4, read_temperature());
}对于具有测试类的更复杂的测试场景,可以在RESET_FAKE方法中调用SetUp()。
希望这能有所帮助!干杯!
发布于 2020-03-06 12:14:32
- ic2.c
- i2c\_x86.cpp取决于您当前是否正在为目标或测试平台进行编译,您可以使用它们中的任何一种。
另一种选择是将C实现提升到C++,并在驱动程序周围编写类包装器。这将允许您从C++特性中获益,并使用依赖注入、继承、CRTP等.
// 2 byte message does not fit 14bit, assertion triggered
ASSERT_DEATH(encode_datagram(make_datagram(0, 64, 0)), ".*");https://stackoverflow.com/questions/60552301
复制相似问题