Boost logo

Boost :

Subject: [boost] test: Initializiation of data test cases
From: Florian Lindner (mailinglists_at_[hidden])
Date: 2016-11-09 03:51:20


Hello,

I would like to use data test cases. The problem that comes with that, is that I want to use objects that needs the
application to be initialized before they are instantiated. Example is that an object that uses MPI needs to habe
MPI_Init called before.

This example code shows the order in which different hooks are run:

#define BOOST_TEST_DYN_LINK
// #define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
#include <boost/test/data/test_case.hpp>
#include <boost/test/data/monomorphic.hpp>
#include <mpi.h>

#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct GlobalFixture {
  GlobalFixture()
  {
 cout << "GlobalFixture" << endl;
  }
  ~GlobalFixture() { }
};

BOOST_GLOBAL_FIXTURE(GlobalFixture);

struct Test : public std::string { // derive from string to get operator<< that boost requires
  Test() { cout << "Object to test" << endl; }
};

namespace bdata = boost::unit_test::data;

template <class T>
class RuntimeDataset {
public:

  using sample = typename T::value_type;;
  enum { arity = 1 };

  T data;

  explicit RuntimeDataset(T _data) {
    cout << "Dataset constructor" << endl;
    data = _data;
  }

  bdata::size_t size() const {
    return data.size();
  }

  typename T::const_iterator begin() const {
    return data.cbegin();
  }
};

namespace boost { namespace unit_test { namespace data { namespace monomorphic {
template <class T>
struct is_dataset<RuntimeDataset<T>> : boost::mpl::true_ {};
}}}}

struct Fixture {
  Fixture() {
    cout << "Fixture" << endl;
  }
};

BOOST_AUTO_TEST_SUITE(MySuite)

BOOST_DATA_TEST_CASE_F(
  Fixture,
  test1,
  RuntimeDataset<std::vector<Test>>( { Test() } ), // This should be evaluated when the test is about to run
  input)
{
  BOOST_TEST(true);
  cout << "Data test case" << endl;
}

BOOST_AUTO_TEST_SUITE_END()

// initialization function:
bool init_unit_test()
{
  cout << "init_unit_test" << endl;
  return true;
}

// entry point:
int main(int argc, char* argv[])
{
  cout << "main" << endl;
  int retCode = boost::unit_test::unit_test_main( &init_unit_test, argc, argv );
  return retCode;
}

I've removed some code parts, but it should compile right away using

 mpic++ -std=c++11 -lboost_unit_test_framework boosttesting.cpp

Its output is

Object to test
Dataset constructor
main
init_unit_test
GlobalFixture
Running 1 test case...
Fixture
Data test case

*** No errors detected

So, before I have any chance to do my own initialization code, the Test object and the dataset is constructed.

I have posted this to the user mailing list, but still looking for a way to work around that.

Do you have any idea how I can do initialization before data is instantiated?

Thanks,
Florian


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk