Google 测试带有等待循环的 C 函数

问题描述 投票:0回答:2

我正在为嵌入式 C 应用程序制作单元测试(注意:C,而不是 C++)。这个非常低端的 8 位应用程序不使用线程或 RTOS。相反,我采用了老式的循环任务调度程序。

我使用 Google Test,因为这是这里随时可用的。它适用于我的绝大多数情况,但我遇到了一个特殊情况。

我这里有这个功能:

bool UartPutsWithWait(char *str)
{
    while (sUartData.m_flags.m_TxBusy)
    {
        /* Wait for previous transmission to complete */
    }
    return UartPuts(str);
}   /* UartPutsWithWait */

“TxBusy”标志在目标上的中断例程中设置。 “UartPuts”已成功通过单元测试。

我的问题是:是否有人有一种有用的方法来设置 Google Test(或 Google Mock)以在一两次迭代后设置“TxBusy”标志?

我的目标内存非常有限(高端产品为 8KB 闪存),因此使用线程和/或任务重新实现不太可能是一个有用的答案。

如果所有其他方法都失败了,我将不得不承担无法像我希望的那样彻底地对该特定代码行进行单元测试的风险。

我还注意到,我的 main() 函数中的任务调度程序循环必须进行调整才能允许使用 Google Mock。那,我可以忍受。

c unit-testing googletest
2个回答
0
投票

这里有一个答案提示:http://vandervoord.net/blog/2015/5/19/unit-test-how-infinite-loops

基本上,我在头文件中包含了以下内容:

/** Definition for waiting macro to allow better unit-testing */
#ifdef  GOOGLE_TEST
#define WAIT_FOR_TEST   (googleTestCount-- != 0)
#else   /* !GOOGLE_TEST */
#define WAIT_FOR_TEST   (true)
#endif  /* !GOOGLE_TEST */

然后我将函数修改如下:

bool UartPutsWithWait(char *str)
{
    while ((sUartData.m_flags.m_TxBusy) && (WAIT_FOR_TEST))
    {
        /* Wait for previous transmission to complete */
    }
    return UartPuts(str);
}   /* UartPutsWithWait */

修改前后的快速编译表明我的编译器正确优化了非测试用例。我只需要在包含代码之前声明“googleTestCount”变量即可。

我应该补充一点,我正在通过创建 C++ 单元测试文件来测试 C 模块,然后 #include 其中的 C 文件,如下所示:

#include "gtest/gtest.h"
#include "types.h"
#include "TestRegisters.h"

namespace uart
{
extern "C"
{
#include "uart.c"
}

“types.h”定义了标准 C++ 构建中不可用的类型,而“TestRegisters.h”包含一些用于定义寄存器行为的类以及我正在使用的寄存器的声明。这使我能够对硬件层进行单元测试,而无需循环中的硬件。

当然,我还需要做更多的工作才能准确地模拟行为。


0
投票

自从我发布之前的答案以来,在半小时左右的时间内发生了进一步的细化。

在单元测试文件中,我定义了以下变量:

int googleTestCount = 0;
bool googleTestFlag = false;

然后,我向上面定义的 WAIT_FOR_TEST 宏添加了以下细微的变化:

/** Definition for wait for busy macro to allow better unit-testing */
#ifdef  GOOGLE_TEST
#define WAIT_FOR_BUSY_TEST   ((googleTestCount-- == 0) ? (sUartData.m_flags.m_TxBusy = googleTestFlag, false) : true)
#else   /* !GOOGLE_TEST */
#define WAIT_FOR_BUSY_TEST   (true)
#endif  /* !GOOGLE_TEST */

这个定义允许我等待任意长时间,然后在循环退出时保留标志设置或将其清除。

我还在主循环中的“FOREVER”函数中重用了 WAIT_FOR_TEST 宏,这让我可以根据需要多次运行主循环。

© www.soinside.com 2019 - 2024. All rights reserved.