测试套件Fixture用于对对测试用例分组。一个fixture中的所有测试用例共享了相同的脚手架,包含共同使用的前置数据,辅助函数定义等等。映射到模板元编程,fixture应该是一个可以定义类型,定义元函数的独立作用域。
首先想到也用类定义来实现fixture,这样内部的testcase就相当于fixture类的内嵌类。那么我们定义可以实现fixture的辅助宏如下:
#define FIXTURE(name) class tlp_fixture_##name
这样我们就可以如下定义Fixture了:
FIXTURE(TestIntTypeAlgo)
{
using num1 = __int(10);
using num2 = __int(2);
TEST("operator add on int type")
{
ASSERT_EQ(__add(num1, num2), __int(12));
};
TEST("operator sub on int type")
{
ASSERT_EQ(__sub(num1, num2), __int(8));
};
};
这样看起来似乎一切OK了,而且我们用了class关键字,这样fixture类内部定义的所有东西默认都是private的,外部不可见。
遗憾的是,上述方案有个致命问题。因为标准规定类的内部不能定义模板的特化,也就是说上述fixture的实现导致fixture内部无法定义需要模式匹配的元函数。
于是我们退而求其次,用namespace来做fixture的实现:
// "tlp/test/details/Fixture.h"
#define FIXTURE(name) namespace tlp_fixture_##name
实际TLP中FIXTURE
宏的实现还包含测试套件注册的代码,所以比这里的示例代码要复杂一些。无论如何现在的fixture内部就可以定义各种供测试用例使用的临时元函数了。
FIXTURE(TestMetaFunctionInFixture)
{
template<typename T, typename U>
using LargerType = __if(__bool(sizeof(T) > sizeof(U)), T, U);
struct TwoBytesType { char dummy[2]; };
TEST("int should be larger than two bytes")
{
ASSERT_EQ(LargerType<int, TwoBytesType>::Result, int);
};
TEST("char should be smaller than two bytes")
{
ASSERT_EQ(LargerType<char, TwoBytesType>::Result, TwoBytesType);
};
}
网友评论