2010-08-23 14 views
5

Sto imparando Java leggendo "Head First Java" e facendo tutti i puzzle e gli excercies. Nel libro raccomandano di scrivere classi TestDrive per testare il codice e le clases che ho scritto, questa è una cosa molto semplice da fare, ma facendo ciò penso che non posso testare completamente il mio codice perché sto scrivendo il codice di test sapendo cosa voglio ottenere, non so se ha senso, ma mi stavo chiedendo se c'è un modo per testare il mio codice in un modo semplice che mi dica cosa non funziona correttamente. Grazie.Come testare facilmente il codice?

+2

Lol, la garanzia della qualità è un problema indecidibile. Il test è un'arte. Il meglio che puoi fare se non sei bravo a immaginare buoni casi di test è probabilmente che qualcun altro lo testasse per te. Tuttavia, leggere alcune nozioni di base sui test unitari dovrebbe iniziare. –

+0

"Sto scrivendo il codice di test sapendo cosa voglio ottenere," Ecco come funziona il test. Sai cosa dovrebbe succedere. Il test è lì per dimostrare che in realtà ** succede **. Che problema stai avendo? Il tuo codice è così buono da superare i test la prima volta? Cosa c'è che non va? –

+0

@ S.Lott: Certo, a volte i test passano la prima volta perché il test è negativo e non perché il codice è buono. –

risposta

2

Cosa intendiamo per codice? Quando testare l'unità, che è ciò di cui penso stiamo parlando, stiamo testando specifici metodi e classi.

penso non riesco a testare a fondo il mio codice perché sto scrivendo il codice di prova sapendo quello che voglio ottenere

In altre parole si sta indagando se un certo codice compie un contratto . Considera questo esempio:

int getInvestvalue(int depositCents, double annualInterestRate, int years) { 

} 

Quali test puoi escogitare? Se crei una buona serie di test puoi avere una certa confidenza in questa routine. Quindi potremmo provare questi tipi di input:

deposit 100, rate 5.0, years 1 : expected answer 105 
    deposit 100, rate 0, years 1 : expected answer 100 
    deposit 100, rate 10, years 0 : expected anwer 100 

Cos'altro? Che ne dici di un tasso negativo?

Più interessante, che dire di un tasso di interesse molto alto come 1.000.000.50 e 100.000 anni, cosa succede al risultato, si inserirà in un numero intero - la cosa su come escogitare questo test è che sfida l'interfaccia - perché è lì nessuna eccezione documentata?

La domanda viene quindi: come individuare questi casi di test. Non penso che ci sia un singolo approccio che porta a costruire un set completo, ma ecco un paio di cose da considerare:

  1. Bordi: zero, uno, due, molti. Nel mio esempio non facciamo solo un tasso del 5%. Consideriamo soprattutto i casi speciali. Zero è speciale, uno è speciale, negativo è speciale, un grande numero è speciale ...
  2. Casi angolari: combinazioni di spigoli. Nel mio esempio è una grande percentuale e un grande numero di anni. La scelta di questi è qualcosa di un'arte, ed è aiutata dalla nostra conoscenza della implmentazione: qui sappiamo che c'è un effetto "moltiplicatore" tra tassi e anni.
  3. Casella bianca: utilizzo del know-how dell'implementazione per guidare la copertura del codice. Regolare gli ingressi per forzare il codice verso il basso su percorsi particolari. Ad esempio, se sai che il codice ha un percorso condizionale "se negativo tasso", allora questo è un indizio per includere un test tasso negativo.
+0

Questo è esattamente il tipo di test che voglio testare il mio codice/classi contro, beh, non esattamente, ma vicino. Come posso dare un'occhiata a tutti i diversi scenari? –

+0

aggiunto qualche idea – djna

1

Uno dei principi di "Test Driven Development" sta scrivendo un test prima (cioè prima che tu abbia scritto il codice). Ovviamente questo test inizialmente fallirà (il tuo programma potrebbe anche non essere compilato). Se il test non ha esito positivo, allora sai di avere un problema con il test stesso. Una volta che il test fallisce, l'obiettivo diventa quindi continuare a scrivere codice fino a quando il test non viene superato.

Inoltre, alcuni dei framework di testing delle unità più popolari come jUnit consentono di verificare se qualcosa funziona o esplicitamente non funziona (ad esempio, si può affermare che un certo tipo di eccezione viene generato). Questo diventa utile per controllare input errati, casi angolari, ecc.

Per rubare una linea a Stephen Covey, inizia solo con la fine in mente e scrivi tutti i test che riesci a pensare. Questo può sembrare banale per un codice molto semplice, ma l'idea diventa utile quando passi a problemi più complessi.

+0

Questo metodo sembra molto utile, grazie. Lo faccio decisamente. –

4

è giusto - sai cosa aspettarti e scrivi casi di test per coprire tale conoscenza. Per molti aspetti è normale: vuoi testare le cose che hai scritto solo così sai che funziona come ti aspetti.

ora, è necessario andare al passo successivo: trovare un sistema in cui funzionerà (cioè integrarlo con altri bit n pezzi del puzzle completo) e vedere se funziona ancora in base alle proprie ipotesi e conoscenze .

Quindi è necessario darlo a qualcun altro per testare per voi - troveranno rapidamente i pezzi che non hai mai pensato.

Poi si dà a un utente reale, e non solo trovare le cose voi e il vostro tester mai pensato, ma anche trovare le cose che non sono mai stati pensati dalla analisi dei requisiti.

Questo è il modo in cui il software funziona, e forse il motivo non è mai finito.

PS. Una cosa sul tuo codice di test che conta più di ogni altra cosa: una volta che l'hai fatto una volta e hai trovato che funziona come previsto, puoi aggiungere altro materiale alla tua app e quindi eseguire nuovamente il codice di prova per assicurarti che funzioni ancora come previsto . Questo è chiamato test di regressione e penso che sia l'unica ragione per scrivere i propri test unitari.

e: Dilbert's take on testing.

+0

Grazie, ci provo. Qualche altro consiglio dato che sono ancora un principiante? –

+1

Suggerisco un altro motivo per scrivere test unitari: l'atto di scriverli ti porta a scrivere codice migliore. Si tende a trovarsi a pensare a casi limite e casi angolari. – djna

0

Fatto correttamente, i test sono le vostre specifiche. Definisce ciò che il tuo codice dovrebbe fare. Ogni test definisce un nuovo aspetto della tua applicazione. Pertanto, non si scriveranno mai test alla ricerca di elementi che non funzionano correttamente, dal momento che i test specificano come le cose devono funzionare correttamente.

Una volta che hai finito di testare e codificare il componente, uno dei modi migliori e più semplici per aumentare la certezza che le cose funzionino correttamente consiste nell'utilizzare una tecnica chiamata Exploratory Testing, che può essere considerata un'esplorazione non codificata della parte dell'applicazione che hai scritto alla ricerca di bug in base alla tua intuizione ed esperienza (e devianza!).

Pair Programming è un altro ottimo modo per impedire e svuotare i bug dal codice. Due menti sono migliori di una e spesso qualcun altro penserà a qualcosa che tu non hai (e viceversa).

+0

Grazie, la programmazione delle coppie è fuori discussione mentre sto imparando da solo, i test esplorativi sembrano interessanti. Lo proverò nei miei progetti futuri. –

1

Prima di tutto, è necessario assicurarsi che il proprio codice sia stato scritto per il test dell'unità. Le dipendenze sulle classi esterne dovrebbero essere rese esplicite (richieste dal costruttore se possibile) in modo che non sia possibile scrivere un test unitario senza identificare ogni possibile modo di rompere le cose.Se trovi che ci sono troppe dipendenze, o che non è ovvio come verrà usata ciascuna dipendenza, devi lavorare sul Principio di Responsabilità Unica, che renderà le tue classi più piccole, più semplici e più modulari.

Una volta che il codice è scritto in modo da poter prevedere le situazioni che potrebbero verificarsi in base alle vostre dipendenze e parametri di input, si dovrebbe scrivere test che cercano il comportamento corretto da una varietà di quelle situazioni prevedibili. Uno dei maggiori vantaggi che ho riscontrato ai test unitari è che in realtà mi ha costretto a pensare, "E se ...", ea capire quale sarebbe il comportamento corretto in ciascun caso. Ad esempio, devo decidere se ha più senso lanciare un'eccezione o restituire un valore nullo in caso di determinati errori.

Una volta che pensi di avere tutte le basi coperte, potresti anche voler lanciare il tuo codice con uno strumento come QuickCheck per aiutarti a identificare le possibilità che potresti aver perso.

Problemi correlati