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 的方式。有几个选项:

  1. #include 测试文件中的模块源 - 这是可能的,但显然你不能 link 多个测试文件在一起,你需要 运行 它们分开,因为它们为被测模块中的所有符号定义了相同的符号。

  2. 让测试 "modules" 以与其他用户相同的方式使用被测模块(\#include 并调用 public 接口)。在这种情况下,您的测试文件与其他任何模块一样都是模块,应该 link 与被测模块的单个实例一起编辑。

  3. 使用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.ctest2.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 它们,要么模拟它们。