2011-06-06 13 views
13

Mi piacerebbe scrivere test C++ di Google che possano utilizzare value-parameterized tests con più parametri di diversi tipi di dati, adattando idealmente la complessità dei seguenti test mbUnit scritti in C++/CLI.È possibile che il valore di Googletest parametrizzato con più tipi di parametri diversi corrisponda alla flessibilità di mbUnit?

Nota quanto è compatto, con l'attributo [Test] che indica che questo è un metodo di prova e gli attributi [Row(...)] che definiscono i valori per un'istanza.

[Test] 
[Row("Empty.mdb", "select count(*) from collar", 0)] 
[Row("SomeCollars.mdb", "select count(*) from collar", 17)] 
[Row("SomeCollars.mdb", "select count(*) from collar where max_depth=100", 4)] 
void CountViaDirectSQLCommand(String^ dbname, String^ command, int numRecs) 
{ 
    String^ dbFilePath = testDBFullPath(dbname); 
    { 
     StAnsi fpath(dbFilePath); 
     StGdbConnection db(fpath); 
     db->Connect(fpath); 
     int result = db->ExecuteSQLReturningScalar(StAnsi(command)); 
     Assert::AreEqual(numRecs, result); 
    } 
} 

O ancora meglio, questo test più esotico da C# (spingere i confini di ciò che può essere definito in .Net attributi al di là di ciò che è possibile in C++/CLI):

[Test] 
[Row("SomeCollars.mdb", "update collar set x=0.003 where hole_id='WD004'", "WD004", 
    new string[] { "x", "y" }, 
    new double[] { 0.003, 7362.082 })] // y value unchanged 
[Row("SomeCollars.mdb", "update collar set x=1724.8, y=6000 where hole_id='WD004'", "WD004", 
    new string[] { "x", "y" }, 
    new double[] { 1724.8, 6000.0 })] 
public void UpdateSingleRowByKey(string dbname, string command, string idValue, string[] fields, double[] values) 
{ 
... 
} 

Il help dice I test con parametri parametrici consentono di scrivere il test una sola volta e quindi di istanziarlo facilmente ed eseguirlo con un numero arbitrario di valori di parametro. ma sono abbastanza sicuro che si riferisca al numero di casi di test.

Anche senza variare i tipi di dati, mi sembra che un test parametrizzato può assumere solo un parametro ?

risposta

21

Sì, c'è un singolo parametro. È possibile rendere quel parametro arbitrariamente complesso, però. Si potrebbe adattare il codice dalla documentazione di usarti tipo, ad esempio:

class AndyTest : public ::testing::TestWithParam<Row> { 
    // You can implement all the usual fixture class members here. 
    // To access the test parameter, call GetParam() from class 
    // TestWithParam<T>. 
}; 

quindi definire il test con parametri:

TEST_P(AndyTest, CountViaDirectSQLCommand) 
{ 
    // Call GetParam() here to get the Row values 
    Row const& p = GetParam(); 
    std::string dbFilePath = testDBFullPath(p.dbname); 
    { 
    StAnsi fpath(dbFilePath); 
    StGdbConnection db(p.fpath); 
    db.Connect(p.fpath); 
    int result = db.ExecuteSQLReturningScalar(StAnsi(p.command)); 
    EXPECT_EQ(p.numRecs, result); 
    } 
} 

Infine, un'istanza:

INSTANTIATE_TEST_CASE_P(InstantiationName, AndyTest, ::testing::Values(
    Row("Empty.mdb", "select count(*) from collar", 0), 
    Row("SomeCollars.mdb", "select count(*) from collar", 17), 
    Row("SomeCollars.mdb", "select count(*) from collar where max_depth=100", 4) 
)); 
+1

Grazie, Rapinare. Usare una struttura di qualche tipo per il singolo parametro era ciò che temevo sarebbe stata la soluzione. Come puoi vedere dalla mia modifica per mostrare il test completo, rende l'approccio gtest molto più ingombrante dello stile mbUnit/NUnit. Ho appena realizzato che c'è anche l'impegno a TUTTI i test per un dato apparecchio che deve essere parametrizzato rispetto ad essere una scelta per test per quelli .Net. Tuttavia, per le persone che non vogliono usare C++/CLI per testare il loro codice nativo, la parametrizzazione gtest è ancora migliore del nulla offerto da altri kit nativi! –

+0

Sì, ma è banale creare un altro dispositivo di prova se si desidera un altro tipo di parametro. È possibile utilizzare l'ereditarietà se tutti hanno bisogno di un codice di installazione e di rimozione simile. Se non hai setup e teardown, il dispositivo può essere * esattamente * il codice che ho mostrato qui per 'AndyTest'. I corpi dei test non devono essere molto più voluminosi, come mostra la mia modifica introducendo la variabile di parametro 'p'. Probabilmente non avrai mai * abbastanza * elegante quanto i framework di test .Net dal momento che C++ non supporta le annotazioni, quindi avrai sempre alcune dichiarazioni separate. –

+0

@RobKennedy Questo attributo 'Row' ha documentazione ..? Puoi indicarmi un link o qualcosa del genere? –

Problemi correlati