Unittest++:测试多个可能值

发布于 2024-08-19 06:59:24 字数 1208 浏览 8 评论 0原文

我目前正在用 C++ 实现一个简单的光线追踪器。我有一个名为 OrthonormalBasis 的类,它从一个或两个指定向量生成三个正交单位向量,例如:

void
OrthonormalBasis::init_from_u ( const Vector& u )
{
    Vector n(1,0,0);
    Vector m(0,1,0);
    u_ = unify(u);
    v_ = cross(u_,n);
    if ( v_.length() < ONB_EPSILON )
        v_ = cross(u_,m);
    w_ = cross(u_,v_);
}

我正在使用 Unittest++ 框架测试我的所有方法。问题是,有效的正交基有不止一种可能的解决方案。例如这个测试:

TEST ( orthonormalbasis__should_init_from_u )
{
    Vector u(1,0,0);
    OrthonormalBasis onb;

    onb.init_from_u(u);

    CHECK_EQUAL( Vector( 1, 0, 0 ), onb.u() );
    CHECK_EQUAL( Vector( 0, 0, 1 ), onb.v() );
    CHECK_EQUAL( Vector( 0, 1, 0 ), onb.w() );
}

有时会成功,有时会失败,因为向量 v 和 w 也可能有负 1,但仍然表示有效的正交基。有没有办法指定多个期望值?或者你知道另一种方法吗?

重要的是,我将实际值和预期值打印到标准输出,以便调试方法,因此此解决方案无法完成工作:

TEST ( orthonormalbasis__should_init_from_u )
{
    Vector u(1,0,0);
    OrthonormalBasis onb;

    onb.init_from_u(u);

    CHECK_EQUAL( Vector( 1, 0, 0 ), onb.u() );
    CHECK(
        Vector( 0, 0, 1 ) == onb.v() ||
        Vector( 0, 0,-1 ) == onb.v() );
    CHECK(
        Vector( 0, 1, 0 ) == onb.w() ||
        Vector( 0,-1, 0 ) == onb.w() );
}

i am currently implementing a simple ray tracer in c++. I have a class named OrthonormalBasis, which generates three orthogonal unit vectors from one or two specified vectors, for example:

void
OrthonormalBasis::init_from_u ( const Vector& u )
{
    Vector n(1,0,0);
    Vector m(0,1,0);
    u_ = unify(u);
    v_ = cross(u_,n);
    if ( v_.length() < ONB_EPSILON )
        v_ = cross(u_,m);
    w_ = cross(u_,v_);
}

I am testing all my methods with the Unittest++ framework. The Problem is, that there is more than one possible solution for a valid orthonormal basis. For example this test:

TEST ( orthonormalbasis__should_init_from_u )
{
    Vector u(1,0,0);
    OrthonormalBasis onb;

    onb.init_from_u(u);

    CHECK_EQUAL( Vector( 1, 0, 0 ), onb.u() );
    CHECK_EQUAL( Vector( 0, 0, 1 ), onb.v() );
    CHECK_EQUAL( Vector( 0, 1, 0 ), onb.w() );
}

sometimes it succeeds, sometimes it fails, because the vectors v and w could also have a negative 1, and still represent a valid orthonormal basis. Is there a way to specify multiple expected values? Or do you know another way to do that?

It is important, that i get the actual and expected values printed to the stdout, in order to debug the methods so this solution won't do the job:

TEST ( orthonormalbasis__should_init_from_u )
{
    Vector u(1,0,0);
    OrthonormalBasis onb;

    onb.init_from_u(u);

    CHECK_EQUAL( Vector( 1, 0, 0 ), onb.u() );
    CHECK(
        Vector( 0, 0, 1 ) == onb.v() ||
        Vector( 0, 0,-1 ) == onb.v() );
    CHECK(
        Vector( 0, 1, 0 ) == onb.w() ||
        Vector( 0,-1, 0 ) == onb.w() );
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

画骨成沙 2024-08-26 06:59:24

当然,如果您要测试的只是您的基础是否正交,那么这就是您需要测试的?

// check orthogonality

CHECK_EQUAL( 0, dot(onb.u(), onb.v));
CHECK_EQUAL( 0, dot(onb.u(), onb.w));
CHECK_EQUAL( 0, dot(onb.v(), onb.w));

// check normality

CHECK_EQUAL( 1, dot(onb.u(), onb.u));
CHECK_EQUAL( 1, dot(onb.v(), onb.v));
CHECK_EQUAL( 1, dot(onb.w(), onb.w));

Surely if all you are testing is whether your basis is orthonormal, then that's what you need to test?

// check orthogonality

CHECK_EQUAL( 0, dot(onb.u(), onb.v));
CHECK_EQUAL( 0, dot(onb.u(), onb.w));
CHECK_EQUAL( 0, dot(onb.v(), onb.w));

// check normality

CHECK_EQUAL( 1, dot(onb.u(), onb.u));
CHECK_EQUAL( 1, dot(onb.v(), onb.v));
CHECK_EQUAL( 1, dot(onb.w(), onb.w));
风铃鹿 2024-08-26 06:59:24

一种可能性是创建您自己的 CHECK_MULTI 函数:

void CHECK_MULTI(TYPE actual, vector<TYPE> expected, const char* message)
{
  for (element in expected) {
    if (element == actual) {
      // there's a test here so the test count is correct
      CHECK(actual, element);
      return;   
    }
  }
  CHECK(actual, expected);
}

One possibility is to create your own CHECK_MULTI function:

void CHECK_MULTI(TYPE actual, vector<TYPE> expected, const char* message)
{
  for (element in expected) {
    if (element == actual) {
      // there's a test here so the test count is correct
      CHECK(actual, element);
      return;   
    }
  }
  CHECK(actual, expected);
}
美人如玉 2024-08-26 06:59:24

我会使用一个实用函数或类,这样你就可以做这样的事情:

CHECK_EQUAL(VectorList(0,0,1)(0,0,-1), onb.v());

鉴于,平等的解释有点奇怪,但它应该打印你想要看到的所有值,而不需要引入自定义宏。
如果您担心在这种情况下的EQUAL,那么像CHECK_CONTAINS() 这样的自定义宏应该不会太难实现。

VectorList 将被构造为临时对象,并使用 operator() 将值插入到包含的 Vector 列表中,类似于 Boost.Assign

基本做法:

class VectorList {
    std::vector<Vector> data_;
public:
    VectorList(double a, double b, double c) {
        data_.push_back(Vector(a,b,c));
    }
    VectorList& operator()(double a, double b, double c) {
        data_.push_back(Vector(a,b,c));
        return *this;
    }
    bool operator==(const Vector& rhs) const {
        return std::find(data_.begin(), data_.end(), rhs) != data_.end();
    }
};

I'd use a utility function or class so you can do something like this:

CHECK_EQUAL(VectorList(0,0,1)(0,0,-1), onb.v());

Given, that interpretation of equality is somewhat weird, but it should print you all values you want to see without the need to introduce a custom macro.
If you are worried about EQUAL in that context, a custom macro like CHECK_CONTAINS() shouldn't be too hard to do.

VectorList would be constructed as a temporary and operator() be used to insert values into the contained list of Vectors, similar to Boost.Assign.

Basic approach:

class VectorList {
    std::vector<Vector> data_;
public:
    VectorList(double a, double b, double c) {
        data_.push_back(Vector(a,b,c));
    }
    VectorList& operator()(double a, double b, double c) {
        data_.push_back(Vector(a,b,c));
        return *this;
    }
    bool operator==(const Vector& rhs) const {
        return std::find(data_.begin(), data_.end(), rhs) != data_.end();
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文