Wie um zu testen, multi-parameter-Formel
Ich bin refactoring code implementiert, dass eine Formel, und ich will es testen-die ersten, zu verbessern, meine Fähigkeiten testen, und lassen Sie den code abgedeckt.
Diesem Stück code ist eine Formel, die nimmt 3 Parameter und gibt einen Wert zurück. Ich habe sogar einige Daten Tabellen mit den erwarteten Ergebnisse für verschiedene Eingaben, so in der Theorie, ich könnte jusst geben eine Unmenge tests, nur für die änderung der input-Parameter und überprüfen Sie das Ergebnis mit dem entsprechenden erwarteten Wert.
Aber ich dachte es sollte ein besserer Weg, es zu tun, und im Blick auf die docs die ich gefunden habe, Wert Parametrisierten Tests.
So, ich weiß jetzt, was automatisch zu erstellen, der die Prüfungen für die verschiedenen Eingänge.
Aber wie bekomme ich die entsprechenden erwarteten Ergebnis zu vergleichen mit meinem berechnet man die?
Das einzige, was ich habe, in der Lage zu kommen mit ist eine statische lookup-Tabelle und eine statische member in der text-Vorrichtung, die einen index für die lookup-Tabelle und erhöht in jedem Lauf. So etwas wie dieses:
#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
));
Ist das ein guter Ansatz oder gibt es einen besseren Weg, um die richtigen erwartete Ergebnis für jeden Lauf?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gehören das erwartete Ergebnis zusammen mit den Eingängen. Anstelle eines triple-input-Werte, machen Sie Ihren test-parameter ein 4-Tupel.
Der Nachteil ist, dass Sie nicht in der Lage zu halten Ihre test-Parameter präzise mit
testing::Combine
. Verwenden Sie stattdessentesting::Values
zu definieren, die jede einzelne 4-Tupel, die Sie testen möchten. Sie könnten auf den argument-count limit fürValues
, so können Sie teilen Sie Ihre instantiierungen, z.B. indem er alle C = 1 Fällen in einem und alle die C = 2 Fällen in einem anderen.Oder setzen Sie alle Werte in einem array getrennt von Ihrer Instanziierung und verwenden Sie dann
testing::ValuesIn
:Siehe hard-Codierung auf das erwartete Ergebnis ist, wie Sie die Begrenzung wieder die nicht der Testfälle. Wenn Sie wollen bekommen Sie eine komplette data-driven-Modell, würde ich eher vorschlagen, Sie zu Lesen, Eingaben, erwartete Ergebnis von einer flachen Datei/xml/xls-Datei.
Ich habe nicht viel Erfahrung mit unit-Tests, aber als Mathematiker, ich glaube, es gibt nicht viel mehr Sie tun könnte.
Wenn Sie wissen, dass einige Invarianten der Formel, den Sie testen könnte, aber ich denke das macht nur Sinn in sehr wenigen Szenarien.
Als ein Beispiel, wenn Sie möchten, um zu testen, ob Sie korrekt umgesetzt werden, der natürlichen Exponentialfunktion, nutzen Sie die Erkenntnis, dass es die Ableitung sollte den gleichen Wert wie die Funktion selbst. Könnte man dann berechnen Sie eine numerische approximation der Ableitung für eine million Punkte und sehen Sie, wenn Sie sind nah an den tatsächlichen Wert für die Funktion.