Domanda

Qualcuno sa dove trovare linee guida e raccomandazioni per i test unitari? Mi piacerebbe avere qualcosa che affronti i seguenti tipi di argomenti (ad esempio):

  • I test devono essere nello stesso progetto della logica dell'applicazione?
  • Dovrei avere delle classi di test per rispecchiare le mie classi logiche o dovrei avere solo tutte le classi di test che sento di dover avere?
  • Come devo nominare le mie classi di prova, metodi e progetti (se vanno in progetti diversi)
  • Dovrebbero essere testati metodi privati, protetti e interni o solo quelli accessibili pubblicamente?
  • I test unitari e di integrazione devono essere separati?
  • C'è un buono motivo per non avere una copertura del test al 100%?

Cosa non sto chiedendo che dovrei essere?

Una risorsa online sarebbe la migliore.

È stato utile?

Soluzione

Consiglierei il libro di Kent Beck su TDD.

Inoltre, devi visitare il il sito di Martin Fowler . Ha anche molte buone informazioni sui test.

Siamo piuttosto grandi su TDD, quindi risponderò alle domande in quella luce.

  

I test devono essere nello stesso progetto della logica dell'applicazione?

In genere manteniamo i nostri test nella stessa soluzione, ma suddividiamo i test in DLL / progetti separati che rispecchiano le DLL / i progetti che stanno testando, ma manteniamo gli spazi dei nomi con i test in uno spazio dei nomi secondario. Esempio: Common / Common.Tests

  

Dovrei avere delle classi di test per rispecchiare le mie classi logiche o dovrei avere solo tutte le classi di test che sento di dover avere?

Sì, i test dovrebbero essere creati prima di creare qualsiasi classe e per definizione dovresti testare una singola unità in isolamento. Pertanto, è necessario disporre di una classe di test per ogni classe nella soluzione.

  

Come devo nominare le mie classi di prova, metodi e progetti (se vanno in progetti diversi)

Mi piace sottolineare che il comportamento è ciò che viene testato, quindi in genere denominerò le classi di test come SUT. Ad esempio, se avessi una classe User, la denominerei così:

public class UserBehavior

I metodi dovrebbero essere nominati per descrivere il comportamento che ti aspetti.

public void ShouldBeAbleToSetUserFirstName()

I progetti possono essere nominati come vuoi, ma di solito vuoi che sia abbastanza ovvio quale progetto sta testando. Vedi la risposta precedente sull'organizzazione del progetto.

  

Dovrebbero essere testati metodi privati, protetti e interni o solo quelli accessibili pubblicamente?

Ancora una volta vuoi che i test affermino il comportamento previsto come se fossi un consumatore di terze parti degli oggetti da testare. Se si verificano i dettagli dell'implementazione interna, i test saranno fragili. Desideri che il tuo test ti dia la libertà di eseguire il refactoring senza preoccuparti di interrompere la funzionalità esistente. Se il tuo test è a conoscenza dei dettagli di implementazione, dovrai cambiare i test se tali dettagli cambiano.

  

I test unitari e di integrazione devono essere separati?

Sì, i test unitari devono essere isolati dai test di accettazione e integrazione. La separazione delle preoccupazioni si applica anche ai test.

  

C'è una buona ragione per non avere una copertura del test al 100%?

Non riuscirò a riattaccare sulla cosa di copertura del codice al 100%. La copertura del codice al 100% tende a implicare un certo livello di qualità nei test, ma questo è un mito. Puoi fare test terribili e ottenere comunque una copertura del 100%. Farei invece affidamento su una buona mentalità Test First. Se scrivi sempre un test prima di scrivere una riga di codice, assicurerai una copertura del 100% in modo che diventi un punto controverso.

In generale, se ti concentri sulla descrizione dell'intero ambito comportamentale della classe, non avrai nulla di cui preoccuparti. Se rendi la copertura del codice una metrica, i programmatori pigri faranno semplicemente quanto basta per raggiungere quel segno e avrai comunque dei test scadenti. Invece, fai molto affidamento sulle revisioni tra pari dove anche i test vengono esaminati.

Altri suggerimenti

È una buona domanda. Siamo cresciuti organicamente e sospettiamo che il modo migliore sia proprio quello. C'è un po '" dipende ... " lì dentro.

Abbiamo messo test nello stesso progetto, in uno spazio dei nomi secondari chiamato " UnitTes "

Le nostre classi di test rispecchiano la classe logica, al fine di semplificare tenere traccia di dove sono i test in relazione a ciò che stanno testando

Le classi sono chiamate come la classe logica che stanno testando, i metodi sono nominati per lo scenario che stanno testando.

Scriviamo solo test per i metodi pubblici e interni (i test sono nello stesso progetto) e puntiamo al 95% di copertura della classe.

Preferisco non distinguere tra " unit " e "intergation". Si passerà troppo tempo a cercare di capire quale ... quale borsa! Un test è un test.

Il 100% è troppo difficile da raggiungere in ogni momento. Puntiamo al 95%. Ci sono anche rendimenti decrescenti su quanto tempo ci vorrà per ottenere quel 5% finale e cosa effettivamente prenderà.

Siamo noi e ciò che si adatta all'ambiente e al ritmo. Il tuo chilometraggio può variare. Pensa al tuo ambiente e alle personalità coinvolte.

Non vedo l'ora di vedere cosa hanno da dire gli altri su questo!

La risposta di Josh è giusta: solo un punto di chiarimento:

Il motivo per cui separo i test unitari dai test di integrazione e accettazione è la velocità. Io uso TDD. Ho bisogno di un feedback immediato sulla linea di codice che ho appena creato / modificato. Non riesco a ottenerlo se sto eseguendo suite complete di test di integrazione e / o accettazione - test che colpiscono dischi reali, reti reali e sistemi esterni davvero lenti e imprevedibili.

Non attraversare le travi. Se lo fai, accadranno cose brutte.

Ti consiglio vivamente di leggere Test Driven Development: By Example e Sviluppo test-driven: una guida pratica Sono troppe domande per un singolo argomento

Per quanto riguarda la tua ultima domanda, nella mia esperienza, il "buono" la ragione per non insistere sulla copertura del test al 100% è che ci vuole uno sforzo sproporzionato per ottenere gli ultimi punti percentuali, in particolare in basi di codice più grandi. In quanto tale, si tratta di decidere se valga la pena o meno il tuo tempo una volta raggiunto quel punto di rendimenti decrescenti.

In ordine:

  • No, di solito è meglio includerli in un progetto separato; a meno che tu non voglia eseguire la diagnostica in fase di esecuzione.
  • L'ideale è una copertura del codice al 100%, che significa ogni riga di codice in ogni routine in ogni classe.
  • Vado con ClassnameTest, ClassnameTest.MethodNameTestnumber
  • Tutto.
  • Direi di sì, poiché i test di integrazione non devono essere eseguiti se i test unitari falliscono.
  • Le proprietà semplici che hanno appena impostato e ottenuto un campo non devono essere testate.

I test devono essere nello stesso progetto della logica dell'applicazione?

Dipende. Ci sono comunque dei compromessi.

Mantenerlo in un progetto richiede una larghezza di banda aggiuntiva per distribuire il progetto, tempi di costruzione aggiuntivi e aumenta l'impronta dell'installazione e semplifica l'errore di avere una logica di produzione che dipende dal codice di prova.

D'altra parte, mantenere progetti separati può rendere più difficile la scrittura di test che coinvolgono metodi / classi privati ??(a seconda del linguaggio di programmazione) e causa piccoli problemi amministrativi, come la creazione di un nuovo ambiente di sviluppo (ad esempio quando un nuovo lo sviluppatore si unisce al progetto) più difficile.

L'importanza di questi diversi costi varia in base al progetto, quindi non esiste una risposta universale.

Devo avere lezioni di prova per rispecchiare le mie classi logiche o dovrei avere solo tutte le lezioni di prova che sento di dover avere?

No.

Dovresti avere classi di test che consentano un codice di prova ben ponderato (ovvero duplicazione minima, intento chiaro, ecc.)

L'ovvio vantaggio del mirroring diretto delle classi logiche nelle classi di test è che è facile trovare i test corrispondenti a un particolare pezzo di codice. Esistono altri modi per risolvere questo problema senza limitare la flessibilità del codice di test. Convenzioni di denominazione semplici per moduli e classi di test sono generalmente sufficienti.

Come devo nominare le mie classi di prova, metodi e progetti (se vanno in progetti diversi)

Dovresti nominarli in modo che:

  • ogni classe di test e metodo di test ha uno scopo chiaro e
  • in modo che qualcuno alla ricerca di un determinato test (o di test su una determinata unità) possa trovarlo facilmente.

È necessario testare metodi privati, protetti e interni o solo quelli accessibili pubblicamente?

Spesso i metodi non pubblici devono essere testati. Dipende se hai abbastanza fiducia solo testando l'interfaccia pubblica o se l'unità che vuoi davvero testare non è accessibile pubblicamente.

I test unitari e di integrazione devono essere separati?

Questo dipende dalla scelta dei framework di test. Fai quello che funziona meglio con il tuo framework di test e lo fa in modo che:

  • sia i test unitari che quelli di integrazione relativi a un pezzo di codice sono facili da trovare,
  • è facile eseguire solo i test unitari,
  • è facile eseguire solo i test di integrazione,
  • è facile eseguire tutti i test.

C'è una buona ragione per non avere una copertura del test al 100%?

Sì, c'è una buona ragione. A rigor di termini "copertura del test al 100%" significa che ogni possibile situazione nel tuo codice viene esercitata e testata. Questo è semplicemente poco pratico per quasi tutti i progetti da realizzare.

Se prendi semplicemente "copertura del test al 100%" per indicare che ogni riga di codice sorgente viene esercitata dalla suite di test ad un certo punto, allora questo è un buon obiettivo, ma a volte ci sono solo un paio di righe in punti scomodi che sono difficili da raggiungere con i test automatizzati. Se il costo della verifica manuale periodica di tale funzionalità è inferiore al costo di attraversare le contorsioni per raggiungere quelle ultime cinque righe, questa è una buona ragione per non avere una copertura del 100% delle linee.

Piuttosto che una semplice regola in base alla quale dovresti avere una copertura delle linee al 100%, incoraggia i tuoi sviluppatori a scoprire eventuali lacune nei tuoi test e a trovare modi per correggere tali lacune, indipendentemente dal numero di righe " coperto "migliora. In altre parole, se si misurano le linee coperte, si migliorerà la copertura della linea, ma ciò che si desidera effettivamente è una qualità migliorata. Quindi non dimenticare che la copertura delle linee è solo un'approssimazione molto grossolana della qualità.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top