Unittest ++: banco di prova per più valori possibili
-
22-09-2019 - |
Domanda
Attualmente sto attuazione di un semplice ray tracer in C ++. Ho una classe denominata base ortonormale, che genera tre vettori unitari ortogonali da uno o due vettori specificati, ad esempio:
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_);
}
sto testando tutti i miei metodi con il quadro unittest ++. Il problema è che non v'è più di una soluzione possibile per una base ortonormale valido. Per esempio questo 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() );
}
a volte ci si riesce, a volte non riesce, perché l'vettori v e w potrebbe anche avere un effetto negativo 1, ed ancora rappresentano una base ortonormale valida. C'è un modo per specificare più valori attesi? O fai a sapere un altro modo per farlo?
E 'importante, che ottengo i valori effettivi e previsti riportati alla stdout, al fine di eseguire il debug i metodi quindi questa soluzione non farà il lavoro:
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() );
}
Soluzione
Sicuramente se tutto si sta testando è se la vostra base è ortonormale, allora questo è ciò che è necessario testare?
// 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));
Altri suggerimenti
Una possibilità è quella di creare la propria funzione 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);
}
mi piacerebbe utilizzare una funzione di utilità o di classe in modo che si può fare qualcosa di simile:
CHECK_EQUAL(VectorList(0,0,1)(0,0,-1), onb.v());
Dato, che l'interpretazione di uguaglianza è un po 'strano, ma dovrebbe stampare voi tutti i valori che si desidera vedere, senza la necessità di introdurre una macro personalizzata.
Se siete preoccupati per EQUAL
in quel contesto, una macro personalizzato come CHECK_CONTAINS()
non dovrebbe essere troppo difficile da fare.
VectorList
sarebbe costruito come temporanea e operator()
essere usato per inserire i valori nell'elenco contenuto di Vector
s, simile a Boost.Assign .
approccio di base:
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();
}
};