G ++ 4.8.2,gtest。
我们正在开发一个类的代码库(在内部使用),这些类派生自一个公共基类BasicGizmo
。
今天,每个派生自BasicGizmo
的类都需要一个名为enum
的{{1}}成员,该成员具有该类的预期大小。例如:
Size
在其他地方,我们使用gtest构建单元测试,以确保实际#pragma (pack 1)
class SpecialGizmo
:
BasicGizmo
{
public:
enum {Size = 4};
uint32_t mSomethingInteresting;
};
class SuperGizmo
:
BasicGizmo
{
public:
enum {Size=8};
uint64_t mKewlData;
};
这些类是我们期望它们根据sizeof
枚举:
CHECK_EQUAL(sizeof(SpecialGizmo),SpecialGizmo :: Size); CHECK_EQUAL(sizeof(SuperGizmo),SuperGizmo :: Size);
这一切都按预期工作,除了要求每个派生类都具有Size
枚举并且需要进行单元测试才能检查它,这只是通过代码审查来强制执行。在代码甚至提交之前,我宁愿让编译器发现遗漏。为此,我需要有一种方法可以自动为从Size
派生的每个类生成单元测试。
这种机制是否可行?
答案 0 :(得分:1)
最好使用static_assert:
template<typename tp_DerivedFromGizmo> struct
t_SizeEnumMemberChecker
{
// you can also check that tp_DerivedFromGizmo really derives from BasicGizmo
static const bool result = (sizeof(tp_DerivedFromGizmo) == tp_DerivedFromGizmo::Size);
};
static_assert(t_SizeEnumMemberChecker<SpecialGizmo>::result, "");
答案 1 :(得分:1)
您的方案可能会在不同平台或不同的编译器设置中中断。
如果我要做这样的事情,我会考虑为给定的平台生成测试代码。您可以将所有类名添加到文件中(在我的示例中为std::stringstream
)并生成一个测试程序,该程序根据每个类/结构的大小输出参考信息文件。 p>
我还会考虑设计一种方法,在输出参考信息文件的开头包含平台和编译器设置。
如果您对某个类进行官方更改,则需要重新生成测试程序以更新参考信息文件。
#include <string>
#include <iostream>
// These could be listed in a file
// opened with std::ifstream
std::istringstream iss
{
"ClassA\n"
"ClassB\n"
"ClassC\n"
"ClassD\n"
"ClassE\n"
};
int main()
{
// output an #include containing all the
// headers you want to test
std::cout << "#include \"all-classes.h\"" << '\n';
// needed for generated code
std::cout << "#include <iostream>\"" << '\n';
// output testing code
std::cout << "\nint main()\n{" << '\n';
std::string class_name;
while(std::getline(iss, class_name))
{
std::cout << "\tstd::cout << \"" + class_name + ": \" << sizeof(\"" + class_name + "\") << '\\n';" << '\n';
}
std::cout << "}" << '\n';
}
<强>输出:强>
#include "all-classes.h"
#include <iostream>"
int main()
{
std::cout << "ClassA: " << sizeof("ClassA") << '\n';
std::cout << "ClassB: " << sizeof("ClassB") << '\n';
std::cout << "ClassC: " << sizeof("ClassC") << '\n';
std::cout << "ClassD: " << sizeof("ClassD") << '\n';
std::cout << "ClassE: " << sizeof("ClassE") << '\n';
}
然后编译输出,你就有了测试程序。