Модульное тестирование CATCH для C++ сравнивает std::array
Мне нравится использовать catch для моих модульных тестов C++. Моя цель - сравнить std::array
а также std::vector
, Я создал этот неудачный пример.
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
TEST_CASE("Vector") {
std::vector<double> direction = {0.1, 0.3, 0.4};
std::vector<double> false_direction = {0.1, 0.0, 0.4};
REQUIRE(direction == false_direction);
}
TEST_CASE("Array") {
std::array<double, 3> direction = {0.1, 0.3, 0.4};
std::array<double, 3> false_direction = {0.1, 0.0, 0.4};
REQUIRE(direction == false_direction);
}
Результат этого теста предназначен для проверки std::vector
REQUIRE( direction == false_direction) с расширением: {0,1, 0,3, 0,4 } == { 0,1, 0,0, 0,4}
и для std::array
REQUIRE( direction == false_direction) с расширением: {?} == {?}
Что я могу сделать, чтобы отобразить фактическое и ожидаемое значение? Мне нравится иметь такой же дисплей в нарушенном REQUIRE
условие для std::array
что касается std::vector
,
Я использую последнюю версию catch (v1.10.0).
3 ответа
Я проследил проблему вниз по toString
метод в заголовке catch. Отсутствует перегрузка для std::array
, std::vector
уже был создан. Я передам это изменение проекту улова.
// already exists in the catch header
template<typename T, typename Allocator>
std::string toString( std::vector<T,Allocator> const& v ) {
return Detail::rangeToString( v.begin(), v.end() );
}
// my modification in the catch header
template<typename T, std::size_t _Nm>
std::string toString( std::array<T, _Nm> const& v ) {
return Detail::rangeToString( v.begin(), v.end() );
}
По сути, это вопрос о том, как тип является строковым, и для этого всегда есть документация.
Сокращенная версия заключается в том, что существует простой алгоритм
Проверка на специализацию
Catch::StringMaker
для данного типа. Если существует, используйте его.Проверить
operator<<
перегрузка для данного типа. Если существует, используйте его.Используйте "{?}".
До недавнего времени Catch предоставляла специализацию для std::vector
из коробки, но не для std::array
, так как std::array
был частью C++11 и вообще менее использовался. Начиная с версии 2.1.0, Catch вместо этого проверяет, предоставляет ли тип контейнероподобный интерфейс, в частности, отвечает begin(T)
а также end(T)
, Это обеспечивает автоматическую строку для многих различных типов, включая std::vector
, std::array
, но также статические массивы.
Я не проверял исходный код Catch, чтобы увидеть, как именно они реализуют REQUIRE
пункт, и почему это не сработает, но vector
делает. Но вот обходной путь:
#define COMPARE_ARRAYS(lhs, rhs) compareArrays(Catch::getResultCapture().getCurrentTestName(), __LINE__, lhs, rhs)
template < typename T, size_t N >
void compareArrays(const std::string & test, unsigned line, std::array<T, N> lhs, std::array<T, N> rhs) {
std::vector<T> lv(lhs.begin(), lhs.end());
std::vector<T> rv(rhs.begin(), rhs.end());
INFO("Test case [" << test << "] failed at line " << line); // Reported only if REQUIRE fails
REQUIRE(lv == rv);
}
TEST_CASE("Array") {
std::array<double, 3> direction = {0.1, 0.3, 0.4};
std::array<double, 3> true_direction = {0.1, 0.3, 0.4};
COMPARE_ARRAYS(direction, true_direction);
std::array<double, 3> false_direction = {0.1, 0.0, 0.4};
COMPARE_ARRAYS(direction, false_direction);
}