作为一个小小的个人项目,我在C中做了一个小而简单的测试框架。
我面临的问题是,我希望能够在用户编写测试用例时自动注册测试用例(即其中包含某些类型的ASSERTS的函数),然后在我预定义的主函数中运行它们。
所以从用户方面来说,我只想做
TEST_CASE("TestName1")
{
// Testing stuff here
}
TEST_CASE("TestName2")
{
// Testing more stuff here
}
其余的应该被覆盖。
目前,定义只是
#define TEST_CASE(name) int name()
问题是,如果有可能在某种程度上记住"这些函数让我可以在main函数中调用它们。
编辑: 所以重点是用户应该包含一个" test-framework.h"它定义了一个预定义的main()函数,该函数运行用户使用TEST_CASEs指定的所有测试。这意味着它应该看起来像这样:
用户定义文件:
// File where tests are defined
#include "framework.h"
TEST_CASE("TestCase1")
{
// Test stuff
}
TEST_CASE("TestCase2")
{
// Test more stuff
}
在框架文件中:
// framework.h
#define TEST_CASE(name) int name()
int main()
{
// Here run all TEST_CASEs there is
}
那意思,我不知道我的main()中TEST_CASES的名字。
答案 0 :(得分:1)
你无法按照自己想要的方式真正做到这一点,但如果你对用户不得不做更多的工作感到满意,比如说。 :
TEST_CASE(TestName1) {
return 42;
}
TEST_CASE(TestName2) {
return 0;
}
ALL_TEST_CASES {
REGISTER_TEST_CASE(TestName1);
REGISTER_TEST_CASE(TestName2);
}
然后你的框架可能有这样的代码(使用函数指针来注册测试用例):
typedef struct TestCase {
const char* name;
int (*fptr)();
} TestCase;
TestCase testCases[10];
size_t testCnt = 0;
#define ALL_TEST_CASES void registerTestCases()
#define TEST_CASE(NAME) int NAME()
#define REGISTER_TEST_CASE(NAME) do { testCases[testCnt].name = #NAME; testCases[testCnt++].fptr = &NAME; } while (0)
和主要:
int main(void) {
registerTestCases();
size_t i;
for (i = 0; i < testCnt; ++i) {
fprintf(stdout, "Test %s : %d\n", testCases[i].name, testCases[i].fptr());
}
return 0;
}
显然,这需要更加健壮等等 - 它应该只是作为概念的证明。
答案 1 :(得分:1)
您可以根据情况重新定义TEST_CASE
宏,因此在不同情况下它会执行不同的操作。
像
这样的东西#define TEST_CASE(name) int Test##name(void)
TEST_CASE(Function1)
{
// Test Function1
}
TEST_CASE(Function2)
{
// Test Function2
}
#undef TEST_CASE
#define TEST_CASE(name) { #name, Test##name }
static const struct
{
char *name;
int (*func)(void);
} tests[] = {
TEST_CASE(Function1),
TEST_CASE(Function2),
{ NULL, NULL }
};
int DoTests(void)
{
for (int test = 0; tests[test].name != NULL; ++test)
{
printf("Running test #%d (%s)...", test + 1, tests[test].name);
fflush(stdout);
if (tests[test].func != NULL)
{
if (tests[test].func() == 0)
{
printf("Failed\n");
return 0;
}
}
printf("Ok\n");
}
return 1;
}
然后在main
函数中调用DoTests()
并调用所有测试
答案 2 :(得分:1)
C中没有人支持做我认为你想做的事情。话虽这么说,如果你想使用一些不可移植的技巧,你可以看看这个问题并回答:How can I implement a dynamic dispatch table in C