TDD e test di scrittura per l'elaborazione dei file

1

Queste domande sono molto simili: TDD per l'elaborazione in batch: Come farlo? e TDD: come testare le uscite dei file? ma mi rimangono ancora alcune domande

L'app elabora file / pdf. Li prende da un server FTP, elabora / legge il contenuto del file, li colloca in un server FTP di destinazione, a seconda del contenuto letto.

Come posso affrontare l'elaborazione dei file in modo TDD? La mia educazione formale su TDD non è stata la migliore, quindi anche suggerimenti "ovvi" mi aiuteranno.

Le mie idee:

Il "successo" della mia app dipende da se legge / elabora correttamente un file sorgente e anche se lo inserisce nella destinazione corretta. Quindi ha senso per me scrivere test per vedere se un file

  1. è "letto" correttamente
  2. finisce nel posto giusto

Potrei provare su file dummy specifici, ma questo significa che dovrei sempre spedire questi file specifici con il codice, perché i test possano passare? Il nome del file sarà diverso dopo essere stato elaborato, quindi non sono sicuro di come testarlo se finisce nel posto giusto - dovrei eyeballare i file e poi inserire i risultati attesi con hardcode nei test?

    
posta mmcrae 07.01.2015 - 02:17
fonte

2 risposte

3

Penso che questa sia una grande domanda. Test unitari, micro-test, TDD e BDD sono difficili, a volte confusi e spesso non presi sul serio. Quindi complimenti per aver provato e chiesto aiuto!

Non sono affatto un esperto, ma ho appena preso una lezione formale e sono anche parte di un piccolo team che sta guidando un'iniziativa per lanciare test unitari e TDD all'interno della nostra organizzazione.

In base alla mia esperienza e a ciò che ho imparato nella mia classe, ecco quello che penso tu abbia bisogno di sapere per iniziare:

  1. Considera che ci sono diversi tipi di test e conseguono obiettivi diversi. Ci sono molte cose per cui il test unitario è semplicemente una soluzione povera o incompleta, il che può portare a pensare che il test unitario sia una perdita di tempo. Tuttavia, lo considero complementare ai test di integrazione e ai test funzionali.
  2. Non stressarti sulla copertura. C'è tempo e spazio per pensare alla copertura del codice, ma se ti preoccupi al momento, perderai tempo per testare le funzioni di accesso e di mutare, il che non fornisce alcun valore aziendale.
  3. Non pensare a testare classi o metodi, ma pensa a testare comportamenti . Che cosa fa di questa classe? Cosa fa non fare? (Questo è parte del motivo per cui il termine BDD è usato in questi giorni)
  4. Prova comportamenti interessanti. Ciò che si qualifica come interessante dipende da te. Molti esperti sostengono che un bug è un test mancante. Pertanto, tutto ciò che ritieni possa ragionevolmente rompersi merita di essere testato. Scriveresti un test per i++ ? Probabilmente no. Scriveresti un test per incrementI() ? Può essere. Se è un'app calcolatrice, probabilmente lo farei. Se si tratta di un'app Web, non vorrei sudare qualcosa di così semplice.
  5. I test non si limitano a fare in modo che il tuo codice funzioni. Servono come una specifica eseguibile. Significato, se qualcuno ha bisogno di capire i requisiti di una classe, può guardare il test.
  6. Va bene per un test assumere che una dipendenza funzioni. Se questo ti preoccupa, forse dovresti testare anche la dipendenza. Ma tienilo separato. Ad esempio, si potrebbe sostenere che testare l'elaborazione dei dati senza un file reale è sbagliato perché non si sa se funziona l'analisi dei file. Ma se hai un test unitario che verifica che l'analisi dei file funzioni, e un test unitario che verifica l'elaborazione dei dati del file, funziona chiaramente. Certo, questo non dimostra che funzionino insieme . Ma va bene. Questo è test di integrazione.
  7. I test unitari dovrebbero essere ripetibili e isolati. Un test unitario che effettua una chiamata al servizio Web, quindi scrive in un database e quindi stampa alcuni risultati nella console è non un test unitario. È un test, certo, ma non un test unitario. Non essere così preso a testare tutto ciò che scrivi test fragili che fanno un sacco di lavoro. Quindi se un metodo fa queste cose, come lo collaudi? Questo porta al prossimo argomento ...
  8. Separare le dipendenze - Scrivere piccole unità che possono essere chiamate indipendentemente, con le dipendenze inoltrate. Se si progetta in modo che l'elaborazione sia indipendente dal file sorgente stesso, è possibile testare la logica di elaborazione senza bisogno di file. Ad esempio, invece dell'elaborazione del file che prende un oggetto java.io.File , analizzandolo e facendo tutto il lavoro, forse potrebbe richiedere un java.io.InputStream , analizzarlo e fare tutto il lavoro? O un metodo che legge il contenuto del file in una matrice o altra struttura di dati, quindi lo passa nell'elaborazione?
  9. Deridere le dipendenze - in ultima analisi, qualcuno deve parlare con il mondo esterno. Idealmente, separerai le tue dipendenze, ma a volte raggiungi punti in cui la complessità introdotta è controproducente. Ad esempio, un metodo che diversi livelli nello stack di chiamate devono comunicare con il database e separarlo non è ragionevole, quindi deriderlo con una falsa implementazione che restituisce i dati del test. Sono arrivato fino alla creazione di una classe MockDatabase prima, che mi consente di mappare i nomi delle stored procedure in serie di risultati hard-coded e in memoria.
  10. Realizza quando ti sei burlato così tanto che il test unitario è inutile. Se hai preso in giro tutto ciò che fa un metodo, allora hai lasciato testare un metodo vuoto. Se questo è il caso, forse quel metodo non è interessante da testare? Affidati che un test di integrazione, un test funzionale automatizzato o anche un test manuale rileveranno problemi e non preoccuparti di testare l'unità.

Potrei andare avanti all'infinito. Speriamo che questo aiuti.

Ricorda, questo non è facile. Se fosse facile, lo farebbero tutti.

    
risposta data 07.01.2015 - 04:11
fonte
0

È importante comprendere TDD come meno sul risultato finale: codice testato e altro sul viaggio per arrivarci. TDD è un processo di progettazione che incoraggia tutte le qualità del codice che sono sicuro che ha imparato: riusabilità, separazione delle preoccupazioni, leggibilità, manutenibilità, ecc. Oh, e naturalmente, correttezza. I tuoi test ti guidano verso la scrittura di codice isolabile e testabile, che a sua volta porta queste qualità. Se comprendi solo TDD per quanto riguarda i test, ti troverai in difficoltà.

Forse hai già scritto questo programma (o forse lo hai almeno progettato nella tua testa), e stai pensando a come avvolgere i test attorno ad esso. Se questo è vero, ricomincia perché non stai guidando il codice dai test: non stai facendo TDD.

Scrivendo prima i test, poi facendo ogni passaggio, potresti condurti verso le seguenti unità:

  • Una cosa che apre un file ed espone un flusso di byte
  • Una cosa che analizza un flusso di byte come PDF
  • Una cosa che prende la rappresentazione di un PDF ed estrae ciò che ti interessa
  • Una cosa che raggruppa in base a qualcosa estratto in precedenza
  • Una cosa che alloca un percorso file in base al gruppo
  • Una cosa che sposta un file in una posizione

(Forse non ho capito bene il tuo programma, ma ottieni il succo).

Si spera che si possa vedere che l'hai suddiviso in unità facilmente testabili, molte delle quali possono essere riutilizzate, la maggior parte delle quali sono agnostiche di file o PDF. Quelle unità che effettivamente gestiscono operazioni di file reali sono molto semplici e sono poche e distanti tra loro, quindi testarle non è difficile; tutto il resto riguarda una rappresentazione in memoria.

All'inizio non è facile, ma la regola d'oro è ricordare che se i tuoi test diventano complicati, è probabilmente un indizio che il tuo codice è diventato troppo complicato e sta cercando di fare troppo in una sola unità. È il tuo spunto per fare un passo indietro e continuare a fare domande come queste.

    
risposta data 08.01.2015 - 11:55
fonte

Leggi altre domande sui tag