Come posso scrivere un caso di test unitario per l'utilità di conversione del formato di file?

5

Ho creato un modulo di utilità che converte un formato di file in un altro. Il file i.e. test.abc verrà convertito in i.e. test.pqr e il formato interno dei file è completamente diverso. Questo modulo coinvolge quasi 5 diversi formati di file.

Internamente , usa uno strumento nativo e non ho alcun controllo su di esso. Converte il file e la mia classe di utilità invia semplicemente i comandi a questo strumento e manipola i file.

public class Utility {

     public File convertIt(File file, Format to) {
        // Check extension
        // Execute command of native tool accordingly
        // Return resulting file
     }
}

Non sono in grado di concludere come dovrei scrivere casi di test unitari per questa utility. Perché ogni formato è diverso e in produzione ogni file verrà inserito dall'utente. Inoltre, ci sono molti attributi alcuni sono obbligatori e alcuni sono opzionali. e potrebbe essere possibile che un formato di file possa usarlo o meno.

Attualmente quello che sto pensando è che, nelle risorse del test case, posso fornire tutti i file di input e i file risultanti che ho già. Quindi posso semplicemente confrontare l'output di ogni chiamata con il file di output esistente. Ma penso che questo non coprirà tutti gli scenari e potrei aver bisogno di più file per i test.

- resources
       |- input
            |- input1.abc
            |- input2.pqr
            |- input3.xyz
       |- output
            |- output1.xyz
            |- output2.abc
            |- output3.pqr

Le mie domande,

  • Questo approccio è corretto?
  • C'è qualche altro approccio migliore ?
  • Qual è la migliore pratica per testare tali metodi che manipolano i file?
posta CoderCroc 22.08.2016 - 12:12
fonte

3 risposte

3

I want to test my code which is basically a wrapper of native tool.

Perfetto. Se si desidera testare lo strumento nativo, non lo si farebbe tramite il codice in ogni caso. Quindi non devi creare file di input o file di output. Tutto quello che devi fare è assicurarti che lo strumento nativo sia chiamato con gli argomenti corretti.

Un modo è creare una classe Executor in grado di eseguire un comando e passarlo nel convertitore.

class Converter {
    private Executor executor;

    public Converter(Executor executor) {
        this.executor = executor;
    }

    convertIt() {
        command = ...
        executor.execute(command);
    }
}

}

Quindi usa Mockito per creare un finto esecutore per i test. Utilizza junit per semplificare la creazione e l'esecuzione dei metodi di prova.

import org.junit.Test;
import static org.mockito.Mockito.*;

class ConverterTest {
    private Executor executor;

    @Before
    public void setup() {
         executor = mock(Executor.class);
    }

    @Test
    public void TestAtoB() {
        String expectedCommand = ...;
        Converter converter = new Converter(executor);
        converter.convert(...);
        verify(executor).execute(expectedCommand);
    }
}
    
risposta data 22.08.2016 - 22:04
fonte
2

Prima di tutto, un punto pedante. Poiché questi test chiamano un'utility esterna che legge e scrive file, questi test sono davvero test di integrazione; non test unitari.

Dai suoni, per un particolare tipo di file di input e il tipo di output scelto, si fornisce un set di parametri all'utilità e tali parametri cambiano per ciascuna combinazione di input / output. Supponendo che questo sia corretto, quindi per testare correttamente il metodo, il tuo approccio è buono (per ora). Dovresti creare un file di output appropriato per ciascuna combinazione, che consenta di testare tutti i percorsi attraverso il metodo (e la chiamata dell'utilità risultante).

Il punto in cui si tratta di un approccio tutt'altro che ideale riguarda la probabilità che l'utilità cambi in futuro. Se il file di output cambia con una nuova versione dello strumento, i test falliranno semplicemente perché lo strumento è cambiato; non perché il tuo codice è difettoso. Quindi hai un test fragile. Inoltre una nuova versione deve offrire più attributi che convertano meglio i file per i tuoi clienti, ma i test non necessariamente selezioneranno queste nuove funzionalità.

Quindi è probabile che sia necessario un flusso di lavoro che consideri i test come sospetti, che rigeneri i file di output e controlli le modifiche degli attributi ogni volta che viene rilasciata una nuova versione dell'utilità. Se lo metti a posto, allora questo approccio di prova dovrebbe andare bene per te.

    
risposta data 22.08.2016 - 14:10
fonte
1

Nonostante il suo commento, penso che l'OP voglia testare implicitamente il convertitore sottostante.

Perché? Un test unitario per un wrapper è quasi inutile (tranne che è molto complesso, ma dovrebbe essere suddiviso in parti più piccole e meno complesse). È possibile testare solo se si effettua correttamente la chiamata alla lib sottostante e gli argomenti vengono passati correttamente. Ma lo riconoscerai nei primi test manuali.

La cosa veramente interessante è se la lib si comporta come previsto, specialmente per i casi d'angolo (ad esempio .abc non definisce un parametro obbligatorio per .xyz). E se la lib ha ancora lo stesso comportamento, quando si esegue l'aggiornamento a una versione più recente.

Alla fine il tuo approccio è buono, solo due note:

  • prova a testare solo alcuni casi standard (test fumo), ma molti casi speciali interessanti
  • Userei un'altra struttura per i file di risorse (penso sia più utile ma è una questione di gusti, però): risorse / abc su xyz / parametri mancanti / input.abc, expected.xyz
risposta data 23.08.2016 - 20:46
fonte

Leggi altre domande sui tag