Test Driven Development: un modo valido / accettato per testare le operazioni del file system?

14

Sto lavorando a un progetto nel momento in cui genera una tabella (tra le altre cose) basata sul contenuto di un file system e, a sua volta, modifica alcuni metadati sulle cose che trova. La domanda è: come dovrebbero essere scritti i test intorno a questo o impostare? C'è un modo semplice per deriderlo? O dovrei impostare una "sandbox"?

    
posta Kirbinator 07.10.2013 - 05:31
fonte

5 risposte

13

Come sempre in TDD con risorse esterne: crei una o più interfacce per le operazioni del tuo filesystem e "le prendi in giro". Vuoi testare il tuo "generatore di tabelle" e il tuo codice di modifica dei meta-dati, non le operazioni del file system stesso (molto probabilmente stai usando le implementazioni di librerie già pronte per accedere al file system).

    
risposta data 07.10.2013 - 08:07
fonte
10

Cosa c'è di sbagliato nell'avere un file system "test"?

Crea una cartella modello / struttura di directory che abbia abbastanza contenuti per testare le tue operazioni.

Durante l'impostazione del test dell'unità, copiare questa struttura iniziale (si consiglia di riavvolgere il modello e decomprimerlo nell'area di prova). Esegui i tuoi test. Elimina tutto durante lo smontaggio.

Il problema con il mocking è che in primo luogo i file system, i sistemi operativi e i database che appartengono al tuo progetto non si qualificano realmente come risorse esterne e in secondo luogo le chiamate di sistema a basso livello richiedono tempo e errori.

    
risposta data 07.10.2013 - 10:13
fonte
2

Comprendo la tua domanda come "Un modo valido / accettato per testare una classe che dipende dalle operazioni del file system". Non credo che tu voglia testare il filesystem del tuo sistema operativo.

Per mantenere lo sforzo di "interfacciarsi con le operazioni del tuo filesystem e" deriderli "come risposta di @Doc Brown suggerita il più piccola possibile è una buona idea usare java stream binari oppure lettore di testo (o equivalente in c # o il linguaggio di programmazione che stai utilizzando) invece di utilizzare File con nomi di file direttamente nella tua classe sviluppata da tdd.

Esempio:

Usando java ho implementato una classe CsvReader

public class CsvReader {
    private Reader reader;

    public CsvReader(Reader reader) {
        this.reader = reader;
    }
}

Per i test che ho usato in dati di memoria come questo

String contentOfCsv = "TestColumn1;TestColumn2\n"+
    "value1;value2\n";

CsvReader sut = new CsvReader(java.io.StringReader(contentOfCsv));

o incorporare testdata nelle risorse

CsvReader sut = new CsvReader(getClass().getResourceAsStream("/data.csv"));

In produzione uso il file system

CsvReader sut = new CsvReader(new BufferedReader( new FileReader( "/import/Prices.csv" ) ));

In questo modo il mio CsvReader non dipende dal filesystem ma da un'astrazione "Reader" dove esiste un'implementazione per il filesystem.

    
risposta data 07.10.2013 - 17:07
fonte
2

Questo è il tipo di cosa che devi assolutamente provare per l'integrazione, dato che i file system reali hanno ogni tipo di comportamento strano (come il modo in cui Windows non consente l'eliminazione di un file se qualsiasi processo, incluso il deleter, lo ha aperto).

Quindi l'approccio TDD è di scrivere prima il test di integrazione (TDD, in senso stretto, non ha concetti distinti di 'unit test' e 'test di integrazione', sono solo test). Abbastanza probabile che sarà abbastanza; quindi lavoro svolto, stop, vai a casa .

In caso contrario, ci sarà una certa complessità interna che non è facile da testare adeguatamente sistemando i file. In tal caso, devi semplicemente rimuovere la complessità, metterla in una classe e scrivere test di unità per quella classe . Molto probabilmente scoprirai che quella classe comune è utilizzabile anche nel database, nel file xml, ecc.

In nessun caso prendi il nucleo fondamentale del codice che stai scrivendo e lo "prendi in giro" per scrivere test che valuteranno se l'unità in prova è sbagliata.

    
risposta data 08.04.2015 - 23:55
fonte
0

Crea un wrapper per le operazioni del file system. Nei test, passare una simulazione che implementa la stessa interfaccia del wrapper. In produzione, passa nel wrapper.

    
risposta data 07.10.2013 - 08:15
fonte

Leggi altre domande sui tag