leveldb分析——单元测试工具
leveldb中自己实现了一个简单的单元测试工具,下面是一个对CRC类测试的一个例子
class CRC { };
TEST(CRC, Extend) {
ASSERT_EQ(Value("hello world", 11),
Extend(Value("hello ", 6), "world", 5));
}
int main(int argc, char** argv) {
return leveldb::test::RunAllTests();
}
TEST() 和RunAllTests()空间是怎么实现的呢?我们来看看源码:
#define TEST(base,name) \
class TCONCAT(_Test_,name) : public base { \
public: \
void _Run(); \
static void _RunIt() { \
TCONCAT(_Test_,name) t; \
t._Run(); \
} \
}; \
bool TCONCAT(_Test_ignored_,name) = \
::leveldb::test::RegisterTest(#base, #name, &TCONCAT(_Test_,name)::_RunIt); \
void TCONCAT(_Test_,name)::_Run()
对上面的测试程序实际展开后如下:
class _Test_Extend : public CRC {
public:
void _Run();
static void _RunIt(){
_Test_Extend t;
t._Run();
}
};
bool _Test_ignored_Extend = ::leveldb::test::Register("CRC","Extend",&_Test_Extend::_RunIt());
void _Test_Extend::Run(){
ASSERT_EQ(Value("hello world", 11),
Extend(Value("hello ", 6), "world", 5));
}
注册过程:
struct Test {
const char* base;
const char* name;
void (*func)();
};
std::vector<Test>* tests;
}
bool RegisterTest(const char* base, const char* name, void (*func)()) {
if (tests == NULL) {
tests = new std::vector<Test>;
}
Test t;
t.base = base;
t.name = name;
t.func = func;
tests->push_back(t);
return true;
}
运行过程:
int RunAllTests() {
int num = 0;
if (tests != NULL) {
for (int i = 0; i < tests->size(); i++) {
const Test& t = (*tests)[i];
}
fprintf(stderr, "==== Test %s.%s\n", t.base, t.name);
(*t.func)();
++num;
}
}
fprintf(stderr, "==== PASSED %d tests\n", num);
return 0;
}