Domanda

Framework fittizi, ad es. EasyMock, semplifica il plug-in delle dipendenze fittizie. Detto questo, usarli per garantire come i diversi metodi su particolari componenti sono chiamati (e in quale ordine) mi sembra male. Espone il comportamento alla classe test, il che rende più difficile mantenere il codice di produzione. E davvero non vedo il vantaggio; mentalmente mi sento incatenato a una palla pesante.

Preferisco piuttosto testare l'interfaccia, fornendo dati di test come input e affermando il risultato. Meglio ancora, utilizzare alcuni strumenti di test che generano automaticamente i dati di test per la verifica di una determinata proprietà. per esempio. l'aggiunta di un elemento a un elenco e la sua rimozione produce immediatamente lo stesso elenco.

Nel nostro posto di lavoro, utilizziamo Hudson che fornisce copertura per i test. Sfortunatamente è facile ossessionarsi ciecamente che tutto sia testato. Sento fortemente che non si dovrebbe testare tutto se si vuole essere produttivi anche in modalità manutenzione. Un buon esempio sarebbe i controller nei framework web. Come generalmente dovrebbero contenere pochissima logica, test con finto framework che il controller chiama tale e tale metodo in ordine particolare è insensato secondo la mia onesta opinione.

Cari SOER, quali sono le vostre opinioni al riguardo?

È stato utile?

Soluzione

Dipende da come modellare i domini del programma.

Se modellizzi i domini in termini di dati archiviati in strutture di dati e metodi che leggono i dati da una struttura di dati e memorizzano i dati derivati ??in un'altra struttura di dati (procedure o funzioni a seconda di quanto procedurale o funzionale sia il tuo progetto), allora finti gli oggetti non sono appropriati. Il cosiddetto "basato sullo stato" test è quello che vuoi. Il risultato che ti interessa è che una procedura inserisca i dati giusti nelle variabili giuste e ciò che chiama per realizzarlo è solo un dettaglio di implementazione.

Se modellizzi i domini in termini di protocolli di comunicazione che trasmettono messaggi attraverso i quali gli oggetti collaborano, i protocolli sono ciò che ti interessa e quali dati archiviano gli oggetti per coordinare il loro comportamento nei protocolli in cui svolgono ruoli è solo implementazione dettaglio. In tal caso, gli oggetti simulati sono lo strumento giusto per il lavoro e i test basati sullo stato collegano i test troppo strettamente a dettagli di implementazione non importanti.

E nella maggior parte dei programmi orientati agli oggetti esiste un mix di stili. Alcuni codici saranno scritti puramente funzionali, trasformando strutture di dati immutabili. Altro codice coordinerà il comportamento degli oggetti che cambiano il loro stato interno nascosto nel tempo.

Per quanto riguarda l'alta copertura dei test, in realtà non ti dice molto. Una copertura di test bassa indica dove si dispone di test inadeguati, ma una copertura di test elevata non mostra che il codice è stato testato adeguatamente. I test possono, ad esempio, passare attraverso percorsi di codice e quindi aumentare le statistiche di copertura, ma in realtà non fare alcuna affermazione su ciò che hanno fatto quei percorsi di codice. Inoltre, ciò che conta davvero è come le diverse parti del programma si comportano in combinazione, quale copertura del test unitario non ti dirà. Se si desidera verificare che i test stiano effettivamente testando adeguatamente il comportamento del sistema, è possibile utilizzare uno strumento di test della mutazione. È un processo lento, quindi è qualcosa che avresti eseguito in una build notturna piuttosto che ad ogni check-in.

Altri suggerimenti

Ho letto 2 domande:

Qual è la tua opinione sul test che determinati metodi sui componenti vengono chiamati in un ordine particolare?

Ho commesso fallo in passato. Usiamo molto di più "stubing" e molto meno "beffardo" questi giorni. Proviamo a scrivere test unitari che testano solo una cosa. Quando lo facciamo, normalmente è possibile scrivere un test molto semplice che si interrompe interazioni con la maggior parte degli altri componenti. E molto raramente affermiamo l'ordinazione. Questo aiuta a rendere i test meno fragili.

I test che testano solo una cosa sono più facili da capire e mantenere.

Inoltre, se ti accorgi di dover scrivere molte aspettative per le interazioni con molti componenti, potrebbe esserci comunque un problema nel codice che stai testando. Se è difficile mantenere i test, il codice che stai testando può spesso essere sottoposto a refactoring.

Si dovrebbe essere ossessionati dalla copertura del test?

Quando scrivo i test unitari per una determinata classe sono piuttosto ossessionato dalla copertura dei test. Rende davvero facile individuare importanti parti di comportamento che non ho testato. Posso anche fare un appello al giudizio su quali parti non ho bisogno di coprire.

Statistiche generali sulla copertura dei test unitari? Non particolarmente interessato finché sono alti.

Copertura del 100% per i test unitari per un intero sistema? Per niente interessato.

Sono d'accordo - sono favorevole a un forte orientamento alla verifica dello stato piuttosto che alla verifica del comportamento (una libera interpretazione di TDD classico mentre si utilizza ancora il doppio di test).

Il libro The Art of Unit Testing offre molti buoni consigli in queste aree.

La copertura del test al 100%, il test della GUI, il test di getter / setter o altri codici non logici, ecc. sembrano improbabili per fornire un buon ROI. TDD fornirà comunque un'elevata copertura di prova. Prova cosa potrebbe rompersi.

Avevo fatto una domanda simile Quanto test di unità è un Buona cosa , che potrebbe aiutare a dare un'idea della varietà di livelli di test che le persone ritengono appropriati.

  1. Qual è la probabilità che durante la manutenzione del tuo codice un dipendente junior interrompa la parte di codice che esegue "il controller chiama tale e tale metodo in particolare ordine"?

  2. Qual è il costo per la tua organizzazione se si verifica una cosa del genere - interruzione della produzione, debug / correzione / riprovare / ripubblicare, rischio legale / finanziario, rischio di reputazione, ecc ...?

Ora, moltiplica # 1 e # 2 e controlla se la tua riluttanza a raggiungere una quantità ragionevole di copertura del test vale il rischio.

A volte non lo sarà (ecco perché nei test c'è il concetto di un punto di rendimenti decrescenti).

es. se gestisci un'app Web che non è critica per la produzione e ha 100 utenti che hanno una soluzione alternativa se l'app è guasta (e / o può eseguire il rollback facile e immediato), probabilmente passare 3 mesi a svolgere la copertura completa dei test di quell'app è probabilmente non -sensical.

Se lavori su un'app in cui un bug minore può avere conseguenze di svariati milioni di dollari o peggio (pensa al software dello space shuttle o al sistema di guida per un missile da crociera), i test approfonditi con copertura completa diventano molto più sensati .

Inoltre, non sono sicuro se sto leggendo troppo nella tua domanda, ma sembra che tu stia sottintendendo che avere test di unità abilitati alla derisione in qualche modo esclude i test funzionali di applicazione / integrazione. In tal caso, hai ragione a obiettare a tale nozione: i due approcci di verifica devono coesistere.

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