Domanda

Ai fini dei test dell'unità, ho bisogno di muovere una risposta di rete.La risposta è normalmente un flusso di byte, memorizzato come const vector<uint8_t>.Per il test dell'unità, tuttavia, vorrei produrre il vettore con i dati che è hardcoded nel file CPP o letto da un file nella stessa soluzione.I miei dati di esempio sono circa 6 kb.Qual è la guida generale su dove posizionare i dati quando si utilizza Googlest ?

È stato utile?

Soluzione

Forse (a) è necessario una grande sequenza di dati per un ruolo in cui I casi di prova lo leggeranno. Questo potrebbe anche essere (classe) dati globali, con Accesso const.

Forse (B) è necessario una grande sequenza di dati per un ruolo in cui I casi di test leggeranno e la modificheranno o lo distruggeranno. Questo deve essere Reninizializzato per caso di prova e con accesso non generatoriAgCode.

Forse entrambi. In entrambi i casi, una convenzionale implementazione Googlest sarebbe Utilizzare un Test Fixture Per incapsulare l'acquisizione dei dati, lo acquisirebbe nel Implementazione della funzione membro virtuale di const del dispositivo, e Accedi tramite un metodo Gettter del dispositivo.

Il seguente programma illustra un dispositivo che fornisce sia per caso Dati mutabili e dati costanti globali acquisiti da file.

#include <vector>
#include <fstream>
#include <stdexcept>
#include "gtest/gtest.h"

class foo_test : public ::testing::Test
{
protected:
    virtual void SetUp() {
        std::ifstream in("path/to/case_data");
        if (!in) {
            throw std::runtime_error("Could not open \"path/to/case_data\" for input");
        }
        _case_data.assign(
            std::istream_iterator<char>(in),std::istream_iterator<char>());
        if (_global_data.empty()) {
            std::ifstream in("path/to/global_data");
            if (!in) {
                throw std::runtime_error(
                    "Could not open \"path/to/global_data\" for input");
            }
            _global_data.assign(
                std::istream_iterator<char>(in),std::istream_iterator<char>());
        }
    }
    // virtual void TearDown() {}   
    std::vector<char> & case_data() {
        return _case_data;
    }
    static std::vector<char> const & global_data() {
        return _global_data;
    }

private:
    std::vector<char> _case_data;
    static std::vector<char> _global_data;

};

std::vector<char> foo_test::_global_data;

TEST_F(foo_test, CaseDataWipe) {
  EXPECT_GT(case_data().size(),0);
  case_data().resize(0);
  EXPECT_EQ(case_data().size(),0);
}

TEST_F(foo_test, CaseDataTrunc) {
  EXPECT_GT(case_data().size(),0);
  case_data().resize(1);
  EXPECT_EQ(case_data().size(),1);
}

TEST_F(foo_test, HaveGlobalData) {
  EXPECT_GT(global_data().size(),0);
}


int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
.

Per caso (a), è inoltre possibile prendere in considerazione l'acquisizione dei dati in un Impostazione globale Funzione membro mediante subclassing Setup(), ma vedo no La ragione generale per preferire farlo in questo modo.

... o codice rigido IT?

Quindi al problema se mantenere i dati del test in un file o codice rigido nella fonte di test. lettori che sono felici a questo punto saranno annoiati solo da ora in poi .

Come problema generale, questa questione di giudizi in-the-circostanze e non penso che l'uso di googletest tips sulle scale materiali. Penso che il principale considerazione è: è desiderabile essere in grado di variare un oggetto dei dati di prova senza Ricostruire la suite di prova?

Dì la ricostruzione della suite di prova per variare questo oggetto è un costo non trascurabile e tu anticipare che il contenuto dell'oggetto varierà in futuro in modo indipendente del codice di prova associato. O può variare, indipendentemente dal codice di prova associato, per diverse configurazioni del sistema sotto test. In tal caso, ottenere meglio il Articolo da un file o da un'altra fonte che può essere selezionato da parametri di runtime di la suite di prova. In Googlest, la sottoclassante ::testing::Environment è a Struttura progettata per l'acquisizione parametrizzata delle risorse suite di prova.

Se in realtà il contenuto di un elemento di dati di prova è esattamente accoppiato con Il codice di test associato, quindi la codifica dura in caso di prova è più improbabile essere una scelta prudente. (E test dei file, al contrario di altri tipi di runtime I configuratori, hanno la proprietà preziosa che possono essere controllate dalla versione in lo stesso sistema del codice sorgente.)

Se il contenuto di una voce di dati di prova è accoppiata con decisione con il Codice di prova associato, quindi sono prevenuto per il codice fisso piuttosto che estrarlo da un file di dati. Semplicemente prevenuto, non commesso dogmaticamente. Forse il tuo test Suite impiega robusta strutture della biblioteca per l'iniziativa dei dati del test API pubblico da, Dì, file XML che vengono anche agganciati a Gestione test e gestione dei difetti, sistemi. Bene!

Lo prendo come chiaramente desiderabile che se un file di dati di test è un primario Prova risorsa - uno che la suite di prova non può generare - allora il suo contenuto era meglio essere dati testuali che un manutentore competente può facilmente comprendere e manipolare. In questa impostazione, ovviamente, ritenirai che a Elenco dei costanti esagonali C / C ++, ad esempio, è dati testuali - è codice sorgente. Se un file di test contiene dati binari o scoraggialmente orientati alla macchina Quindi la suite di prova aveva il migliore contiene i mezzi della sua produzione da leggibili Risorse primarie. A volte è inevitabile per una suite di prova da dipendere binari "archetipici" provenienti dall'esterno, ma quasi inevitabilmente comportano il Grim per lo spettacolo degli ingegneri di prova e dei fissatori di errori che girano il grigio davanti agli editor di HEX.

Dato il principio secondo cui i dati di prova primari dovrebbero essere leggibili ai manutentori, noi può prenderlo come norma che i dati dei test primari saranno "alcuni tipi di codice": lo farà Sii senza logico, ma sarà il tipo di roba testuale che i programmatori sono abituati a rilevare e modificare.

Immagina che una particolare sequenza di 4096 numeri interi non firmati a 64 bit (Il grande tavolo magico) è richiesto per testare il tuo software ed è strettamente sposati al codice di prova associato. Potrebbe essere codificato in modo difficile come un enorme vettore o array Elenco inizializzatore in un file sorgente della suite di prova. Potrebbe essere Estratte dalla suite di prova da un file di dati gestito in formato CSV o in Linee punteggiate csv.

per l'estrazione da un file di dati e contro la codifica rigida, può essere sollecitato (come da risposta di Andrew McDonell) che questo raggiunge prevalentemente un disentnicling di Revisioni al BMT dalle revisioni dell'altro codice nello stesso file sorgente. Allo stesso modo potrebbe essere invitato che qualsiasi codice sorgente che cornici enorme letterali

Le inizializzazioni tendono ad essere insorvedibili e quindi una manutenzione responsabilità.

Ma entrambi questi punti possono essere contrastati con l'osservazione che la definizione La dichiarazione del BMT potrebbe essere codificata in un file sorgente da solo. esso potrebbe essere un criterio di revisione del codice per la suite di prova che le inizializzazioni dei dati dei dati deve essere così codificati - e forse in file che aderiscono a una denominazione distintiva convenzione. Una politica fanatica, per essere sicuri, ma non più fanatici di Uno che insisterà che tutti gli inizializzatori dei dati di test devono essere estratti dai file. Se un manutentore è obbligato a indagare sul BMT in qualsiasi file contiene, Non farà differenza se l'estensione del file è class ::testing::Environment, .cpp o Qualunque cosa: tutte le questioni sono la comprensibilità di "il codice".

Per la codifica rigida e contro l'estrazione da un file di dati, può essere sollecitato Questa estrazione da un file di dati deve introdurre una fonte di irrilevante potenziali fallimenti in casi di test - tutti i non dovrebbero accadere gli errori potrebbe sconfiggere lettura dei dati giusti da un file. Questo impone un sovraccarico Sviluppo del test per effettuare una distinzione corretta e chiara tra errori di test genuini e fallimenti per acquisire i dati del test dal file e per diagnosticare chiaramente tutto il possibile Cause di quest'ultimo.

Nel caso di quadri funzionali di googlest e relativamente funzionali questo punto può essere contrastato, in misura, pubblicizzando le classi di base del dispositivo polimorfico Come .dat e ::testing::Test. Questi facilitano Lo sviluppatore del test nell'incapsulando l'acquisizione delle risorse di test in caso di test o inizializzazione della suite di prova in modo che sia tutto finito, sia con successo che Con un guasto diagnosticato, prima che vengano eseguiti test costituenti di qualsiasi caso di prova. RAII può mantenere una divisione non procematica tra fallimenti di installazione e guasti reali.

Tuttavia, c'è un sovraccarico irriducibile per il file di gestione del file percorso e c'è un sovraccarico operativo che le caratteristiche RAII del quadro Non fare nulla da ridurre. Nei miei rapporti con sistemi di prova pesante che commerciano File di dati, i file di dati sono solo più inclini a contrattempi operativi di File di origine che devono essere presenti e corretti solo in costruzione. I file di dati hanno maggiori probabilità di alzarsi mancanti o sfacciati durante il runtime, o contenente roba malformata, o in qualche modo essere diventati negativi, o in qualche modo per apparire alla revisione sbagliata. I loro usi in un sistema di test non sono così semplici o rigidamente controllati come quelli dei file sorgente. cose Che non dovrebbe accadere che accade ai file di dati del test fa parte dell'attrito operativo di Sistemi di prova che fanno affidamento su di loro ed è proporzionale al loro numero.

Dal momento che File di origine può incapsulare le inizializzazioni dei dati di prova igienicamente Per il tracciamento delle revisioni, la codifica rigida può essere equiparata all'estrazione da a File, con il preprocessore che esegue l'estrazione come sottoprodotto della compilazione. In quella luce, perché utilizzare altri macchinari, con passività aggiuntive, per estrarla? Ci possono essere buone risposte, come l'interfaccia XML suggerita con la gestione dei test, I sistemi di gestione dei difetti, ma "i dati dei test, quindi non il codice fisso" non è buono.

Anche se una suite di prova deve supportare varie configurazioni del sistema sotto Testare che chiamano varie istanze di un elemento di dati di prova, se i dati L'articolo è convinto con Build Configurazioni della suite di prova , puoi Bene immobile (igienicamente) hard-code e lasciano la compilazione condizionata selezionare La giusta codifica rigida.

Finora non ho sfidato l'argomento di revisione-hygeine-hygeine Per la segregazione basata su file di inizializzatori di dati di test. Ho appena fatto il Puntare che i file di origine regolari in cui le inizializzatori sono in grado di codifica rigida realizzare questa segregazione. E non voglio sollevare quella discussione, ma Voglio fermarlo a corto della conclusione fanatica che test iniziali inizializzatori dovrebbe in linea di principio essere sempre estratti da file dedicati - se file di origine o file di dati.

Non c'è bisogno di BELAbur le ragioni per resistere a questa conclusione. Quel modo Lies Test Code che è localmente meno intelligibile della pizza media Il programmatore scriverà e organizzazioni di file suite di test che crescono la mente-aggangolare molto più rapidamente di quanto sia necessario o sano. Normalmente, Tutte le risorse primarie della suite di test sono "alcuni tipi di codice". UN Skillset del programmatore include l'abilità del codice divisorio in file con granularità appropriata per garantire l'appropriato hygeine di tracciamento di revisione. Non è una procedura meccanica, è un'esperienza, per la revisione del codice da coprire. La recensione del codice può e deve garantire che le inizializzazioni dei dati di prova, comunque Sono realizzati, sono ben progettati e realizzati con il tracciamento della revisione Proprio come in tutti gli altri rispetti di routine.

Bottom line: Se vuoi essere in grado di eseguire la stessa build della tua suite di test per

una varietà Di queste risposte di rete finta, leggilo da un file.Se l'altra parte è è invariante o covariante con configurazione di configurazione della suite di test, perché non hard Codice It?

Altri suggerimenti

(caveat - Questa risposta è generica a qualsiasi quadro di prova unitario)

Preferisco mantenere i file di dati di test come oggetti separati in un sistema di controllo della revisione.Ciò fornisce i seguenti vantaggi:

    .
  • È possibile codificare il test dell'unità per accettare qualsiasi o più file di dati per testare una varietà di situazioni
  • È possibile tenere traccia delle modifiche nei dati secondo necessità

Se non si desidera che l'esecuzione del test dell'unità che legge un file di dati, che può essere una condizione necessaria in alcune situazioni, è possibile scegliere di scrivere un programma o uno script che genera codice C ++ che inizializza il vettore all'installazione del dispositivo. .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top