【发布时间】:2014-11-28 22:18:17
【问题描述】:
我正在尝试在 Boost 单元测试框架中设置依赖项。 我发现this thread tbat 有一个如何使用 test_unit::depends_on() 方法的示例。到目前为止一切顺利,我可以围绕它写一些魔术来平滑它。 但是,UTF 在执行期间不尊重测试依赖项。
场景:一个 BOOST_AUTO_TEST_CASE A 在另一个 (B) 之前声明,而 A 依赖于 () B 预期(期望)结果:框架检测到依赖关系并首先运行 B,如果 B 成功则运行 A。 实际结果:A 被跳过,因为尚未运行的 B 已经“失败”(即没有/错误的结果)。
现在,我的想法是对测试用例/套件进行拓扑排序,然后按排序顺序运行它们。 为此,我创建了一个 test_tree_visitor 来遍历套件并确定 m_members test_suite 成员的顺序。
但是,m_members 是受保护的,不能通过方法访问。 由于我无法更改标头(会使升级到新版本更加困难,等等),并且 BOOST_* 宏将类“硬编码”为 test_suite,我正在考虑以下黑客:
class member_accessible_test_suite : public test_suite
{
public:
const std::vector<test_unit_id> *get_members() const { return &m_members; }
};
class dependency_order_visitor : public test_tree_visitor
{
public:
virtual void visit( test_case const& tu)
{}
virtual bool test_suite_start( test_suite const& tu)
{
const member_accessible_test_suite *psuite(reinterpret_cast<const member_accessible_test_suite*>(&tu));
const std::vector<test_unit_id> *pmembers(psuite->get_members());
/* do something with pmembers */
return true;
}
virtual void test_suite_finish( test_suite const& tu)
{}
};
在 Coliru 上查看 watered down version
现在回答我的问题:
boost 库通常设计良好 - 我是否因为对单元测试设计的误解而需要此功能而犯了根本性错误?
由于 member_accessible_test_suite 没有数据并且只添加功能,reinterpret_cast() 是安全的还是进入 UB 领域的快车道? 无论哪种方式,我都担心在生产中使用这种可怕的 hack。
有没有更好的方法,如果有,什么时候会变成 XY 问题?
【问题讨论】:
-
我对这个 boost 库没什么好说的,但是演员阵容还可以。参见例如Type aliasing section at cppreference:
the resulting pointer or reference may be accessed if ... T2 is the (possibly cv-qualified) dynamic type of the object ...。你可以直接投给参考 -reinterpret_cast<const member_accessible_test_suite&>(tu) -
感谢您的链接。我认为“T2 是对象动态类型的(可能是 cv 限定的)基类”将适用,因为指针实际上是 test_suite,而不是 member_accessible_test_suite。我只是想从标准专家那里知道是否允许编译器做一些尴尬的事情,例如重新对齐或将隐藏/内部数据成员与派生类一起存储。
-
你所描述的似乎是一个错误的级别(
boost.test正在做拓扑排序和一切)。你能把代码贴出来吗?我相信这可以很容易地解决,而不是实施已经存在的东西。
标签: c++ unit-testing dependencies reinterpret-cast boost-test