Come si scrivono i test per il codice che dipende da implementazioni esterne concrete che non possono essere derise?


17

Antefatto: sto pensando di provare a introdurre il concetto di unit test ai miei colleghi creando alcuni per un modulo su cui sto lavorando; i requisiti sono cambiati di recente e richiedono alcune ulteriori astrazioni / interazioni, quindi sembra un buon modo per sviluppare una serie di test che "dimostreranno" che funziona senza dover cercare manualmente l'applicazione.

Il problema, tuttavia, è che il modulo si basa su fattori esterni non modificabili, vale a dire PDF e XSL. Fondamentalmente ho letto XML dal database e vi ho applicato una trasformazione XSL, quindi l'ho convertito in PDF usando una libreria chiamata ABCPDF. Questo PDF viene quindi unito a un altro PDF basato su un modello statico. So che posso testare l'XML e assicurarmi che i valori siano corretti, ma molti dei potenziali bug e problemi sono correlati alla visualizzazione effettiva del documento finito, ad esempio minuzie come la lunghezza delle stringhe di testo, dove determinate aree HTML sono situato in relazione al documento, ecc. È anche possibile testare queste cose (mi rendo conto che si tratta probabilmente di test di integrazione o .. il terzo tipo di test di cui dimentico il nome [non test di accettazione, l'altro tipo] e non unità test) dal momento che non posso, per quanto ne so, prendere in giro un PDF facilmente prima di crearlo, quindi rileggerlo o creare una stringa HTML (ovvero XML trasformato) e analizzarlo manualmente per verificare la presenza di determinate celle della tabella in relazione con altre celle della tabella.

In una situazione come questa, dovrei concentrarmi solo sui test unitari per accertarmi che le informazioni siano corrette e che sia possibile creare il PDF o unirli o qualsiasi altra cosa e ricorrere al test manuale per i problemi di visualizzazione effettivi?


6
"fattori esterni smontabili" è un suggerimento che non stai facendo test unitari in primo luogo. Ciò significa test di integrazione . Che vuoi fare? Test unitari del tuo codice o test di integrazione di questa cosa composita ? Per favore, scegli l'uno o l'altro, perché è difficile parlarne entrambi contemporaneamente.
S.Lott

2
Non sto acquistando "unmockable". Accetterò "che non so deridere", il che significa semplicemente che la tua vera domanda è "come la derido?".
Rein Henrichs,

Probabilmente :) Ho familiarità con il deridere l'XML utilizzato, ma non con il modo di deridere un documento PDF o HTML reale in cui la formattazione è importante.
Wayne Molina,

1
Penso che intendi test "funzionali" (applicazione end-to-end) o "sistema" (applicazioni multiple end-to-end)
Gary Rowe,

@Gary - Sì, funzionale era la parola. Li ricordo ora dall'apprendimento di Rails: modelli di unit test, controller di test funzionali, test di integrazione tutto.
Wayne Molina,

Risposte:


13

Prova la funzione non l'unità

Utilizzando input xml noti, genera un PDF e verifica manualmente (e meticolosamente) che sia corretto. Quindi salvarlo come riferimento.

I test futuri che utilizzano gli stessi input XML possono fare un confronto di file binario con il riferimento.

Se un confronto a livello di file non è soddisfacente, visualizzare il PDF alla fine del test e acquisire schermate, quindi confrontare automaticamente il test con le schermate di riferimento.


+1 perché sei interessato solo al risultato finale a questo livello. Se cambi l'implementazione di come arrivi a ottenere il PDF non dovresti cambiare il test funzionale.
Gary Rowe,

2
+1 per un buon consiglio, questo è ciò che facciamo nel nostro attuale progetto. Abbiamo creato un set di strumenti personalizzato per eseguire il confronto PDF, che ci consente di omettere la modifica delle parti nei documenti come i timestamp. Avvertenza: il passaggio a un diverso (versione del) renderer PDF può causare lievi modifiche al layout, causando un confronto binario diretto per segnalare cumuli di falsi positivi.
Péter Török,

5

Normalmente in un caso come questo si astratto tutto ciò che non è possibile verificare dietro un'implementazione che è possibile utilizzare con un'interfaccia. Farò semplicemente qualcosa di stupido come PDF Builder perché sembra ragionevole.

public class PdfBuilder : IPdfBuilder
{
  public byte[] BuildPdf(...)
  {
    // actual untestable code here
  }
}

public interface IPdfBuilder
{
  byte[] BuildPdf(...);
}

Puoi quindi deridere IPdfBuilder nei tuoi test per fare quello che vuoi. Ciò significa spesso che è necessario iniziare a utilizzare un contenitore IoC ( /programming/871405/why-do-i-need-an-ioc-container-as-opposed-to-straightforward-di-code e /programming/21288/which-net-dependency-injection-frameworks-are-worth-looking-into come punto di partenza) se non ne stai usando uno adesso.

E i test che non sono unit test sono spesso chiamati test di integrazione. I test di integrazione complicati spesso non ne valgono la pena, quindi è sufficiente sottrarre tale parte e ridurre la quantità di logica aziendale in tale astrazione in modo da poterla testare in un unit test.

Fammi sapere se questo non è del tutto chiaro.


+1 per nascondere il codice non verificabile. Quindi è possibile eseguire test manuali fino a quando non si è capito cosa deve attraversare quell'interfaccia per ottenere il risultato giusto e test unitari per quello che viene generato correttamente per ottenere i test unitari di regressione.
Ethel Evans,

1

Qualche tempo fa ho costruito qualcosa di molto simile e ho usato solo test visivi di base. I test non devono essere automatizzati, quindi non c'è nulla di sbagliato nel cercare un risultato atteso (ovviamente, in una varietà di situazioni predeterminate). Spesso, un'immagine vale mille test per quanto riguarda la grafica . Uso ampiamente i test di unità automatizzati, ma penso che alcune persone possano essere un po 'trascurate quando entrano nei test della GUI o qualsiasi altro IMHO visivo. Con un certo prodotto, riconosco che questo approccio "abbastanza buono" non sarà sufficiente, quindi YMMV.

Sarei un po 'preoccupato, tuttavia, per le esternalità inconfondibili. Questo può essere un segno di accoppiamento stretto, che è bene evitare come regola generale, ma non speculerò troppo sul tuo codice al riguardo senza ulteriori dettagli.


È strettamente accoppiato, ma questa è un'area che non posso risolvere dal momento che non vi è alcun buy-in per renderlo vagamente accoppiato e nessuna risorsa è dedicata al refactoring (ma si tratta di una serie completamente diversa di problemi).
Wayne Molina,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.