#c #unit-testing #googletest
#c #модульное тестирование #googletest
Вопрос:
У меня есть две реализации алгоритма, работающего с массивами и возвращающего одно значение, медленный и наивный, но правильный метод 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:
Вы всегда можете упаковать несколько типов параметров в кортеж. Чтобы упаковать целочисленные значения, вы можете использовать преобразователи типа в значение, подобные этому:
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);
Комментарии:
1. Обратите внимание, что в C 11
element
isstd::tuple_element
иElementType
typedef выглядят такtypedef typename std::tuple_element<0, T>::type ElementType
.