Ho iniziato usando googletest per implementare i test e ci siamo imbattuti in questa citazione nella documentazione relativa value-parameterized testsIl test guidato dai dati è errato?
- Si desidera testare il proprio codice su vari ingressi (anche noto come data-driven test). Questa funzione è facile da abusare, quindi si prega di esercitare il buon senso quando lo si fa!
penso che sto davvero "abusando" il sistema quando si fa la seguente e vorrei sentire il vostro input e opinioni su questa materia.
Supponiamo di avere il seguente codice:
template<typename T>
struct SumMethod {
T op(T x, T y) { return x + y; }
};
// optimized function to handle different input array sizes
// in the most efficient way
template<typename T, class Method>
T f(T input[], int size) {
Method m;
T result = (T) 0;
if(size <= 128) {
// use m.op() to compute result etc.
return result;
}
if(size <= 256) {
// use m.op() to compute result etc.
return result;
}
// ...
}
// naive and correct, but slow alternative implementation of f()
template<typename T, class Method>
T f_alt(T input[], int size);
Ok, quindi con questo codice, certamente il senso di testare f()
(per confronto con f_alt()
) con differenti formati di matrice di ingresso di dati generati casualmente per verificare la correttezza dei rami. In cima a quello, ho diversi structs
come SumMethod
, MultiplyMethod
, ecc, quindi sono l'esecuzione di un numero piuttosto elevato di test anche per i diversi tipi:
typedef MultiplyMethod<int> MultInt;
typedef SumMethod<int> SumInt;
typedef MultiplyMethod<float> MultFlt;
// ...
ASSERT(f<int, MultInt>(int_in, 128), f_alt<int, MultInt>(int_in, 128));
ASSERT(f<int, MultInt>(int_in, 256), f_alt<int, MultInt>(int_in, 256));
// ...
ASSERT(f<int, SumInt>(int_in, 128), f_alt<int, SumInt>(int_in, 128));
ASSERT(f<int, SumInt>(int_in, 256), f_alt<int, SumInt>(int_in, 256));
// ...
const float ep = 1e-6;
ASSERT_NEAR(f<float, MultFlt>(flt_in, 128), f_alt<float, MultFlt>(flt_in, 128), ep);
ASSERT_NEAR(f<float, MultFlt>(flt_in, 256), f_alt<float, MultFlt>(flt_in, 256), ep);
// ...
Ora, naturalmente, la mia domanda è: questo fa qualsiasi senso e perché questo sarebbe male?
In realtà, ho trovato un "bug" durante l'esecuzione di test con float
s dove f()
e f_alt()
darebbe valori diversi con SumMethod
a causa degli arrotondamenti, che ho potuto migliorare di preselezione della matrice di ingresso, ecc .. Da questa esperienza Considero questo in qualche modo una buona pratica.
I dati generati casualmente sono negativi per due motivi: in primo luogo, perché come hai detto, i test non sono riproducibili. E in secondo luogo, perché i casi angolari potrebbero non essere coperti da dati generati casualmente. Salvare i vettori casuali non fa nulla per il secondo inconveniente. –
Grazie. Ho modificato la mia risposta, hai ragione, ovviamente. – haimg
@haimg - Se stai facendo un test della scatola nera, come fai a sapere l'algoritmo usato e i suoi casi d'angolo? :-) –