Boost logo

Boost Users :

Subject: Re: [Boost-users] Boost test and openmpi
From: Richard (legalize+jeeves_at_[hidden])
Date: 2014-05-21 00:44:06


[Please do not mail me a copy of your followup]

boost-users_at_[hidden] spake the secret code
<llg9ls$cb2$1_at_[hidden]> thusly:

>I'll do my testing again, but this is inconsistent with what I
>observed from this example:

When I got the unexpected behavior of a test case executing before the
global fixture was initialized, that was in my work environment on a
more complicated uni testing project.

Using the simple example I created for the documentation, I am unable
to reproduce that behavior, but there is still some unexpected
behavior.

Using these two source files in an executable:
<http://user.xmission.com/~legalize/boost.test/libs/test/doc/src/examples/global_fixture.cpp>
<http://user.xmission.com/~legalize/boost.test/libs/test/doc/src/examples/another_global_fixture.cpp>

I have the following in the code:

global_fixture.cpp:
    BOOST_GLOBAL_FIXTURE(global_fixture)
    BOOST_FIXTURE_TEST_SUITE(suite, suite_fixture)
    BOOST_AUTO_TEST_CASE(one)
    BOOST_GLOBAL_FIXTURE(global_fixture2)
    BOOST_AUTO_TEST_CASE(two)
    BOOST_AUTO_TEST_SUITE_END()

another_global_fixture.cpp:
    BOOST_GLOBAL_FIXTURE(global3)
    BOOST_AUTO_TEST_CASE(three)
    BOOST_GLOBAL_FIXTURE(global4)
    BOOST_AUTO_TEST_CASE(four)

I get this output (each fixture does a printout in c'tor/d'tor):

global setup
global2 setup
global4 setup
global3 setup
Running 4 test cases...
suite setup
one
suite teardown
suite setup
two
suite teardown
three
four
global teardown
global2 teardown
global4 teardown
global3 teardown

*** No errors detected

What was unexpected was that the global fixtures didn't execute in the
order they were encountered in the translation unit(s) (notice that
global3 was in the source file before global4, but they were
initialized in the reverse order, while the fixtures in the other
source file were initialized in the order encountered) and that when
multiple global fixtures are present, they aren't torn down in the
reverse order in which they are setup, but in the same order in which
they are setup.

So we don't get symmetric setup/teardown like we do with a test case
fixture.

In other words, we don't get:

    global setup
    global2 setup
    global4 setup
    global3 setup
    ...tests
    global3 teardown
    global4 teardown
    global2 teardown
    global teardown

Since the global fixture registration is done via static initializers, the
order in which they are initialized relative to each other is undefined
across translation units. C++ makes no guarantees about the order of
static initializers between translation units.

Furthermore, the global fixture registration creates the global
fixtures as observers of the test tree with equal priority and all
observers are stored in a std::set with a comparison function that
uses the priority. However, since they all have priority zero, then
there is no specific ordering to them. This is why global4 is setup
before global3, even though global3 appears in the source file before
global4.

Add this all up and I can't really recommend global fixtures. They only
work as you might expect from using test case and test suite fixtures
when there is exactly one of them.

-- 
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
     The Computer Graphics Museum <http://computergraphicsmuseum.org>
         The Terminals Wiki <http://terminals.classiccmp.org>
  Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net