2010-05-20 7 views
6

Guardando la nostra copertura del codice dei nostri test unitari siamo piuttosto alti. Ma l'ultima percentuale è difficile perché molti di loro catturano cose come le eccezioni del database - che in circostanze normali non succedono. Ad esempio il codice impedisce che i campi siano troppo lunghi ecc., Quindi le uniche eccezioni possibili del database sono se il DB è rotto/inattivo o se lo schema è cambiato sotto i nostri piedi.Qual è il modo corretto per analizzare le aree di test intorno alle eccezioni

Quindi è l'unico modo per deridere gli oggetti in modo che l'eccezione possa essere generata? Sembra un po 'inutile. Forse è meglio accettare semplicemente di non ottenere una copertura del 100% del codice?

Grazie, Dan

+3

Gli ultimi punti percentuali di solito non valgono la pena (tranne ovviamente se la funzione che implementano è un requisito fondamentale, allora si è iniziato con i punti percentuali sbagliati ;-)). –

+1

Il codice di gestione delle eccezioni è solitamente pieno di bug, vale la pena di provarlo. – Peli

+0

Devo essere d'accordo con Peli, stiamo facendo il 100% e abbiamo trovato un sacco di bug possibili. – roundcrisis

risposta

1

Di solito quando si eseguono eccezioni di basso livello, come IOException o SQLException in Java, le includo in un'eccezione che estende RuntimeException. Ritengo che testare questo comportamento sia molto importante perché altrimenti c'è la possibilità molto brutta di ingerire accidentalmente l'eccezione.

Quindi consiglio di testarli, se effettivamente si fa qualcosa quando viene lanciata un'eccezione di basso livello.

Modifica: Aggiunto esempio.

public void store(User user) { 
    try { 
     userDao.store(user); 
    } catch (IOException e) { 
     // Logging, perhaps some logic. 
     throw new ServiceException(e); 
    } 
} 

@Test(expected = ServiceException.class) 
public void Store_Fail() { 
    UserDao userDaoMock = createMock(UserDao.class); 
    User user = // Create test user. 
    userDaoMock.store(user); 
    replay(userDaoMock); 
    userService.store(user); 
    verify(userDaoMock); 
} 

Non c'è molto di testare qui, ma se la logica richiede per un ServiceException per essere buttato perché non provarlo?

+0

Ok. Quindi come fai a testare il tuo? Prendi in giro l'errore o trovi un modo per innescarlo in qualche modo? – Codek

+0

@Codek vado con il beffardo. In quel caso specifico, inietto un oggetto fittizio nella classe testata e lo costringo a lanciare un'eccezione nella chiamata testata. Non provo a causare alcun tipo di errore di file o database perché richiede molto tempo e talvolta non è nemmeno chiaro il motivo per cui il metodo genererebbe l'eccezione verificata. – ponzao

1

Una pratica comune quando un obiettivo di copertura del 100% è specificato è quello di coprire quanto più codice possibile, prova e coprire i restanti piccola percentuale di revisione del codice.

+0

Non dovresti coprire anche il resto del codice con la revisione del codice? – Mark

+0

Certo che sì. Ma questa revisione specifica mira a giustificare il motivo per cui quella parte del codice non è stata testata e perché non dovrebbe danneggiare non testarla. – mouviciel

+0

Ok bene. Tuttavia è possibile contrassegnare il codice come "non coperto"? Al momento non abbiamo un modo chiaro per identificare dal rapporto di copertura quale codice è stato "revisionato dal codice" e ritenuto ok e quale no? Quindi mi piacerebbe arrivare a una sorta di pseudo copertura al 100% in cui tutto il codice è stato testato o rivisto. (Lo strumento che usiamo è EclEmma) – Codek

0
Quindi è l'unico modo per deridere gli oggetti in modo che l'eccezione possa essere generata?

Credo che sarà il modo più semplice, ma si potrebbe anche fare uno stub (ovvero un oggetto che estende l'oggetto reale e costringe a comportarsi come un'eccezione ogni volta). O potresti usare AOP, ma penso che usare una libreria come easymock o jmock sarà la via più facile da percorrere.

Sembra un po 'inutile. Forse è meglio accettare semplicemente di non ottenere una copertura del 100% del codice?

Ogni volta che parlo di questo argomento mi piace spostare la mentalità delle persone dal preoccuparsi di una certa percentuale di copertura, e invece di usare la percentuale come strumento per renderti uno sviluppatore migliore. In altre parole, avere una copertura del 100% o una copertura del 50% non significa necessariamente che il tuo codice sia ben scritto o addirittura funzionante, ma utilizzare la copertura del codice come indicatore chiave quando stai sviluppando il codice, se ti stai rallentando durante la scrittura di test, ecc ... una buona idea.

La mia opinione personale sulla tua domanda è che se la tua applicazione è logica, allora vale la pena di provarla. Quindi se stai prendendo ed eccezione e risintonizzi il metodo falso, dovresti fare un test per questo. Se si sta rilevando l'eccezione e lo si avvolge in un'altra eccezione, è necessario verificarlo. Se stai rilevando l'eccezione e non fai nulla, allora questo dovrebbe essere un odore di codice che deve essere corretto perché ciò può portare a tutti i tipi di effetti collaterali ingestibili.

Per quanto riguarda il 100% non lo fa, direi di sì non ne vale la pena. Dovresti trovare un buon livello di comfort per te (forse l'80%, forse il 90%) e seguirlo. Ma non lo baserei sui tipi di test (come la logica delle eccezioni di test), dovrebbe basarsi solo sulla copertura totale e visto come un indicatore che non stai scrivendo i tuoi test quando esegui il commit del codice.

Problemi correlati