I am trying to set dependencies in the Boost Unit Testing Framework. I have found this thread tbat has an example of how to use the test_unit::depends_on() method. So far so good, I can write some magickery around that to smooth it out. However, the UTF doesn't honor test dependencies during execution.
Scenario: A BOOST_AUTO_TEST_CASE A is declared before another (B), and A depends_on() B Excpected (desired) outcome: The framework detects the dependency and runs B first, and then A if B succeeded. Actual Outcome: A is skipped because B, which has not run yet, has "failed" (i.e. no/false result yet).
Now, my idea was to do a topological sort on the test cases / suites and then run them in the sorted order. For that, I created a test_tree_visitor to walk the suites and determine the order of the m_members test_suite member.
However, m_members is protected and not accessible via methods. Since I can't change the headers, (would make upgrading to a newer version more difficult, etc, etc), and the BOOST_* macros "hardcode" the class as test_suite, I was thinking about the following hackery:
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)
{}
};
See a watered down version on Coliru
So now to my questions:
The boost libraries are generally well designed - am I making a fundamental mistake due to a misunderstanding about unit testing design by requiring this feature?
Since member_accessible_test_suite has no data and adds only functions, is the reinterpret_cast() safe or the fast lane into UB land? Either way, I am worried to use such a ghastly hack in production.
Is there a better way, and if so, at which point did this turn into an XY problem?