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
。
问题
- 用cmocka实现测试隔离的唯一方法是将每个测试分离到自己的可执行文件中吗?
当我发现发生这种情况时,我感到很震惊。我是 C 和 C 测试的新手,我一直认为测试隔离是单元测试框架的关键部分。对我来说,为什么一开始会有测试组是没有意义的,因为大多数时候你将测试带有依赖关系的代码,其中在某处使用静态变量,因此每次测试都会生成一个可执行文件。
是的,如果你在测试对象中有一个静态变量,如果他们需要一个“新的”测试对象,你需要编译单独的测试。
无论如何我都会这样做,每个测试都在一个单独的可执行文件中,因为您的测试对象中有一个 Singleton。
这是单例模式今天 anti-pattern 的一个很好的例子。很难测试。
失败
给定以下带有依赖项中的静态变量的 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
。
问题
- 用cmocka实现测试隔离的唯一方法是将每个测试分离到自己的可执行文件中吗?
当我发现发生这种情况时,我感到很震惊。我是 C 和 C 测试的新手,我一直认为测试隔离是单元测试框架的关键部分。对我来说,为什么一开始会有测试组是没有意义的,因为大多数时候你将测试带有依赖关系的代码,其中在某处使用静态变量,因此每次测试都会生成一个可执行文件。
是的,如果你在测试对象中有一个静态变量,如果他们需要一个“新的”测试对象,你需要编译单独的测试。
无论如何我都会这样做,每个测试都在一个单独的可执行文件中,因为您的测试对象中有一个 Singleton。
这是单例模式今天 anti-pattern 的一个很好的例子。很难测试。