IEA - Una strategia di test basata su file per la trasformazione dei documenti

di Douglas Campbell, ingegnere capo

I/E/A - Ingresso/aspettato/Attuale

Se è possibile fornire implementazioni per l'insieme delle funzioni di seguito riportate,

// defines how to go from file to an instance of IN
abstract IN loadInput(File input);

// defines how to go from file to OUT instances
// throw FNF whenever there’s no expected file.
abstract OUT loadOutput(File expected) throws FileNotFoundException;

// invoked upon missing expected file or if actual != expected
abstract void storeResult(OUT result, File resultFile);

Si può fare molto per eliminare la fatica delle trasformazioni dei documenti di prova e mantenere una serie di test robusti.

In breve, diventa un banale test di scrittura come file piuttosto che come funzione.

Preferisco di gran lunga questo approccio al test della trasformazione dei documenti piuttosto che fare casino con il codice di prova. Prima di tutto, un po' di background.

Background

Gran parte del codice che ho scritto nel corso degli anni ha come fulcro il cambiamento dei documenti di un formato in un altro. Per documenti, sto parlando di qualsiasi varietà di json, xml, avro, tab delimited, yaml, qualsiasi cosa - tutto e tutto a tutto e tutto e ritorno.

Quando gli viene chiesto di codificare cose come questa, molti occhi di Dev si rivolgono semplicemente all'orrore di scrivere qualcosa di così banale come la mappatura di un campo su un altro campo, la sua classificazione in alto, la fusione con un altro valore letto da una fonte di dati esterna, e poi l'output in un'altra rappresentazione.

Questa nuova rappresentazione può avere poca somiglianza con il doc iniziale. Questa è la natura della bestia.

In breve, i requisiti che guidano le trasformazioni dei dati sono completamente arbitrari!

Penso che questo sia il motivo per cui alcuni sviluppatori detestano questa roba. Prendono delle scorciatoie e buttano cose nel codice di prova che assomigliano a questo...

//CHECKSTYLE:OFF
private static final String CLICK = "a horrendously ugly line of input from an access log";
//CHECKSTYLE:ON

E quando è il momento di testare una "impressione", indovinate cosa succede. Ugh - test di input in linea come variabili di stringa. Il senso di ragno si attiva immediatamente dopo la soppressione del checkstyle!

Una cosa che ho imparato è che ovunque ci siano paura ed elusione, è proprio lì che serve un po' di pigrizia eccessivamente energica. Fate un passo indietro. Rendetelo semplice e sbarazzatevi di risme e risme di logica e/o codice duplicato. Scrivete una funzione per eseguire un'intera cartella piena di test

// test folder of tests and fail entire run if any fail.
public void testFolder(File testfolder, Function<IN, OUT> converter) {

    for (File test: testfolder.listFiles(testFileFilter)) {
        if (!testSingle(test, converter)) {
           fail("expected != actual - actual " +
           "results saved in .actual file");
        };
    }
}

E allora, cosa ne è di questa funzione di testSingle? Molto semplice con le tre funzioni definite all'inizio del blog.

// test a single test
private boolean testSingle(File test, Function converter) {
    IN input = loadInput(test);
    OUT actual = converter.apply(input);
    OUT expected = null;

    // only create if no expected file or result is different.
    File actualFile = new File(test.getParent(),
                               test.getName() + ".actual");

    try {
        expected = loadOutput(new File(test.getParent(),
                                       test.getName()
                                       + ".expected"));

    } catch (FileNotFoundException ex) {
        // we haven't got expected file - no biggie
        // we can turn this into an expected file once
        // satisfied with it.
        storeResult(actual, actualFile);
    }
    return false;

    // we've got something to compare
    if (!actual.equals(expected)) {
        // fail and save the actual file for command
        // line diffing
        storeResult(actual, actualFile);
        return false;
    }

    return true;
}

Vantaggi vari di questo approccio

Per i documenti basati su testo e o ascii, l'utilità diff è immediatamente disponibile per confrontare i fallimenti dei test

Non è necessario scrivere codice di prova per generare l'output atteso. Basta aggiungere il vostro record di prova nella cartella dei test, eseguire i test e l'output effettivo viene generato in un nuovo file con estensione .actual

Avete un modo immediato per far passare il vostro codice sui record che vi hanno causato problemi nella produzione. Anche in questo caso, lasciate cadere il record problematico nella vostra cartella di prova ed eseguite il test.

Se il vostro team decide di costruire un convertitore nuovo di zecca o di utilizzare un'altra libreria json, tutti i vostri test sono espressi come file indipendenti dalla lingua. Potete portarli avanti.

Cose da fare in anticipo

In primo luogo, fate attenzione a rendere la vostra logica di trasformazione apolide. In sostanza, le trasformazioni dei documenti che comportano chiamate fuori processo devono essere rielaborate per separare il recupero dei dati grezzi da ciò che viene fatto ad essi.

In secondo luogo, iniziare a farlo all'inizio del ciclo di vita del modulo di codice o dell'applicazione. Gli appetiti sono di solito piuttosto scarsi per tornare indietro e rielaborare i vecchi e schifosi test.

Prossimo passo

Un passo successivo per noi è quello di confezionare questo come un pacchetto di prova di origine aperta. Chissà, potrebbe anche accadere prima se otteniamo un po' di interesse ?

Informazioni su ShareThis

ShareThis ha sbloccato il potere del comportamento digitale globale sintetizzando i dati di condivisione sociale, interesse e intenzione dal 2007. Alimentato dal comportamento dei consumatori su oltre tre milioni di domini globali, ShareThis osserva le azioni in tempo reale di persone reali su destinazioni digitali reali.

Iscriviti alla nostra newsletter

Ricevete le ultime notizie, i suggerimenti e gli aggiornamenti

Iscriviti

Contenuto correlato