cgreen 中的多个 Describe()
Multiple Describe() in cgreen
我正在使用 cgreen 为我的 C 代码编写测试,我的问题是:
简短版本:
是否可以在一个文件中放置多个 Describe()
?
长版:
我有不同的测试文件,它们有自己的 Describe()
、BeforeEach()
和 AfterEach()
。因为在这些文件中,我使用了相同的模块,所以我必须将它们编译在一起。 [为了防止编译器多次包含模块,我使用了这个技巧(包含保护)
#ifndef SOME_NAME
#define SOME_NAME
...
#endif
我还有一个包含我所有测试的文件,比方说 all_tests.c
。现在,我想将我的测试文件包含到 all_tests.c
中并将所有内容编译在一起,如下所示:
#include <cgreen/cgreen.h>
#include "./test1.c"
#include "./test2.c"
int main() {
TestSuite *suite = create_test_suite();
add_suite(suite, test1_tests());
add_suite(suite, test2_tests());
return run_test_suite(suite, create_text_reporter());
}
导致这些错误:
error: redefinition of ‘setup’
error: redefinition of ‘teardown’
显然,因为Describe()
、BeforeEach()
和AfterEach()
有多个定义。好吧,我找不到更好的主意,使用推荐的方式
TestSuite *test1_tests();
TestSuite *test2_tests();
不是直接包含文件,而是分别组装和编译每个测试文件,然后将所有文件链接在一起导致此错误:
multiple definition of `some_global_module'
这是意料之中的,因为在链接状态下,有多个some_global_module
的定义。为了清楚起见,test1.c
文件看起来像这样(还有 test2.c
文件,只需在以下代码中将 test1
更改为 test2
):
#include <cgreen/cgreen.h>
#include "./some_global_module.h"
#include "./some_other_module_i_want_to_test1.h"
Describe(test1);
BeforeEach(test1) {
...
}
AfterEach(test1) {
...
}
Ensure(test1, do_something) {
...
}
TestSuite *test1_tests() {
TestSuite *suite = create_test_suite();
add_test_with_context(suite, test1, do_something);
return suite;
}
有什么想法吗?也许我可以使用一些编译器技巧或更简单的方法来管理整个事情?
无法在同一测试文件中包含多个 Describe()
。而且应该没有必要。
您没有准确解释您 assemble 您的 tests/modules 的方式。有几个选项:
#include
测试文件中的模块源 - 这是可能的,但显然你不能 link 多个测试文件在一起,你需要 运行 它们分开,因为它们为被测模块中的所有符号定义了相同的符号。
让测试 "modules" 以与其他用户相同的方式使用被测模块(\#include
并调用 public 接口)。在这种情况下,您的测试文件与其他任何模块一样都是模块,应该 link 与被测模块的单个实例一起编辑。
使用cgreen-runner
。它加载共享库并发现库中的所有测试,从而减轻您记住将每个新测试用例添加到套件的负担。
如果您正在对现有的、不可测试的代码进行改造测试,或者确实需要测试内部结构,则仅使用#1 ,比如 static
函数。
#2 非常标准,可能是您应该做的。在这种情况下,从您的测试文件中删除任何 #include "some_global_module.c"
,就像您在 test1.c
中一样。您的 Makefile
应该类似于:
all: all_tests
all_tests: all_tests.o some_global_module.o \
test1.o some_global_module_under_test1.o \
test2.o some_global_module_under_test2.o
所以 test1.c
和 test2.c
看起来像你指出的那样,以及上面的 Makefile 内容,我不明白为什么你应该在 link 时得到 "multiple definition"。
#3 是我的最爱。 Link 将所有内容放入共享对象库(Linux 上的 .so
)和 运行 cgreen-runner
上。您的 Makefile
应该类似于:
all: all_tests.so
cgreen-runner ./$^
all_tests.so: some_global_module.o \
test1.o some_global_module_under_test1.o \
test2.o some_global_module_under_test2.o
$(LINK) -shared -o $@ $^
注意:如果您的 some_global_module_under_test1
依赖于许多其他模块,您要么也需要 link 它们,要么模拟它们。
我正在使用 cgreen 为我的 C 代码编写测试,我的问题是:
简短版本:
是否可以在一个文件中放置多个 Describe()
?
长版:
我有不同的测试文件,它们有自己的 Describe()
、BeforeEach()
和 AfterEach()
。因为在这些文件中,我使用了相同的模块,所以我必须将它们编译在一起。 [为了防止编译器多次包含模块,我使用了这个技巧(包含保护)
#ifndef SOME_NAME
#define SOME_NAME
...
#endif
我还有一个包含我所有测试的文件,比方说 all_tests.c
。现在,我想将我的测试文件包含到 all_tests.c
中并将所有内容编译在一起,如下所示:
#include <cgreen/cgreen.h>
#include "./test1.c"
#include "./test2.c"
int main() {
TestSuite *suite = create_test_suite();
add_suite(suite, test1_tests());
add_suite(suite, test2_tests());
return run_test_suite(suite, create_text_reporter());
}
导致这些错误:
error: redefinition of ‘setup’
error: redefinition of ‘teardown’
显然,因为Describe()
、BeforeEach()
和AfterEach()
有多个定义。好吧,我找不到更好的主意,使用推荐的方式
TestSuite *test1_tests();
TestSuite *test2_tests();
不是直接包含文件,而是分别组装和编译每个测试文件,然后将所有文件链接在一起导致此错误:
multiple definition of `some_global_module'
这是意料之中的,因为在链接状态下,有多个some_global_module
的定义。为了清楚起见,test1.c
文件看起来像这样(还有 test2.c
文件,只需在以下代码中将 test1
更改为 test2
):
#include <cgreen/cgreen.h>
#include "./some_global_module.h"
#include "./some_other_module_i_want_to_test1.h"
Describe(test1);
BeforeEach(test1) {
...
}
AfterEach(test1) {
...
}
Ensure(test1, do_something) {
...
}
TestSuite *test1_tests() {
TestSuite *suite = create_test_suite();
add_test_with_context(suite, test1, do_something);
return suite;
}
有什么想法吗?也许我可以使用一些编译器技巧或更简单的方法来管理整个事情?
无法在同一测试文件中包含多个 Describe()
。而且应该没有必要。
您没有准确解释您 assemble 您的 tests/modules 的方式。有几个选项:
#include
测试文件中的模块源 - 这是可能的,但显然你不能 link 多个测试文件在一起,你需要 运行 它们分开,因为它们为被测模块中的所有符号定义了相同的符号。让测试 "modules" 以与其他用户相同的方式使用被测模块(
\#include
并调用 public 接口)。在这种情况下,您的测试文件与其他任何模块一样都是模块,应该 link 与被测模块的单个实例一起编辑。使用
cgreen-runner
。它加载共享库并发现库中的所有测试,从而减轻您记住将每个新测试用例添加到套件的负担。
如果您正在对现有的、不可测试的代码进行改造测试,或者确实需要测试内部结构,则仅使用#1 ,比如 static
函数。
#2 非常标准,可能是您应该做的。在这种情况下,从您的测试文件中删除任何 #include "some_global_module.c"
,就像您在 test1.c
中一样。您的 Makefile
应该类似于:
all: all_tests
all_tests: all_tests.o some_global_module.o \
test1.o some_global_module_under_test1.o \
test2.o some_global_module_under_test2.o
所以 test1.c
和 test2.c
看起来像你指出的那样,以及上面的 Makefile 内容,我不明白为什么你应该在 link 时得到 "multiple definition"。
#3 是我的最爱。 Link 将所有内容放入共享对象库(Linux 上的 .so
)和 运行 cgreen-runner
上。您的 Makefile
应该类似于:
all: all_tests.so
cgreen-runner ./$^
all_tests.so: some_global_module.o \
test1.o some_global_module_under_test1.o \
test2.o some_global_module_under_test2.o
$(LINK) -shared -o $@ $^
注意:如果您的 some_global_module_under_test1
依赖于许多其他模块,您要么也需要 link 它们,要么模拟它们。