2017-10-17 94 views
2

我喜欢用我的C++单元测试使用catch。 我的目标是比较std::arraystd::vector。我创造了这个失败的例子。CATCH单元测试C++比较std :: arrays

#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

REQUIRE(方向== false_direction) 带扩展: {?} == {?}

如何显示实际值和预期值?我喜欢在std::arraystd::vector的违反REQUIRE条件中具有相同的显示。

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

回答

1

我跟踪这个问题上下抓头内的toString方法。它缺少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()); 
} 
1

我没有检查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); 
} 
+0

这肯定会起作用,但会降低测试代码的可读性。 – schorsch312

+0

@ schorsch312,改进后的解决方案更加清洁,可重复使用且不会影响测试输出信息 –

1

从根本上说,这是一个类型是如何字符串化的问题,并始终存在的documentation

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

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

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

  3. 使用“{?}”。

直到最近,CATCH提供了一种用于std::vector专业化开箱,但不能用于std::array,因为std::array是的C++ 11部分,并且通常较少采用。 Since version 2.1.0 Catch会检查类型是否提供类似容器的界面,具体而言,会响应begin(T)end(T)。这为许多不同类型提供了自动字符串化,包括std::vector,std::array,但也包括静态数组。