Когда набор данных (и образцы) уничтожается в boost::test?

Я пытаюсь научиться использовать функции тестирования на основе данных boost::test. Как бы то ни было, я столкнулся с проблемой, которая, как мне кажется, связана с уничтожением набора данных (и образцов). В качестве примера возьмем следующий фрагмент кода:

#define BOOST_TEST_MODULE dataset_example68
#include <boost/test/included/unit_test.hpp>
#include <boost/test/data/test_case.hpp>
#include <boost/test/data/monomorphic.hpp>
#include <sstream>
#include <cstdio>

namespace bdata = boost::unit_test::data;

// Dataset generating a Fibonacci sequence
class fibonacci_dataset {
public:
    // Samples type is int
    using sample=int;
    enum { arity = 1 };

    struct iterator {

        iterator() : a(1), b(1) {}

        int operator*() const   { return b; }
        void operator++()
        {
            a = a + b;
            std::swap(a, b);
        }
    private:
        int a;
        int b; // b is the output
    };

    fibonacci_dataset() {fprintf(stderr, "constructed %p\n", (void*)this);}
    ~fibonacci_dataset() {fprintf(stderr, "destructed %p\n", (void*)this);}
    // size is infinite
    bdata::size_t   size() const    { return bdata::BOOST_TEST_DS_INFINITE_SIZE; }

    // iterator
    iterator        begin() const   { return iterator(); }
};

namespace boost { namespace unit_test { namespace data { namespace monomorphic {
  // registering fibonacci_dataset as a proper dataset
  template <>
  struct is_dataset<fibonacci_dataset> : boost::mpl::true_ {};
}}}}

// Creating a test-driven dataset 
BOOST_DATA_TEST_CASE(
    test1,
    fibonacci_dataset() ^ bdata::make( { 1, 2, 3, 5, 8, 13, 21, 35, 56 } ),
    fib_sample, exp)
{
      BOOST_TEST(fib_sample == exp);
}

Этот фрагмент кода взят из документа boost::test, и я добавил только fprintf(stderr,''') в конструктор/деструктор. Я скомпилировал и запустил его на своем Arch Linux (boost 1.63.0, gcc 6.3.1, опция компилятора -std=c++14), вывод выглядит следующим образом:

constructed 0x7ffd69e66e3e
destructed 0x7ffd69e66de0
destructed 0x7ffd69e66e3d
destructed 0x7ffd69e66e3e
Running 9 test cases...
4.cpp(53): error: in "test1/_7": check fib_sample == exp has failed [34 != 35]
Failure occurred in a following context:
    fib_sample = 34; exp = 35; 
4.cpp(53): error: in "test1/_8": check fib_sample == exp has failed [55 != 56]
Failure occurred in a following context:
    fib_sample = 55; exp = 56; 

*** 2 failures are detected in the test module "dataset_example68"

Мой вопрос:

  1. Кажется, что набор данных уничтожается до начала выполнения тестового примера, имеет ли это смысл? (Хотя это и не показано в этом фрагменте, кажется, что образцы данных также уничтожаются до начала выполнения тестового примера, имеет ли это смысл?)
  2. Я думаю, что если вы объявите конструктор, компилятор не будет неявно генерировать для вас конструктор по умолчанию. И если вы объявите деструктор, компилятор не будет неявно генерировать для вас оператор/конструктор копирования/перемещения, так как же создается «другой» набор данных (из вывода удалено более одного набора данных)?

Большое спасибо за Вашу помощь.


person Jinpei Li    schedule 24.05.2017    source источник


Ответы (1)


Первый набор данных по адресу 0x7ffd69e66e3e создается из-за вызова его конструктора в

fibonacci_dataset() ^ bdata::make( { 1, 2, 3, 5, 8, 13, 21, 35, 56 } )

и это единственный, который вы видите с вашим конструктором по умолчанию. Все остальные наборы данных фактически перемещаются. Есть такой ход например в operator^ подразумевающий построение класса boost::unit_test::data::monomorphic::zip.

При инициализации (перед вводом main) UTF объявляет BOOST_DATA_TEST_CASE, который вызывает make_test_case_gen. Это регистрирует модульный тест для каждой выборки набора данных. Модульный тест содержит образец напрямую.

После регистрации всех модульных тестов больше нет необходимости хранить набор данных. Поэтому имеет смысл удалить набор данных до начала тестов.

person Raffi    schedule 28.06.2017