CATCH 单元测试C++比较 std::array

CATCH unit testing for C++ compare std::array

本文关键字:array std 比较 单元测试 C++ CATCH      更新时间:2023-10-16

我喜欢在c ++单元测试中使用catch。我的目标是比较std::arraystd::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

要求( 方向 == false_direction )扩展: { 0.1, 0.3, 0.4 } == { 0.1, 0.0, 0.4 }

std::array

要求( 方向 == false_direction )扩展: {?} == {?}

如何显示实际值和预期值?我喜欢在违反REQUIRE条件下为std::arraystd::vector显示完全相同。

我使用最新版本的 catch (v1.10.0)。

从根本上说,这是一个如何字符串化类型的问题,为此总是有文档。

删节版是有一个简单的算法

  1. 检查给定类型的Catch::StringMaker的专用化。如果存在,请使用它。

  2. 检查给定类型的operator<<重载。如果存在,请使用它。

  3. 使用"{?}"。

直到最近,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);
}

我沿着 catch 标头中的 toString 方法追踪了问题。它缺少std::array的重载,std::vector已经被实例化了。 我会将此更改提交到 catch 项目。

// 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() );
}