Boost.Test Custom Type using decorator boost::unit_test::tol
Boost.Test Custom Type using decorator boost::unit_test::tolerance
我正在使用Boost.Test来测试数值。通常,我必须比较数学对象的值。下面是一个玩具示例,显示了我必须如何进行大量测试。
#define BOOST_TEST_MODULE VektorTest
#include <boost/test/included/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
struct Vector {
Vector(double x, double y, double z) : x(x), y(y), z(z) {}
double x;
double y;
double z;
};
BOOST_AUTO_TEST_CASE(Rotations, * boost::unit_test::tolerance(1.0e-2)) {
Vector vector1(1.5,3.,7.4);
Vector vector2(1.51, 3.01, 7.41);
// The following can get really annoying and is error prone.
BOOST_TEST(vector1.x==vector2.x);
BOOST_TEST(vector1.y==vector2.y);
BOOST_TEST(vector1.z==vector2.z);
// This should be the expected usage, but only if the tolerance is considered.
// BOOST_TEST(vector1==vector2); // Will not compile!
}
我可以教 Boost.Test 识别考虑boost::unit_test::tolerance
装饰器的自定义类型吗?
仅仅对Vector
对象的内容x,y,z
进行一对一的比较将不是可行的解决方案。
#define BOOST_TEST_MODULE 维克托测试 #include #include
结构向量 { Vector
(double x, double y, double z) : x(x), y(y), z(z) {}double x;
double y;
double z;
};
编辑
在我更仔细地研究了Boost.Test的文档之后,我发现了有趣的函数per_element()
,它允许比较序列中包含的值。这个函数已经是一个很大的好处,因为它考虑了tolerance
装饰器,如下所述。std::vector<T>
满足序列接口,可以很好地在此框架内使用。
Boost.Test文档说,序列应该实现size()
和begin()
函数,以及字段const_iterator
和value_type
。至于我,这不是一个可行的解决方案,因为我无法更改数学类的界面。更重要的是,我无法扩展下面的玩具示例来满足此接口。
#define BOOST_TEST_MODULE VektorTest
#include <boost/test/included/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
struct Vector {
Vector(double x, double y, double z) : x(x), y(y), z(z) {}
double x;
double y;
double z;
};
BOOST_AUTO_TEST_CASE(VectorTest, * boost::unit_test::tolerance(1.0e-4)) {
{
std::vector<double> vector1;
vector1.push_back(1.5);
vector1.push_back(3.);
vector1.push_back(7.4);
std::vector<double> vector2;
vector2.push_back(1.51);
vector2.push_back(3.01);
vector2.push_back(7.41);
BOOST_TEST(vector1==vector2, boost::test_tools::per_element());
}
{
Vector vector1(1.5,3.,7.4);
Vector vector2(1.51, 3.01, 7.41);
//BOOST_TEST(vector1==vector2, boost::test_tools::per_element()); // Will not compile!!!
}
}
我不确定是否完全理解您的问题,但也许BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE
(见此处)是您问题的答案。
编辑:善良而复杂的方式
如果您想将Vektor
视为应执行基于公差的比较的类型,则可以在文档中查看此处
您需要的是:
- 使您的类与基于公差的比较兼容(需要
EqualityComparable
,LessThanComparable
)。所有比较(见这里和那里)操作都涉及要计算的两个值之间的差异,因此您需要您的类来实现LessThanComparable
、否定 - 绝对值 - 以及从单个值构造 - 原点所需的。boost.operators
在这里可能会有很大帮助。 - 通知 boost.test 您的类与基于公差的操作兼容,方法是声明您的类的专用
tolerance_based
在您的情况下,要实现的容差区域位于特定位置周围的 3D 立方体内。给定公差 \epsilon,
- 落在这个立方体内的向量是"足够接近"的 wrt。
- 落在立方体之外的向量被认为是"足够远的"
所有这些操作都由close_at_tolerance执行。
由于要执行每个轴的公差,因此可以实现
-
operator-
为每轴差分 -
operator-
(一元否定)作为每个轴的否定 -
operator<
作为每个轴的比较 -
operator/
作为每个轴的划分
等。 operator<
和operator-
(一元)用于计算绝对值。
但是,这不会像std::max
那样按预期工作,std::min
也应该实施(请参阅此处)。在您的情况下,他们应提供每个轴的max
和min
。现在
- 最简单的方法是实现您的
close_at_tolerance
专业化(见这里)。 - 或实现
std::min
和std::max
并专门化boost::math::fpc::fpc_detail::fpt_abs
(私有 API)来计算绝对值。
归根结底,这只是一个比较公差、差异和绝对值计算的问题。
如果你采取
|v1 - v2| = (|a1-a2|, |b1-b2|, |c1-c2|)
|v1 - v2|/|v1| = (|a1-a2|/|a1|, |b1-b2|/|b1|, |c1-c2|/|c1|) // same for v2
max(|v1 - v2|/|v1|, |v1 - v2|/|v2|) = (max(|a1-a2|/|a1|, |a1-a2|/|a2|),
max(|b1-b2|/|b1|, |b1-b2|/|b2|),
... )
执行测试所需的是:
|v1 - v2|/|v1| < eps. && |v1 - v2|/|v2| < eps.
=> max(|v1 - v2|/|v1|, |v1 - v2|/|v2|) < eps.
=> max(|v1 - v2|/|v1|, |v1 - v2|/|v2|) < vektor(eps., eps., eps.)
=> max(|a1-a2|/|a1|, |a1-a2|/|a2|) < eps.
&& max(|b1-b2|/|b1|, |b1-b2|/|b2|) < eps. ...
并且它与每个轴的最大值、除法和比较保持一致。
- 如何使用 Google Test 向测试添加元数据 / 如何将数据从 Google Test 发送到 TestEven
- Boost.TEST with CLion: "Test framework quit unexpectedly"
- Google Test for OpenCv c++
- 使用 Google Test 对自定义断言函数进行单元测试
- 柯南,CMake.test()生成XML报告
- 如何在 google test in windows 中管理断言
- google test PrintTo for std::set<std::string>
- 我正在尝试学习如何在 c++ 中传递指针,但出现错误:没有用于调用"test"的匹配函数。我做错了什么?
- Xcode Test Navigator 如何在纯C++项目中显示 Google 测试
- 如何期望通过使用Google Test(Mock)以特定频率调用函数
- 无法将 Google Test NuGet 包添加到 Visual Studio Linux C++ 项目中
- 错误:无效使用非静态成员函数"int test::hotplug_callback(libusb_contex
- 为什么会给出"multiple test case"错误?
- 使用 C++ Boost.Test 组织单元测试?
- Caffe在net_.reset上打印整个protext文件(new Net<float>(model_file,TEST))
- Google Test:错误 LNK2019:使用 Visual Studio 2017 与 CMake 进行未解析的外
- C ++ Google test (gtest):如何创建自定义断言和期望?
- 无效使用非静态成员函数 int test::funcAB(int, int)
- Boost.Test - 如何在交叉点上检查两个向量
- 如何使用模板化函数作为Boost::Unit-test的自定义谓词