Estoy refacturando un código que implementa una fórmula y quiero hacerlo primero para probar, mejorar mis habilidades de prueba y dejar el código cubierto.Cómo probar la fórmula de varios parámetros
Esta pieza de código en particular es una fórmula que toma 3 parámetros y devuelve un valor. Incluso tengo algunas tablas de datos con resultados esperados para diferentes entradas, así que en teoría, podría jusst escribir un trillón de pruebas, simplemente cambiando los parámetros de entrada y comprobando los resultados contra el valor esperado correspondiente.
Pero pensé que debería haber una mejor manera de hacerlo, y mirando los documentos que encontré, encontré Value Parameterized Tests.
Entonces, con eso ahora sé cómo crear automáticamente las pruebas para las diferentes entradas.
¿Pero cómo obtengo el resultado esperado correspondiente para compararlo con el calculado?
Lo único que he podido encontrar es una tabla de búsqueda estática y un miembro estático en el elemento de texto que es un índice de la tabla de búsqueda y se incrementa en cada ejecución. Algo como esto:
#include "gtest/gtest.h"
double MyFormula(double A, double B, double C)
{
return A*B - C*C; // Example. The real one is much more complex
}
class MyTest:public ::testing::TestWithParam<std::tr1::tuple<double, double, double>>
{
protected:
MyTest(){ Index++; }
virtual void SetUp()
{
m_C = std::tr1::get<0>(GetParam());
m_A = std::tr1::get<1>(GetParam());
m_B = std::tr1::get<2>(GetParam());
}
double m_A;
double m_B;
double m_C;
static double ExpectedRes[];
static int Index;
};
int MyTest::Index = -1;
double MyTest::ExpectedRes[] =
{
// C = 1
// B: 1 2 3 4 5 6 7 8 9 10
/*A = 1*/ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0,
/*A = 2*/ 1.0, 3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0,
/*A = 3*/ 2.0, 5.0, 8.0, 11.0, 14.0, 17.0, 20.0, 23.0, 26.0, 29.0,
// C = 2
// B: 1 2 3 4 5 6 7 8 9 10
/*A = 1*/ -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0,
/*A = 2*/ -2.0, 0.0, 2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0,
/*A = 3*/ -1.0, 2.0, 5.0, 8.0, 11.0, 14.0, 17.0, 20.0, 23.0, 26.0,
};
TEST_P(MyTest, TestFormula)
{
double res = MyFormula(m_A, m_B, m_C);
ASSERT_EQ(ExpectedRes[Index], res);
}
INSTANTIATE_TEST_CASE_P(TestWithParameters,
MyTest,
testing::Combine(testing::Range(1.0, 3.0), // C
testing::Range(1.0, 4.0), // A
testing::Range(1.0, 11.0) // B
));
¿Es esta una buena aproximación o ¿Hay alguna forma mejor para obtener el derecho de resultado para cada ejecución esperada?
Gracias. En este caso, la especificación que debo seguir proporciona la fórmula más algunas tablas con los resultados esperados para algunos valores. Puedo estar bastante seguro de que si mis resultados coinciden con esas tablas, lo he hecho bien.De hecho, ya he encontrado algunos valores incorrectos en la especificación, gracias a las pruebas. – MikMik
Eso es genial. Si agrega sus datos de prueba dentro de su clase de prueba, el problema será que, en el futuro, si desea probar otro escenario, deberá actualizar su clase nuevamente. Pero si accede a sus datos de prueba desde un archivo externo, se reducirá la capacidad de mantenimiento de su caso de prueba. Porque va a actualizar ese archivo sin formato para agregar una nueva prueba de datos. Eso es. No es necesario construir tu clase y luego implementarla de nuevo. –
@PritamKarmakar, quiere decir que la mantenibilidad del caso de prueba aumentará, ¿verdad? El esfuerzo requerido para mantenerlo se reducirá. – Alan