Unittest ++: prueba para varios valores posibles
-
22-09-2019 - |
Pregunta
Actualmente estoy poniendo en práctica un simple trazador de rayos en C ++. Tengo una clase denominada base ortonormal, que genera tres vectores unitarios ortogonales a partir de uno o dos vectores especificados, por ejemplo:
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_);
}
Estoy probando todos mis métodos con el marco unittest ++. El problema es que hay más de una solución posible para una base ortonormal válida. Por ejemplo esta prueba:
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() );
}
A veces tiene éxito, a veces falla, porque los vectores V y W también podría tener un efecto negativo 1, y todavía representan una base ortonormal válida. ¿Hay una manera de especificar varios valores esperados? ¿O usted sabe otra manera de hacer eso?
Es importante, que me sale de los valores reales y esperados impresos a la salida estándar, con el fin de depurar los métodos por lo que esta solución no hará el trabajo:
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() );
}
Solución
Sin duda, si todo lo que se está probando es si su base es ortonormal, entonces eso es lo que necesita para la prueba?
// 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));
Otros consejos
Una posibilidad es crear su propia función 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);
}
Me haría uso de una función de utilidad o una clase de lo que puede hacer algo como esto:
CHECK_EQUAL(VectorList(0,0,1)(0,0,-1), onb.v());
Teniendo en cuenta, que la interpretación de la igualdad es algo raro, pero se debe imprimir todos los valores que desea ver sin la necesidad de introducir una macro personalizada.
Si usted está preocupado por EQUAL
en ese contexto, una macro personalizada como CHECK_CONTAINS()
no debería ser demasiado difícil de hacer.
VectorList
sería construido como un temporal y operator()
usarse para insertar valores en la lista contenida de Vector
s, similar a Boost.Assign .
Enfoque básico:
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();
}
};