2016-07-05 38 views
5

Con Google test voglio specificare un dispositivo di prova da utilizzare in diversi casi di test. L'apparecchiatura deve assegnare e deallocare oggetti della classe TheClass e la sua classe di gestione dei dati TheClassData, dove la classe di gestione dei dati richiede il nome di un file di dati.
Per i diversi test, il nome del file dovrebbe variare.Specificare gli argomenti del costruttore per un dispositivo di prova Google

ho definito il seguente apparecchio:

class TheClassTest : public ::testing::Test { 
protected: 
    TheClassTest(std::string filename) : datafile(filename) {} 
    virtual ~TheClassTest() {} 
    virtual void SetUp() { 
    data = new TheClassData(datafile); 
    tc = new TheClass(data); 
    } 
    virtual void TearDown() { 
    delete tc; 
    delete data; 
    } 

    std::string datafile; 
    TheClassData* data; 
    TheClass* tc; 
}; 

Ora, diverse prove dovrebbero usare l'apparecchio con i nomi di file differenti. Immagina questo come impostazione di un ambiente di test.

La domanda: Come specificare il nome file da un test, ad esempio chiamare un costruttore non predefinito di un proiettore?

Ho trovato cose come ::testing::TestWithParam<T> e TEST_P, che non aiuta, poiché non voglio eseguire un test con valori diversi, ma test diversi con un faro.

+0

Quindi vuoi gestire quel dispositivo da solo? Il test runner di test di google non può creare un'istanza di fixture con parametri. –

+0

Voglio eseguire un test (probabilmente 'TEST_F') usando l'apparecchio. Quindi la risposta è che non è possibile? Grazie. – Gregor

+0

Penso che 'TestWithParam ' e 'TEST_P' sia esattamente ciò di cui hai bisogno. Cerca i [Documenti avanzati] (https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md) come utilizzarli nella pratica. Puoi sempre istanziare l'istanza sotto test (presumo che sia 'TheClass') all'interno del testcase. –

risposta

3

Come suggerito da un altro utente, non è possibile ottenere ciò che si desidera creando un'istanza utilizzando un costruttore non predefinito. Tuttavia, ci sono altri modi. Semplicemente sovraccaricare il che la versione SetUp funzione e chiamata esplicitamente nelle prove:

class TheClassTest : public ::testing::Test { 
protected: 
    TheClassTest() {} 
    virtual ~TheClassTest() {} 
    void SetUp(const std::string &filename) { 
     data = new TheClassData(filename); 
     tc = new TheClass(data); 
    } 
    virtual void TearDown() { 
     delete tc; 
     delete data; 
    } 

    TheClassData* data; 
    TheClass* tc; 
}; 

Ora nel test è sufficiente utilizzare questo sovraccarico per impostare il nome del file:

TEST_F(TheClassTest, MyTestCaseName) 
{ 
    SetUp("my_filename_for_this_test_case"); 

    ... 
} 

Il senza parametri TearDown verrà automaticamente pulire quando il test è completo.

+0

Grande. Molte grazie! – Gregor

+0

Il metodo SetUp sarà ancora chiamato da gtest, con conseguente due chiamate a SetUp ... quindi in questo caso c'è una perdita di memoria dal momento che TearDown elimina solo le ultime allocazioni. Vorrei rinominare SetUp a qualcos'altro in modo che Gtest non lo chiamasse. – Andreas

+0

Scusa, mi sbaglio. Dato che il tuo 'Setup' prende un parametro, non verrà chiamato da gtest. Rinominerei 'SetUp' in qualcos'altro dato che può essere confuso con' SetUp() 'che viene chiamato da gtest. – Andreas

0

Utilizzare la classe corrente come classe di base per i vostri dispositivi:

class TheClassTestBase : public ::testing::Test { 
protected: 
    TheClassTestBase(std::string filename) : datafile(filename) {} 
    ... 
}; 

Per ogni nome di file specifico - uso apparecchio derivato:

class TheClassTestForFooTxt : public TheClassTestBase { 
protected: 
    TheClassTestForFooTxt() : TheClassTestBase ("foo.txt") {} 
}; 

Tuttavia, questo è il primo passo in più necessario per ogni serie di parametri - così puoi provare a usare modelli o macro per farlo con meno sforzo. Come:

template <typename ClassTestTag> 
struct ClassTestParams 
{ 
    static std::string filename; 
}; 

template<typename ClassTestTag> 
class TheClassTest : public TheClassTestBase { 
protected: 
    TheClassTest() : TheClassTestBase (ClassTestParams<ClassTestTag>::filename) {} 
}; 

Poi - per ogni serie di parametri - do che:

class FooTxtTag {}; 
template <> std::string ClassTestParams<FooTxtTag>::value = "foo.txt"; 
using TheClassTestForFooTxt = TheClassTest<FooTxtTag>; 
TEST_F(TheClassTestForFooTxt, xxxx) {} 

Tuttavia - nel caso specifico - Vorrei anche provare GoogleTest:type-parameterized-tests.

+0

Grazie. Penso che questo sia un po 'troppo impegnativo per la dimensione del mio problema. – Gregor