googletest: построить приборы с параметрами? - PullRequest
4 голосов
/ 02 октября 2011

У меня есть две реализации алгоритма, работающего с массивами и возвращающего одно значение, медленный и наивный, но правильный метод A и оптимизированный метод B, который может содержать ошибки в углах пространства входных параметров. Метод B имеет ветви в зависимости от размера входного массива, и я хотел бы проверить B против A для разных размеров входного массива. Оба метода настроены на работу с разными типами.

Я только начинаю использовать googletest в первый раз, но на самом деле я не вижу четкого способа сделать это с помощью прибора (следующее упрощено, есть еще что настроить, чтобы получить тесты собирается, и я также хотел бы запустить другие тесты на данных):

template<typename T, unsigned int length>  // type to test on, test array size
class BTest : public ::testing:Test {
    public:
        T* data; // test data
    public:
        BTest(); // allocate data, populate data with random elements
        ~BTest();
        T run_method_a_on_data(); // reference: method A implementation
};
// ...
TYPED_TEST_CASE(...) // set up types, see text below

TYPED_TEST(...) {
    // test that runs method B on data and compares to run_method_a_on_data()
}

В документации googletest шаг для запуска реальных тестов после определения прибора - это определить типы

typedef ::testing::Types<char, int, unsigned int> MyTypes;
TYPED_TEST_CASE(BTest, MyTypes);

но это показывает ограничение, что для классов, производных от ::testing::Test, разрешен только один параметр шаблона. Я читаю это правильно? Как можно поступить об этом?

1 Ответ

6 голосов
/ 03 октября 2011

Вы всегда можете упаковать несколько типов параметров в кортеж.Чтобы упаковать целочисленные значения, вы можете использовать конвертеры типа-значения следующим образом:

template <size_t N> class TypeValue {
 public:
  static const size_t value = N;
};
template <size_t N> const size_t TypeValue<N>::value;

#include <tuple>  /// Or <tr1/tuple>
using testing::Test;
using testing::Types;
using std::tuple;  // Or std::tr1::tuple
using std::element;

template<typename T>  // tuple<type to test on, test array size>
class BTest : public Test {
 public:
  typedef element<0, T>::type ElementType;
  static const size_t kElementCount = element<1, T>::type::value;
  ElementType* data; // test data

 public:
  BTest() {
    // allocate data, populate data with random elements
  }
  ~BTest();
  ElementType run_method_a_on_data(); // reference: method A implementation
};
template <typename T> const size_t BTest<T>::kElementCount;

....

typedef Types<tuple<char, TypeValue<10> >, tuple<int, TypeValue<199> > MyTypes;
TYPED_TEST_CASE(BTest, MyTypes);
...