2009-02-05 20 views
9

Sto iniziando con test automatici e vorrei testare uno dei miei metodi di accesso ai dati. Sto provando a testare cosa fa il codice se il database non restituisce alcun record.Sono un test unitario o test di integrazione?

È qualcosa che dovrebbe essere eseguito in un test di unità o in un test di integrazione?

Grazie

risposta

13

Se il codice di prova si collega a un database effettivo e si basa sulla presenza di determinati dati (o mancanza di dati) affinché il test passi, è un test di integrazione.

Io di solito preferisco testare qualcosa di simile prendendo in giro il componente che il "metodo di accesso ai dati" utilizzato per ottenere i dati effettivi, sia che si tratti di una connessione JDBC o di un proxy del servizio web o qualsiasi altra cosa. Con una simulazione, dici "quando viene chiamato questo metodo, restituisci questo" o "assicurati che questo metodo sia chiamato N volte", e quindi dici alla classe sottoposta a test di utilizzare il componente simulato piuttosto che il componente reale. Questo è quindi un "test unitario", perché stai testando come si comporta la classe sotto test, in un sistema chiuso in cui hai dichiarato esattamente come si comportano gli altri componenti. Hai isolato completamente la classe sottoposta a test e puoi essere sicuro che i risultati dei test non saranno volatili e dipendenti dallo stato di un altro componente.

Non so con quale linguaggio/tecnologia si sta lavorando, ma nel mondo Java, è possibile utilizzare JMock, EasyMock, ecc per questo scopo.

+3

Pensare al "test unitario" nel senso di "sistema chiuso" è molto utile per differenziarlo dal "test di integrazione". – hurikhan77

0

Molto probabilmente un test di unità ... ma c'è una linea sfocata qui. Dipende molto dalla quantità di codice che viene eseguita - se è contenuto in una libreria o in una classe, quindi nel suo test unitario, se si estende su più componenti, allora è più un test di integrazione.

0

Credo che dovrebbe essere fatto in un test unitario. Non stai testando che possa connettersi al database, o che tu possa chiamare le tue stored procedure ... stai testando il comportamento del tuo codice.

Potrei sbagliarmi, ma è quello che penso a meno che qualcuno non mi dia una ragione per pensare diversamente.

7

Fai il tuo test e lascia che altre persone passino il tempo con la tassonomia.

+4

Penso che la differenza sia importante, perché ti aiuta a decidere come scriverlo, chi dovrebbe scriverlo, dove dovrebbe vivere, quando dovrebbe essere eseguito, e come devono essere gestiti i guasti. Ma non è una scusa per impantanarsi. Votato. –

+0

Conoscere quali test di integrazione o test di unità è in grado di aiutare a trovare strutture, strumenti o procedure ottimali per quel compito specifico. Questa domanda è stata utile! –

1

Credo che sia possibile testarlo come un test unitario, senza un vero database. Invece di utilizzare un'interfaccia reale per il database, sostituirlo con un mock/stub/fake object (il PDF meglio visualizzato è here).

Se la scrittura come test di unità si rivela troppo difficile e non è possibile eseguire il refactoring del codice per testarlo, è preferibile scriverlo come test di integrazione. Funzionerà più lentamente, quindi potresti non essere in grado di eseguire tutti i test di integrazione dopo il cambio di codice (a differenza dei test di unità che puoi eseguire centinaia e migliaia al secondo), ma fintanto che vengono eseguiti regolarmente (ad esempio come parte di continua integrazione), producono un certo valore.

5

Ci sono quelli (me compreso) che hanno regole severe su ciò che costituisce un test unitario rispetto a un test di integrazione.

Un test is not a unit test se:

  • Si parla al database
  • Si comunica attraverso la rete
  • Si tocca il file system
  • non è possibile eseguire nello stesso momento come un altro dei tuoi altri test di unità
  • Devi fare cose speciali per il tuo ambiente (come modificare i file di configurazione) per eseguirlo

Quale potrebbe essere un modo per fare una distinzione tra ciò che una prova di unità farà per voi utilizzando beffardo per esempio, piuttosto che uno qualsiasi dei fornitori di risorse reali - filesystem, db ecc

un test di integrazione possibile essere visto come un test di accoppiamento molto efficace tra sistemi/livelli applicativi, quindi i fondamentali sono testati nell'unità e l'interoperabilità del sistema è al centro di un test di integrazione.

È ancora un'area grigia, anche perché è spesso possibile individuare alcune eccezioni a questi tipi di regole.

2

Penso che la domanda importante sia "Che cosa DOVREI fare?"

In questo caso, penso che dovresti essere un test unitario. Prendi il codice che parla al DB e fallo restituire un risultato affidabile (senza righe), in questo modo il tuo test controlla cosa succede quando non ci sono righe, e non cosa succede quando il DB restituisce ciò che è nel DB nel punto in cui test.

Definitivamente unità testarlo!

[TestMethod] 
public void ForgotMyPassword_SendsAnEmail_WhenValidUserIsPassed() 
{ 
    var userRepository = MockRepository.GenerateStub<IUserRepository>(); 
    var notificationSender = MockRepository.GenerateStub<INotificationSender>(); 
    userRepository.Stub(x => x.GetUserByEmailAddressAndPassword("[email protected]", "secret")).Return(new User { Id = 5, Name = "Peter Morris" }); 

    new LoginController(userRepository, notificationSender).ResendPassword("[email protected]", "secret"); 

    notificationSender.AssertWasCalled(x => x.Send(null), 
     options => options.Constraints(Text.StartsWith("Changed"))); 
} 
0

che è un test di unità, per definizione: si sta testando un singolo elemento isolato del codice su un percorso specifico

5

La mia prospettiva è che si dovrebbe classificare il test basato sulla portata:

  • Un unità di prova può essere eseguito stand-alone senza dipendenze esterne (File IO, IO rete, di database, servizi Web esterni).
  • Un test di integrazione può toccare sistemi esterni.

Se il test richiede un vero database da eseguire, chiamarlo test di integrazione e tenerlo separato dai test dell'unità. Questo è importante perché se si mischiano l'integrazione e i test unitari, si rende il codice meno gestibile.

Un insieme di test diversi significa che i nuovi sviluppatori potrebbero aver bisogno di un intero mucchio di dipendenze esterne per poter eseguire la suite di test. Immagina di voler apportare una modifica a un pezzo di codice correlato al database ma che in realtà non richiede il funzionamento del database, sarai frustrato se hai bisogno di un database solo per eseguire i test associati al progetto.

Se la dipendenza esterna è difficile da decifrare (ad esempio, in DotNet, se si utilizzano Rhino Mock e le classi esterne non dispongono di interfacce), creare una classe di wrapper sottile che tocchi il sistema esterno. Quindi prendi in giro quell'involucro nei test unitari. Non dovresti avere bisogno di un database per eseguire questo semplice test quindi non ne hai bisogno!

10

Penso che più tempo sia stato sprecato a discutere su cosa sia un'unità rispetto a quale sia un test di integrazione rispetto al valore aggiunto.

Non mi interessa.

Lasciatemelo dire in un altro modo: se lo stavo testando, vedrei due modi per farlo: rimuovere il database restituendo zero righe o connettersi effettivamente a un database che non ha dati per la selezione. Probabilmente inizierei a testare con qualsiasi cosa fosse più facile da fare e più semplice da implementare - se fosse abbastanza veloce da consentirmi di ottenere un feedback significativo. Poi considererei l'altro se ne avessi bisogno per correre più veloce o pensassi che ci sarebbe stato qualche vantaggio.

Ad esempio, probabilmente mi collegherò al DB di test effettivo al mio lavoro. Ma se il software avesse bisogno di lavorare con molti database diversi - Oracle, PostGres, MySQL, SQL server e DB, o se il DB di test al lavoro fosse inattivo per 'refreshes' molto, probabilmente scriverei 'pure/unit' test che esisteva totalmente isolato.

Nella mia vecchiaia, preferisco usare più spesso il termine "rivolto allo sviluppatore" o "rivolto al cliente" e fare il tipo di test più sensato. Trovo che usare termini come "unità" in modo estensivo, e poi ottenere una definizione - weenie a riguardo porta le persone a fare cose come prendere in giro il filesystem o deridere getter e setter - attività che trovo non utile.

Credo fermamente; Ho presentato prima di google su di esso.

http://www.google.com/url?sa=t&source=web&oi=video_result&ct=res&cd=1&url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DPHtEkkKXSiY&ei=9-wKSobjEpKANvHT_MEB&rct=j&q=heusser+GTAC+2007&usg=AFQjCNHOgFzsoVss50Qku1p011J4-UjhgQ

buona fortuna! Fateci sapere come va!