He empezado a utilizar googletest para implementar pruebas y tropezamos con esta cita en la documentación relativa a value-parameterized tests¿Las pruebas basadas en datos son malas?
- ¿Quieres probar el código a través de varias entradas (también conocido como las pruebas según los datos). Esta función es fácil de abusar, así que ¡por favor ejercite su buen sentido al hacerlo!
Creo que estoy hecho "abusar" del sistema cuando se hace lo siguiente y le gustaría conocer sus opiniones y comentarios sobre este asunto.
Asumamos que tenemos el siguiente código:
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, así que con este código, sin duda tiene sentido para probar f()
(por comparación con f_alt()
) con diferentes tamaños de matriz de entrada de datos generados aleatoriamente para poner a prueba la la corrección de las ramas. Además de eso, tengo varios structs
como SumMethod
, MultiplyMethod
, etc, así que me estoy quedando un número bastante grande de pruebas también para diferentes tipos:
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);
// ...
Ahora, por supuesto, mi pregunta es: ¿Esto hace cualquier sentido y por qué sería esto malo?
De hecho, he encontrado un "error" al ejecutar pruebas con float
s donde f()
y f_alt()
daría valores diferentes con SumMethod
debido al redondeo, lo que podría mejorar mediante la preclasificación la matriz de entrada etc .. A partir de esta experiencia Considero que en realidad esta es una buena práctica.
Los datos generados aleatoriamente son malos por dos razones: primero, porque como mencionaste, las pruebas no son reproducibles. Y en segundo lugar, porque los casos de esquina pueden no estar cubiertos por datos generados aleatoriamente. Guardar los vectores aleatorios no hace nada para el segundo inconveniente. –
Gracias. Enmendé mi respuesta, tienes razón, por supuesto. – haimg
@haimg: si haces una prueba de caja negra, ¿cómo conoces el algoritmo utilizado y sus casos de esquina? :-) –