我正在使用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;
}
有什么想法吗?也许我可以使用一些编译技巧或更简单的方法来管理整个事情?
答案 0 :(得分:1)
无法在同一测试文件中包含多个Describe()
。它不应该是必要的。
您无法准确解释如何组装测试/模块。有几种选择:
#include
您的模块源代码在测试文件中 - 这是可能的,但是您显然无法将多个测试文件链接在一起,您需要单独运行它们,因为它们定义相同的所有被测模块中的符号。
让测试&#34;模块&#34;以与其他用户相同的方式使用您的测试模块(\#include
并调用公共接口)。在这种情况下,您的测试文件与其他模块一样,应该与被测模块的单个实例链接在一起。
使用cgreen-runner
。它加载共享库并发现库中的所有测试,使您免于记住将每个新测试用例添加到套件中的负担。
如果要将测试改装为现有的,不可测试的代码,或者 需要测试内部,例如static
函数,请仅使用#1 。
#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内容,我就不明白为什么您应该得到&#34;多重定义&#34;在链接时。
#3是我最喜欢的。将所有内容链接到共享对象库(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
依赖于许多其他模块,您也需要链接它们,或者模仿它们。