Cmocka - 我们都应该为每个测试创建一个可执行文件来隔离静态变量吗?

Cmocka - should we all be creating one executable per test for isolating static variables?

失败

给定以下带有依赖项中的静态变量的 cmocka 测试:

main.c

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include "dependency.h"

void test1(void** state) {
    increment();
    assert_int_equal(1, get_incrementer());
}

void test2(void** state) {
    increment();
    assert_int_equal(1, get_incrementer());
}

int main() {
    const struct CMUnitTest tests[] = {
        cmocka_unit_test(test1),
        cmocka_unit_test(test2),
    };
    return cmocka_run_group_tests(tests, NULL, NULL);
}

dependency.h

void increment();
int get_incrementer();

dependency.c

static int incrementer = 0;

void increment() {
    ++incrementer;
}

int get_incrementer() {
    return incrementer;
}

(用 gcc main.c dependency.c -lcmocka 和 运行 编译)

我得到以下输出:

[==========] Running 2 test(s).
[ RUN      ] test1
[       OK ] test1
[ RUN      ] test2
[  ERROR   ] --- 0x1 != 0x2
[   LINE   ] --- main.c:14: error: Failure!
[  FAILED  ] test2
[==========] 2 test(s) run.
[  PASSED  ] 1 test(s).
[  FAILED  ] 1 test(s), listed below:
[  FAILED  ] test2

 1 FAILED TEST(S)

这是因为 incrementer 没有在每次测试之间“重置”。

这只是一个证明观点的最小示例。实际上,我的依赖性深入到我在测试中调用的代码中。

让它发挥作用的替代方法

但是,如果我将每个测试分成具有自己的测试组的自己的可执行文件,我就可以像人们期望的那样为每个测试重置 incrementer

问题

当我发现发生这种情况时,我感到很震惊。我是 C 和 C 测试的新手,我一直认为测试隔离是单元测试框架的关键部分。对我来说,为什么一开始会有测试组是没有意义的,因为大多数时候你将测试带有依赖关系的代码,其中在某处使用静态变量,因此每次测试都会生成一个可执行文件。

是的,如果你在测试对象中有一个静态变量,如果他们需要一个“新的”测试对象,你需要编译单独的测试。

无论如何我都会这样做,每个测试都在一个单独的可执行文件中,因为您的测试对象中有一个 Singleton。

这是单例模式今天 anti-pattern 的一个很好的例子。很难测试。