Technology Experience

Contenuti gestiti da Igor Damiani
posts - 949, comments - 2741, trackbacks - 15120

My Links

News

  • Questo blog si propone di raccogliere riflessioni, teoriche e pratiche, su tutto quello che riguarda il world-computing che mi sta attorno: programmazione in .NET, software attuale e futuro, notizie provenienti dal web, tecnologia in generale, open-source.

    L'idea è quella di lasciare una sorta di patrimonio personale, una raccolta di idee che un giorno potrebbe farmi sorridere, al pensiero di dov'ero e cosa stavo facendo.

    10/05/2005,
    Milano

Archives

Post Categories

Generale

Lo unit testing come lo intendo io

Ho appena letto questo post segnalato da Lorenzo che mi ha fatto riflettere. Le modalità del database unit testing descritto assomigliano moltissimo alle modalità con cui sfrutto nUnit e Test Driven .NET nelle mie ultime settimane. Mi spiego meglio, ma prima ho bisogno di fare una piccola premessa.

Sabato mattina mio fratello ha messo live la nostra piccola applicazione per la gestione di concessionari d'auto, creata ad-hoc per un concessionario piuttosto imponente di Lodi. Lo sviluppo di questa applicazione ha richiesto molto più tempo di quello preventivato inizialmente, per tutta una serie di motivi, di cui magari parlerò in un altro post (anche un fallimento può farci guadagnare experience point e farci salire di livello). Nelle fasi iniziali di sviluppo io e mio fratello abbiamo prima creato un domain model strutturato in grado di rappresentare adeguatamente gli oggetti del dominio applicativo. Senza scendere troppo nel dettaglio, ci sono tutta una serie di oggetti che vanno dall'atto di vendita tipico, o a quello specifico nel caso di nuovo veicolo o veicolo usato, c'è un'anagrafica clienti categorizzata, importi dettagliati. Alla fine, ci siamo ritrovati a gestire qualcosa come ~15 classi gerarchicamente legate fra di loro, tutte mappate con NHibernate per essere persistite su database. E qui arriva il mio discorso legate ad nUnit.

Ho creato un progetto dedicato allo unit testing. Attraverso il codice, istanzio oggetti del mio domain model, dal più semplice al più complesso. Poi li salvo su database con NHibernate. Ho creato ~40 metodi di test che salvano e rileggono gli oggetti del domain model, assicurandomi ogni volta che l'oggetto venga persistito correttamente. Questo mi assicura che il database sia sempre congruo rispetto al domain model implementato. Questo mi assicura che il file di mapping di NHibernate sia sempre corretto. Questo mi assicura che il mio codice continui a funzionare anche se rinomino un campo, o una tabella, o una stored-procedure. Riporto qui sotto a titolo di esempio uno dei tanti metodi che ho scritto per testare la persistenza.

[Test]
public void CreaNuovo15()
{
    AttoVendita av = 
new AttoVendita();
    av.Denominazione = "CreaNuovo15";
    av.Finanziaria = "Finanziaria";
    av.Locatario = "Locatario";
    av.Modello = "Modello";
    av.NumeroFattura = "NumFatt";
    av.Protocollo = "Protocollo";
    av.ProtocolloVendita = "Protocollo Vendita";
    av.Marca = DataProvider<Marca>.LoadObject(2);
    av.Nuovo = 
null;

    
// Aggiungo i dettagli importo all'AttoVendita
    
DettaglioImporto di = new DettaglioImportoAttoVendita(av);
    di.Esecutore = DataProvider<Soggetto>.LoadObject(5);
    di.Lavorazione = DataProvider<Lavorazione>.LoadObject(1);
    di.ImportoUnitario = 80;
    di.Quantita = 1;
    av.Importi.Add(di);

    
// Aggiungo un oggetto Usato a questo AttoVendita
    
Usato us = new Usato(av);
    us.AnnoImmatricolazione = 2000;
    us.ArchiviazioneUsato = "arch.usato";
    us.ClasseVeicolo = ClasseVeicoloEnum.Rimorchio;
    us.DataFatturaExProprietario = DateTime.Today;
    us.Denominazione = "denominazione";
    us.ExProprietario = DataProvider<Soggetto>.LoadObject(7);
    us.Notaio = DataProvider<Soggetto>.LoadObject(6);
    us.NumeroStock = "numero stock";
    us.PassaggioProprietà = 
true;
    us.Repertorio = "repertorio";

    
// Aggiungo un dettaglio importo all'oggetto Usato
    
di = new DettaglioImportoUsato(us);
    di.Esecutore = DataProvider<Soggetto>.LoadObject(5);
    di.ImportoUnitario = 45;
    di.Lavorazione = DataProvider<Lavorazione>.LoadObject(1);
    di.Quantita = 3;
    us.Importi.Add(di);

    
// Aggiungo un oggetto VenditaUsato all'oggetto Usato
    
VenditaUsato vendita = new VenditaUsato(us);
    vendita.DataFattura = DateTime.Today.AddDays(1);
    vendita.NumeroFattura = "num.fattura";
    vendita.PartitaIva = "p.iva";
    vendita.Provincia = "MI";

    
// Aggiungo un dettaglio importo all'oggetto VenditaUsato
    
DettaglioImportoVenditaUsato divu = new DettaglioImportoVenditaUsato(vendita);
    divu.Esecutore = DataProvider<Soggetto>.LoadObject(5);
    divu.ImportoUnitario = 11;
    divu.Lavorazione = DataProvider<Lavorazione>.LoadObject(1);
    divu.Quantita = 11;
    vendita.Importi.Add(divu);

    us.Vendita = vendita;
    av.Usato = us;

    DataProvider<AttoVendita>.SaveObject(av);
    newID = av.ID;
    Debug.WriteLine("Inserito ID = " + newID.ToString());

    
Assert.AreNotEqual(newID, 0, "L'entità non è stata salvata!");
}

Mio fratello, che inizialmente era scettico, alla fine ha afferrato l'effettivo vantaggio, anche perchè all'aumentare dei metodi di test, il tutto diventa sempre più efficace. Non è una cosa da poco, anche perchè il mio domain model attualmente ha un solo oggetto root chiamato AttoVendita, al di sotto del quale vivono numerosi altri dettagli che non sempre esistono, a seconda dei casi. Quindi è molto importante verificare sempre che la gerarchia di business object venga mappata sul database nelle tabelle corrette, con relazioni 1:1 o 1:molti. Usare Test Driven .NET, cliccare col pulsante destro sul progetto dedicato, cliccare Run Tests e vedere la scritta ~40 test passed è motivo di soddisfazione, credetemi.

Beh, insomma, quel post che ho segnalato all'inizio sembra molto fare il mio stesso ragionamento. Il database unit testing è quanto di più vicino abbia trovato rispetto al mio modo di intendere lo unit testing. Indipendentemente dallo strumento tecnologico utilizzato, sia chiaro. Se tutti i miei test passano, sono sicuro al 100% che cliccando il pulsante Salva della mia interfaccia utente, l'oggetto verrà salvato correttamente, senza troppe storie, dal momento che la UI del software richiama esattamente gli stessi metodi del data provider testati durante lo unit testing. E ci mancherebbe altro, altrimenti cosa servirebbe farli?

powered by IMHO 1.2

Print | posted on Monday, June 26, 2006 10:03 AM | Filed Under [ Sviluppo .NET ]

Feedback

Gravatar

# re: Lo unit testing come lo intendo io

Parlare del numero di test che passano senza parlare del code coverage è un'informazione assolutamente inattendibile...
6/26/2006 10:57 AM | Lorenzo Barbieri
Gravatar

# re: Lo unit testing come lo intendo io

non ho scritto il post per indicare quanti test passano, anche perchè se no dovrei descrivere meglio un po' tutto, come il code coverage che hai detto tu. Ho scritto il post per sottolineare che adesso si ragiona sullo unit testing anche in termini di database, e non solo per query/view/sp, ma anche (e lo dice il post) per assicurarci che il nostro codice continui a funzionare su quella struttura di database.
6/26/2006 12:59 PM | Igor Damiani
Gravatar

# re: Lo unit testing come lo intendo io

Lo so... ma una cosa è quello che vuoi scrivere, una cosa è quello che trasmetti.
Leggendo il post si capisce... ah... se ho 40 test che passano allora non avrò errori nel codice prodotto, che è uno degli errori più comuni che fanno i newbee dello unit testing.
Lo so che tu lo sai, ma questi post li legge anche gente che non ha tutto il contesto in cui calarli...
6/26/2006 1:24 PM | Lorenzo Barbieri
Gravatar

# Elavil.

Elavil fact sheet. Cousin to elavil. Elavil.
Gravatar

# Synthroid side effects.

Synthroid anxiety. Synthroid. Low cost synthroid.
3/11/2010 6:57 PM | Synthroid dosage.
Gravatar

# Keflex urinary tract infection.

Keflex penicillin sulfa interaction.
3/12/2010 1:18 AM | Keflex.
Gravatar

# Elavil.

How does elavil work. Elavil high. Elavil. Zoloft and elavil intervantion. Interactions between topamax and elavil.
3/12/2010 7:57 AM | Elavil.
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET