November 2009 Blog Posts
Usare TDD ovunque, testare un servizio WCF - TDD everywhere, testing a WCF service

Il Test Driven Development è un’altra delle metodologie secondo me vincenti, specialmente in alcuni contesti, in alcuni, perchè non è detto che siano sempre adatte.

TDD o meglio Test Driven Design è particolamente utile quando si scrive una nuova applicazione o nuove feature nella fase di design della soluzione, partire dal test permette di tradurre al meglio la User Story o la feature (Feature Driven Development) nel codice che la implementa, si rimane concentrati sul cosa e non sul come, si scrive lo stretto necessario senza over-ingegnerizzare => “over-complicare”.

Scrivendo prima il test si identificano le classi/membri esattamente nel momento in cui servono, inoltre con i test ovviamente… si hanno i test :), si possono verificare più use-case e rendere il codice più robusto. Infine grazie agli stub ed ai mock non è indispensabile lavorare sulle classi reali anzi meglio lavorare su fake con Unit Test, invece che scrivere Integration Test. Ovviamente sono utili anche gli Integration Test ed i System Test per evitare allo sviluppatore di eseguire continuamente l’applicazione. Nonstante questo gli User Acceptance Test rimangono indispensabili, uno o più utenti devono testare l’applicazione e la UI specialmente (se esiste) perchè ovviamente è la parte maggiormente a contatto con il “ProductOwner” e probabilmente la più difficile da testare in automatico attualmente.

Arriviamo al titolo del post :). In un progetto a cui lavoro ho avuto la necessità di creare una key per una entity che fosse in realtà un’insieme di valori eterogeneo, il motivo è che lo storage è più di uno ed ogni storage può definire differenti chiavi naturali (i loro progettisti, Topolino e Paperino, non conoscono le chiavi surrogate e i Guid :D).
Topolino e Paperino DB designers

Quindi partendo dal test:

   1: public void CreateAKeyExpectedCorrectNameAndCorrectValueAreSetted()
   2: {
   3:     var concreteKey = new ConcreteKey(KnownKeys.Key);
   4:  
   5:     concreteKey
   6:         .Id
   7:         .ShouldEqual(KnownKeys.Key, "IdKey has not the expected value.");
   8: }


Quindi la classe Key:

   1: public abstract class Key : IEnumerable<KeyValue>
   2: {
   3:     private readonly IEnumerable<KeyValue> keysDictionary;
   4:  
   5:     protected Key(params KeyValue[] keyValues)
   6:     {
   7:         if ((keyValues == null) || (keyValues.Length == 0))
   8:         {
   9:             throw new ArgumentException("Must define at least a KeyValue.", "keyValues");
  10:         }
  11:  
  12:         keysDictionary = keyValues;
  13:     }
  14:  
  15:     public IEnumerator<KeyValue> GetEnumerator()
  16:     {
  17:         return 
  18:             keysDictionary
  19:             .OrderBy(keyValue => keyValue.Key)
  20:             .GetEnumerator();
  21:     }
  22:  
  23:     IEnumerator IEnumerable.GetEnumerator()
  24:     {
  25:         return GetEnumerator();
  26:     }
  27:  
  28:     protected T GetKeyValue<T>(string keyName) where T : struct
  29:     {
  30:         var value =
  31:             keysDictionary
  32:                 .Where(e => e.Key == keyName)
  33:                 .First()
  34:                 .Value;
  35:  
  36:         return (T) value;
  37:     }


Ho quindi scritto un DTO per trasportare le entity attraverso WCF e qui nasce il problema, non volendo creare un servizio WCF fittizio solo per verificare che il design sia corretto ho cercato come hostare il servizio direttamente dal test, ed ecco la soluzione: Testable WCF ServiceHost.

In sostanza grazie alla classe scritta dall’autore è possibile questo test:

   1: [TestMethod]
   2: public void CallGetAllOfWcfServiceExpectedWorksAndKeysAreSetted()
   3: {
   4:     using (var messageServiceHost = new WcfTestHost<Service, IService>())
   5:     {
   6:         var client = messageServiceHost.CreateProxy();
   7:         var dtoSet = client.GetAll().ToList();
   8:  
   9:         var keyValue = dtoSet[0]
  10:             .Key
  11:             .First();
  12:  
  13:         keyValue
  14:             .Key
  15:             .ShouldEqual(ConcreteKey.IdKeyName, "Expected a key that is not present.");
  16:  
  17:         ((int)
  18:         keyValue
  19:             .Value)
  20:             .ShouldEqual(KnownKeys.Key, "Wrong key value.");
  21:     }
  22: }


Un pezzo della classe WcfTestHost:

   1: public WcfTestHost(Binding binding)
   2: {
   3:     host = new ServiceHost(serviceImplType);
   4:     this.binding = binding;
   5:  
   6:     url = string.Format("{0}://localhost/{1}", binding.Scheme, Guid.NewGuid());
   7:     host.AddServiceEndpoint(serviceIntType, binding, url);


Nell’esempio allegato si trova il progetto della key e la classe per testare un servizio WCF completa, grazie a qualche email scambiata con l’autore, di error handling e trace che permette di intercettare qualsiasi exception scatenata “lato server”.
Solution TDD WCF 

Scarica qui.

Matteo Migliore.

Technorati Tags: ,,,
Add Comment Filed Under [ Architettura ]
Scrum e il template di Conchango per Visual Studio - Scrum and Conchango template for Visual Studio

Per usare Scrum agevolmente con Visual Studio il modo più semplice è usare il template di Conchango, sviluppato in collaborazione con Microsoft e Ken Schwaber (co-autore insieme a Jeff Sutherland della metodologia). Con Visual Studio 2010 e TFS 2010 invece si ha a disposizione un nuovo template agile (MSF for Agile Software Development v5.0), sul blog di Aaron Bjork si trovano maggiori informazioni.

Al momento sto usando il nuovo template solo su due progetti quindi non ho ancora sufficienti elementi per poterne parlare, invece sono ormai 5 mesi che lavoro con il template di Conchango e soprattutto con la TaskBoard che è davvero molto utile per seguire il processo di sviluppo incrementale, per la gestione delle User Story, Task, Bug e Impediment durante lo sprint. Conchango TaskBoard

Ieri ho fatto planning con un cliente, non l’avevano mai fatto, li stò anche portando ad usare Scrum e TDD, non hanno però un’installazione di TFS 2008 o 2005 su cui installare il template di Conchango e poi considerando che il progetto è nuovo ho consigliato di partire direttamente con VS 2010 Beta 2 e quindi con TFS 2010, per cui ciccia.

Per sopperire alla mancanza di un tool ci siamo muniti dei soliti Post-It, che hanno vantaggi (vedasi uno dei pochi, e soprattuto corti :D, post di Mauro):

  • sono fisici, tangibili e difficili da spostare! :)
  • bisogna pensare di più alle UserStory e ai Task rispetto ad un tool software

E svantaggi:

  • sono fisici, tangibili e difficili da spostare! :)
  • è più difficile manutenerli, riscriverli, modificarli
  • ci si concentra troppo sulla loro disposizione piuttosto che sulla pianificazione
Per questo preferisco un software, ciò nonostante, meglio i Post-It e Scrum piuttosto che Waterfall e pianificazione per anni senza risultati (vedi release funzionanti).

Sto cercando altri tool che permettano di lavorare con il template di Conchango oppure con il sopracitato MSF Agile 5.0 Beta 2 di TFS 2010, non ho ancora trovato nulla che mi soddisfi, lo sto cercando per il cliente e per me, stò lavorando insieme ad altre 3 persone ad un progetto che si chiama Time Assistant, di cui in teoria parlerò fra qualche tempo:
Time Assistant .NET - Architecture Sample on CodePlex


E’ su CodePlex che purtroppo offre consente di usare un solo template che offre ben tre tipi di WorkItem :D… un po’ poco per lavorare profiquamente:
  • Bug
  • Feature
  • Task

Ci sarebbe questo di Telerik, gratuito e molto ben fatto, ma nella TaskBoard non ho avuto modo di vedere se è possibile una visualizzazione tipo quella sopra, in particolare vedere i Task raggruppati nelle User Story:
Telerik TaskBoard

E Mingle di Thought Works (a proposito, ora il mio cliente principale è GSK, una nota casa farmaceutica, un posto fantastico in cui lavorare, dove la qualità del software è apprearezzata e bramata, dove spesso è premiato il “come” rispetto al “quanto”, e grazie alla quale ho potuto lavorare con un collega di Mr. Pattern Martin Fowler nella veste di agile coach, woooowww!!), ma anche questo sembra non funzionare.

E infine rimane ScrumDesk, che ovviamente si installa, crea il DataBase in locale, ma dall’applicazione non c’è verso di fare login…

Vediamo se prossimamente esce qualcosa dal cilindro :).

Matteo Migliore.

Scrum, lo sviluppo incrementale e agile con .NET – Scrum, incremental development and agile with .NET

Negli ultimi mesi sto lavorando ad un progetto in particolare che utilizza Scrum e TDD (Test Driven Development) come metologie agile. La forza delle metodologie agile, dello sviluppo incrementale e delle iteration è davvero fantastica.

Metologia agile Scrum - Scrum agile metodology


Scrum è una metodologia agile iterativa che consente attraverso il planning e l’estimation di produrre delle release funzionanti ad ogni fine sprint, che può durare due o quattro settimane. La durata viene stabilita all’inizio del progetto e non dovrebbe più essere cambiata perchè diventa difficile calcolare la velocity, cioè la capacità che ha il team nello “smaltire” l’effort.

Il ProductOwner è “la voce” che rappresenta gli utenti dell’applicazione, è la figura che stabilisce quali sono le feature desiderate e che si occupa di scrivere le User Story. Le User Story sono l’elemento portante di qualsiasi metodologia agile, sono la formalizzazione delle feature.

All’inizio di ogni iterazione viene fatto il planning con il ProductOwner, il team e lo ScrumMaster, che è invece la figura mediatoria che prevalentemente si occupa di risolvere gli “impediment” che incontra il team; un impediment è un imprevisto che il team deve affrontare per procedere allo sviluppo della release.

La sessione di design si può affrontare usando il Planning Poker, ad esempio con questa applicazione WPF:
1. viene presa in considerazione una user story ritenuta prioritaria dal business
2. la user story viene suddivisa in task dal team
3. ogni membro del team gioca una carta per stimare l’effort (costo); l’efforto può essere un numero di Fibonacci (modificato :)) da 1 a 100 (1, 2, 3, 5, 8, 13, 20, 40, 60, 100, ?)
4. il team discute eventuali disparità nell’effort per concordare quale assegnare 
5. è buona regola suddividere ulteriormente task che superano 5

Lo sviluppo incrementale permette al business di pianificare correttamente le feature, anzichè “sparare” senza capire i costi di sviluppo, permette anche di pensare meglio a queli sono i benefici nei processi aziendali che si vogliono raggiungere prima grazie al software.

Al team invece permette di fare delle previsioni più affidabili e di concentrarsi sugli obiettivi e le problematiche tecniche imminenti anzichè divagare per cercare “la soluzione più bella”; si fa solo quello che è necessario per arrivare alla produzione della release. Il resto viene posticipato.

Ovviamente è necessaria anche una metodologie di sviluppo coerente con la metodologia di processo adottata… e qui arriviamo a TDD, per un prossimo post.

Per ulteriori dettagli sulla metodologia rimando a Wikipedia e al libro che ho segnalato.

Matteo Migliore.

Nuovi libri su agile, Scrum e .NET - New books about agile, Scrum and .NET

Ho acquistato due nuovi libri che consiglio, specialmente quello su SCRUM:
1. Agile Project Management with Scrum (Microsoft Professional)
2. Visual Studio Team System: Better Software Development for Agile Teams  

Agile Project Management with Scrum (Microsoft ProfessionalVisual Studio Team System: Better Software Development for Agile Teams
Prossimamente (febbraio e marzo) verrano pubblicati anche questi:
3. CLR via C# 3rd Edition
4. Pro WPF in C# 2010

Cosa c’è di nuovo in C# 4.0: Jeffrey Ritcher - What's new in CLR Via C# (4.0)

Matteo Migliore.