Condividi tramite


Il presente articolo è stato tradotto automaticamente.

Patterns in Practice

Recapito incrementale tramite Progettazione continua

Jeremy Miller

Contenuto

Recapito incrementale delle funzionalità
Struttura continua
Il momento responsabile ultimo
Reversibility
YAGNI e Thing il più semplice che può funzionare Possibly
Come più modellazione prima codice?
Novità in quantità send-ahead

In precedenti modelli nelle colonne di esercitazione, è incentrato principalmente ai tecnici "modelli", ma in questo articolo verrà illustrato il lato "consigliabile" più "morbido" della finestra di progettazione software. Lo scopo finale dei progetti software consiste nel fornire valore al cliente e mia esperienza è che la progettazione software è un fattore principale come correttamente un team può inviare tale valore. Tramite Progettazione, in Progettazione oppure solo piatto uscita errato in Progettazione impedisce a un progetto. Una buona progettazione consente un team riesca più l'impegno.

Mia esperienza è anche la migliore progettazione di un prodotto di continuo progettazione (noto anche come emergent o evolutivo) anziché il risultato di un impegno che tenta di ottenere anticipatamente a destra il progetto intero. In Progettazione continua, è possibile iniziare con un modicum della progettazione questionario, ma si ritarda il commit delle istruzioni tecniche, purché è possibile. Questo approccio consente di cercano di applicare appresi durante il progetto per migliorare costantemente la progettazione, invece di diventare bloccato in una progettazione errata sviluppata troppo presto nel progetto.

Inoltre, saldamente credo che la soluzione migliore per creare valore aziendale sia tramite distribuzione incrementale di utilizzo funzionalità anziché con particolare attenzione prima creazione dell'infrastruttura. In questo articolo verranno esaminati consegna come incrementale di utilizzo di funzionalità consente un team di progetto per meglio fornire valore aziendale, e come utilizzando Progettazione continua può attivare incrementale recapito più efficiente e consentono di creare progettazioni software migliore.

Stima e la struttura interattivo

Prima di tutto, qual è la progettazione del software? Per molte persone software progettazione significa "Creazione di una specifica di progettazione prima di codice di avvio" o "Fase di pianificazione/Elaboration". Mi piacerebbe per passaggio away from processi formali intermedio documentazione e definire più in generale di progettazione del software come "l'atto di determinare come deve essere strutturato il codice". Che viene detto, è possibile ora pensare progettazione software che si verificano in due modalità: stima o reattiva (o riflettente se si preferisce).

Progettazione di stima è il lavoro di progettazione che è possibile eseguire prima di codice. Struttura di stima è creazione modelli UML o CRC, esecuzione di sessioni di progettazione con il team di sviluppo all'inizio dell'iterazione e la scrittura di specifiche di progettazione. Progettazione reattivo è le modifiche apportate in commenti e suggerimenti base durante o dopo la codifica. Il refactoring è progettazione reattivo. Ogni team anche persone all'interno di un team sono diverse Preferenze utilizzo struttura di stima o reattiva. Progettazione continua inserisce semplicemente maggiore importanza sulla progettazione reattive rispetto a processi di sviluppo software tradizionali.

Recapito incrementale delle funzionalità

Nel 2002, il datore di lavoro quindi è stata di sperimentazione appena minted Microsoft .NET Framework e ha avviato un progetto di valutazione utilizzando ASP.NET 1.0. I, unitamente a molti altri, accuratamente controllata del progetto, speranza per il successo in modo che è possibile iniziare a utilizzare questo nuovo framework interessanti sui progetti di nostra. Il progetto di sei mesi dopo è stato annullato. Il team certamente era occupato e per tutti gli account che ha scritto una grande quantità di codice, ma nessuna parte di codice è stato adatta per la produzione.

L'esperienza del progetto team fornisce alcune importanti lezioni. Il team ha prima creato una specifica di progettazione che apparentemente era piuttosto completo e conformed agli standard della nostra organizzazione. Con questo documento in mano, il team avviato il progetto dal tentativo di generazione di livello di accesso di tutti i dati, quindi il livello business logic e infine l'interfaccia utente. Quando è avviato le schermate dell'interfaccia utente di codice, gli sviluppatori realizzano rapidamente che il codice di accesso ai dati esistente non esattamente ciò che sono necessari per creare l'interfaccia utente, anche se tale codice conformed ai documenti di progettazione. A che punto, i partner commerciali di gestione IT e non di visualizzare qualsiasi valore recapitati dal progetto e ha generato nel towel a favore di altre iniziative.

Paradossalmente, a me la casa madre era ed uno degli esempi principali di tutto il mondo di un produttore di Agile o -time. La maggior parte dei maggiori concorrenti utilizzati "push" produzione, in cui grandi quantità di parti vengono ordinati per righe di factory in base alla domanda prevista in un periodo di tempo. Il downfalls della produzione di push nel fatto che si perde qualsiasi momento è ordinare è possibile utilizzare composta dalle parti di money; dispone per il pagamento extra per archiviare i titoli parte eccedente prima che si desidera utilizzarli, e che si è esposti per insufficienza di parte del piano di factory qualsiasi momento le previsioni sono errate, e le previsioni sono raramente accurate.

Al contrario, il datore di lavoro quindi utilizzato produzione "pull". I sistemi di factory pianificati gli ordini cliente dovevano creare tramite la coppia successiva di ore, più volte al giorno viene determinata la quantità di parti necessarie per completare gli ordini e che quindi ordinati per il recapito immediato esattamente il numero e tipo di parti necessarie. I vantaggi della produzione di pull sono che da acquistare solo cosa è necessario, sprecare meno denaro in parti che non può essere utilizzato; factory sono molto meno titoli parte scorte a che fare con, rendendo leggermente più efficiente di produzione; è possibile rapidamente adattare alle circostanze nuove e sul mercato impone quando non associato previsioni generate mesi; e previsioni e stime sono più precise quando eseguita a breve termine, anziché un termine più.

In che modo il pull e push problema è valida per lo sviluppo del software? Il progetto ho descritto precedentemente utilizzati push progettazione tenta di determinare innanzitutto tutte le esigenze infrastructural del sistema e quindi si tenta di creare l'infrastruttura di accesso ai dati prima di scrivere altri tipi di codice. Il team sprecato numerose attività di progettazione, la documentazione e la creazione di codice che non è stato utilizzato nell'ambiente di produzione.

Invece che cosa fare se il team era liquidato per rapidamente la scrittura di una specifica di alto livello con dettagli minimi, sviluppato per sviluppare la priorità più alta funzionalità alla qualità di produzione per l'internazionalizzazione, quindi la successiva funzione di priorità più alta e così via. In questo scenario, il team dovrebbe creare codice di infrastruttura solo, come codice di accesso ai dati, che è stata estratta da requisiti della funzionalità specifica.

Considerare questo problema. Che cos'è un risultato migliore per un progetto alla fine del relativo indicatore cronologico pianificata?

  1. 1 Solo al 50 % delle funzionalità proposte sono completato, ma le funzionalità più importanti della proposta di progetto iniziale sono pronti a distribuire alla produzione.
  2. Massimo di 2 per l'infrastruttura di codifica è stato completato, ma nessuna funzionalità è completamente utilizzabile e non può essere distribuito alla produzione.

In entrambi i casi il team solo circa metà eseguito e nessuno risultato veramente ha esito positivo confrontato con il piano iniziale e la pianificazione. Ma, quale "errore" sarebbe invece informare il capo? È possibile sapere mio capo e il team di vendita in modo definito preferisce il primo risultato in base incrementale del recapito.

I vantaggi chiavi di recapito incrementale sono le seguenti operazioni:

  1. Priorità di ordine di business in uso. Generazione incrementale dalla funzionalità offre la possibilità migliore per completare le funzionalità più importanti per l'azienda. Dopo tutto, perché è impiegata qualsiasi momento tipo progettazione, creazione e verifica di una funzionalità "interessante per" prima le funzionalità di "deve essere" sono state completate?
  2. Dei rischi delle misure di riduzione dei rischi. Il rischio principale nella maggior parte dei progetti non tecnico. Il rischio principale è che non fornire valore aziendale o consegnare il sistema non corretto. Inoltre, la realtà nuda è che i requisiti e analisi del progetto indicato sono semplicemente come potrebbe essere errato come la progettazione o codice. Dimostrando la funzionalità di lavoro ai partner aziendali nella fase iniziale del progetto, è possibile ottenere utili indicazioni sui requisiti del progetto. Per il team, dimostrazioni anticipate al nostro team manager e vendite di prodotti sono stati estremamente utile per l'ottimizzazione dell'utilizzabilità dell'applicazione.
  3. Consegna anticipata. È possibile inserire funzionalità completate nell'ambiente di produzione prima il resto del sistema per avviare frutta un rendimento del valore.
  4. Consegna flessibile. Che ci si creda o No, i partner commerciali e il responsabile del prodotto a cambiamenti le relative priorità. Invece di gnashing i denti nel injustice, tutti i, è possibile utilizzare in modo che si presuppone che verranno modificata la priorità. Collegando il codice di infrastruttura per le funzionalità di riproduzione, ridurre la probabilità sforzo inutilizzato a causa di modificare la priorità.

A questo punto, per lo svantaggio di consegna incrementale: difficile eseguire. Nell'esempio inclina di produzione, pull produzione utilizzati solo perché la catena della società è ultraefficient ed è in grado di factory predefinite con parti quasi su richiesta. Lo stesso vale per il recapito incrementale. È necessario rapidamente gli elementi delle nuove funzionalità di progettazione e mantenere la qualità della struttura sufficientemente elevata che non si apporta funzionalità future più difficile di generazione del codice. Che è non possibile eseguire è dedicare settimane o addirittura mesi in un momento lavorando strettamente problemi architetturali, ma esistono ancora tali problemi architetturali. È necessario modificare la modalità progettazione di sistemi software per adattare il modello di distribuzione incrementale. Si tratta di entra progettazione continua nell'immagine.

Struttura continua

Proponents di tradizionale sviluppo spesso si ritiene che i progetti sono più efficace quando la struttura può essere completamente specificata anticipatamente ridurre inutilizzato impegno nel codice e rielaborare. L'aumento della programmazione Agile e Lean è richiesta nozioni tradizionali di tempi della progettazione software introducendo un processo di progettazione continua che si verifica durante il ciclo di vita del progetto. Progettazione continua deliberatamente ritardi impegni per progettazioni particolare, si estende più operazioni di progettazione tramite il ciclo di vita del progetto e incoraggia un team di evoluzione di una struttura come il progetto viene attuato applicando appreso dal codice.

Si tratta di questo tipo. Semplicemente non sviluppare la progettazione dettagliata per una funzione fino alla creazione di tale funzionalità. Impossibile tenta di progettazione ora, ma che utilizzano progettazione non vantaggi qualsiasi fino a molte versioni successive, e nel momento in mio team si ottiene tale funzionalità, sono probabilmente molto più comprendere su architettura e sistema e potrà avviarsi con una struttura migliore rispetto a includano all'inizio del progetto.

Prima di accedere in ulteriormente, vorrei dire che progettazione continua non implica alcun lavoro di progettazione di ha luogo anticipatamente. Mi piacequesta offerta da c. Robert (Carlo corretta) Martin: " L'obiettivo è creare una struttura iniziale piccola ma in grado, quindi mantenere ed evoluzione di questa struttura tutta la durata del sistema ."

Prima di scrivere Disattiva progettazione continua come rischiosa e soggetta a errori, di seguito viene illustrato come apportare alla struttura continua esito positivo (in altre parole, sto per tentare di indurre che questo non è utilizzato).

L'importanza di commenti e suggerimenti

Molti progetti sono veramente semplici, con ben-compreso i requisiti e utilizzano esclusivamente tecnologie conosciute. Progettazione questionario potrebbe funzionare piuttosto bene con i progetti, ma la mia esperienza è l'opposto. Quasi tutti i progetti utilizzati in ha un certo grado di novelty, nella tecnologia utilizzata, le tecniche di sviluppo utilizzate, o nei requisiti. In questi casi, credo che la soluzione migliore per riuscire sia di adottare un atteggiamento humility e dubbi. Non occorre considerare ciò che che si sta eseguendo e pensare funziona fino a ottenere una sorta di commenti e suggerimenti che verifica il codice o la struttura.

Poiché Progettazione continua implica l'evoluzione della struttura del codice, è ancora più importante quando si utilizza questo approccio per creare rapidamente commenti e suggerimenti di cicli per rilevare errori anticipati causati da modifiche al codice. Diamo il modello di programmazione estrema (XP) di sviluppo come esempio. XP chiama per un approccio iterativo altamente allo sviluppo che rimane controverso. Quasi come controverso consiste nel fatto che XP specifica una serie di procedure che sono piuttosto difficili da accettare per molti sviluppatori e negozi. In particolare, è necessario che XP ottimali progettati in gran parte per compensare il tasso rapido di iterazione, fornendo i cicli di commenti e suggerimenti rapidi e completi.

  • Proprietà collettiva coppia di programmazione. Con affetto, o odio, programmazione di coppia è necessario che almeno due coppie di occhi esaminare tutte le righe di codice di produzione. Coppia di programmazione fornisce il feedback da una progettazione o codice revisione semplice secondi dopo il codice è scritto
  • Basato su test sviluppo (TDD), basato sul comportamento dei test di sviluppo (BDD) e accettazione. Tutte queste attività creare commenti e suggerimenti molto rapido. TDD e BDD consentono di unità da difetti nel codice scritti inizialmente, ma altrettanto importante, il livello elevato di unit test coverage rende successive modifiche di progettazione e aggiunte al codice molto più sicuro per rilevare errori di regressione in modo specifico.
  • Continuous integration. Se combinato con un elevato livello di copertura di test automatizzati e strumenti di analisi codice eventualmente statico, continuous integration possibile trovare rapidamente problemi in base di codice che viene archiviato ogni codice di orario.
  • Retrospectives. È necessario che il team di sviluppo interrotta e illustrare come la progettazione di software è di aiuto o compromettendo l'impegno di sviluppo. Ho visto numerosi miglioramenti di progettazione forniti di iterazione e rilasciare retrospectives.

La qualità e quantità i meccanismi di commenti e suggerimenti di influire notevolmente sulle progettazione. Copertura di test automatizzati elevato con unità ben scritta verifica, ad esempio, rende molto più semplice ed efficiente di refactoring. Refactoring con minime o Nessuna copertura di test automatizzati è probabilmente troppo rischioso. È possibile quasi unhelpful come con non verifica qualsiasi scritta male unit test.

Il reversibility del codice è notevolmente migliorato mediante meccanismi di commenti e suggerimenti a tinta unita.

Il momento responsabile ultimo

In caso contrario anticipatamente, quando decisioni di progettazione? Tra le più importanti lezioni che verranno fornite informazioni tramite Progettazione continua è da cognizant delle decisioni apportate sulla progettazione e consapevolmente decidere quando tali decisioni. Programmazione snelli insegna a prendere decisioni al momento"l'ultimo responsabile." In base a Mary Poppendieck (informazioni in suo libro Lean Software Development) seguendo questo principio significa "ritardare impegno fino a quando non … il momento in cui errori rendere una decisione Elimina alternativa importante."

Il punto è di prendere decisioni tardi possibile, perché è quando si dispone di più informazioni con cui la decisione. Si pensi al progetto che descritto all'inizio di questo articolo. Tale team sviluppato e salvate troppo presto una progettazione dettagliata del codice di accesso ai dati. Se gli sviluppatori sono consentire l'interfaccia utente e la logica aziendale deve unità la forma di codice di accesso dati come sono creati funzionalità dell'interfaccia utente, avrebbe consentito di evitare parecchio lavoro inutilizzato. (Questo è un esempio di "progetto basato su client," dove creare il consumer di un'API prima per definire la forma e la firma dell'API di se stesso).

Uno dei concetti chiavi qui è che è necessario pensare in anticipo e proporre continuamente le modifiche di progettazione, ma è non applicare definitivamente una direzione di progettazione finché non si dispone di. Non si desidera agire in base alla progettazione speculative. Commit in anticipo uno schema impedisce la possibilità di utilizzare un'alternativa più semplice o superiore che potrebbe presentare stesso in un secondo momento nel progetto. Per citare un precedente collega due Mike fama NUnit 2, "Think Avanti Sì, non Avanti."

Reversibility

Martin Fowler viene visualizzato, "Se si possono facilmente modifica le decisioni, ciò significa che è meno importante ottenere tali a destra, che rende la vita molto più semplice." Strettamente correlata all'ultimo momento responsabile è il concetto di reversibility che descriverò come capacità o impossibilità di modificare una decisione. Corso cognizant del reversibility delle decisioni inerenti è essenziale per segue il principio all'ultimo istante del responsabile. Il primo decisionale mio team apportate per un progetto recente è stato consente di sviluppare con Ruby on Rails o rimanere con un'architettura di .NET. Scelta di una piattaforma e il linguaggio di programmazione non è una decisione facilmente reversibile e sapevamo che è stato necessario tale decisione anticipata. In altri progetti, ho avuto coordinarsi con gruppi esterni necessari per definire e pianificare in anticipo i mesi di tempo. In casi simili a quelli, mio team assolutamente doveva decisioni anticipatamente effettuare operazioni con i team esterni.

Una decisione classica riguardanti reversibility è se generare la memorizzazione nella cache in un'applicazione. Pensare a casi in cui non si conosce certezza se si desidera effettivamente memorizzare nella cache alcuni tipi di dati. Se si temere che la memorizzazione nella cache sarà possibile adeguare in un secondo momento, è sempre necessario creare tale memorizzazione nella cache all'avvio, anche se che può essere una perdita di tempo. D'altra parte, che cosa fare se si è strutturato il codice per isolare l'accesso ai dati in modo è facilmente possibile adeguare memorizzazione nella cache il codice esistente con un piccolo rischio? Nel secondo caso, consente all'individuazione di evitare il supporto di memorizzazione nella cache per il momento e fornire la funzionalità più veloce.

Reversibility consente inoltre il team in quali tecnologie e tecniche utilizziamo. Poiché si utilizza un processo di recapito incrementale (Kanban con procedure di progettazione Extreme Programming), si preferiscono indubbiamente tecnologie e procedure consigliate alzare di livello superiore reversibility. Il sistema dovrà probabilmente supportano più motori di database a un certo punto in futuro. A tal fine, utilizziamo un framework di mapping relazionale a oggetti per separare in gran parte il livello intermedio dal motore di database effettivo. Altrettanto importante, abbiamo un insieme piuttosto completo di test automatizzati che utilizzano l'accesso al database. Quando è tempo per lo scambio di motori di database, è possibile utilizzare tali test per essere certi che il sistema funziona con il nuovo motore di database, o almeno sottolineare esattamente nel punto in cui siamo incompatibile.

YAGNI e Thing il più semplice che può funzionare Possibly

Per eseguire progettazione continua, è disporre facilitare il codice modificare, ma vorremmo realmente evitare che numerose variazioni nel codice come si devono apportare modifiche. A scopo di recapito incrementale, si desidera concentrarsi sulla generazione solo le funzionalità che è in esecuzione con l'ora di creazione, ma non si desidera rendere la funzione successiva più difficili da sviluppare, rendendo la progettazione o impossibile non compatibile con le esigenze future.

Programmazione estrema introdotto due sayings per comunemente di sviluppo che sono rilevanti qui: "È non gonna necessario" (YAGNI, si pronuncia "nee yawg") e "Cosa il più semplice che probabilmente potrebbe funzionare."

YAGNI proibisce in primo luogo, è possibile aggiungere qualsiasi codice il sistema ora che non verrà utilizzato dalle funzionalità corrente. " Paralysis analisi"nello sviluppo di software è un problema reale e YAGNI Taglia tramite il problema forzando concentrarsi solo il problema immediato. Gestione complessità è difficile, ma consente di YAGNI riducendo l'ambito della progettazione di sistema che è necessario considerare in qualsiasi momento.

Naturalmente, YAGNI possibile suoni con tema horror e forse anche irresponsible in quanto si potrebbe essere necessario molto bene il livello di complessità ignorata la prima volta. Segue YAGNI non significa che è necessario eliminare possibilità in futura. Uno dei modi migliori per assicurarsi che è di utilizzare "la cosa più semplice potrebbe funzionare probabilmente".

Mi piace la definizione di Alan Shalloway della cosa più semplice che potrebbe funzionare probabilmente visualizzata nell'elenco riportato di seguito. (La regola di una volta-e-solo a volte fa riferimento l'eliminazione di duplicazione dal codice; si tratta di un altro modo per descrivere il principio di "non ripetere anche manualmente"). È necessario scegliere la soluzione più semplice ancora conforme a queste regole:

  1. Esegue tutti i test.
  2. Segue la regola di una volta sola e-solo-volta.
  3. Dispone di coesione elevato.
  4. Dispone di accoppiamento ridotto.

Queste qualità strutturale di codice facile codice modificato in seguito.

Il punto di queste sayings complementare è che ogni porzione di complessità è guadagnare il diritto di esiste. Considerare tutto ciò che può verificarsi quando si sceglie una soluzione più complessa su una più semplice:

  1. Garantisce il buon la complessità aggiuntiva chiaramente esita.
  2. La complessità aggiuntiva non è necessaria e rappresenta inutilizzato impegno su un approccio più semplice.
  3. La complessità aggiuntiva rende più difficile ulteriormente lo sviluppo.
  4. La complessità aggiuntiva è errato flat-out e deve essere modificati o sostituiti.

I risultati di aggiunta di complessità includono un risultato positivo e tre risultati negativi. Al contrario, fino a prova contraria, una semplice soluzione potrebbe essere adeguata. Più importante in semplice approccio probabilmente sarà molto più semplice per creare e utilizzare con altre parti del codice e se è disponibile essere modificato, beh, è più facile modificare il codice semplice rispetto al codice complesso. Lo scenario peggiore è che è necessario generare immediatamente il codice semplice e avviare su, ma da quel momento, che è probabile che affinché comunque una molto migliore comprensione del problema.

A volte una soluzione più complessa in modo definito verrà attivare per essere giustificate e la scelta corretta, ma molto spesso, utilizzando un approccio più semplice è preferibile alla fine. In modo coerente in seguito YAGNI e "la cosa più semplice" in dubbio è semplicemente seguente la probabilità.

Come più modellazione prima codice?

È opportuno inserire riservare i requisiti di documentazione per il momento. Ecco una domanda classica nello sviluppo di software: "quanti progettazione e modellazione devo fare prima di iniziare a codice?" Non è disponibile nessuna risposta definitiva poiché ogni situazione è diversa. Il punto chiave è che quando non si è sicuri come procedere, ciò significa che sono in una modalità di apprendimento. Se si alcuni modellazione o codifica esplorativo prima strettamente dipende approccio consente di apprendere più rapidamente a portata di mano il problema e, naturalmente, È necessario ripetere questa offerta da Bertrand Meyer classica: "Bolle non bloccarsi".

  • Se sta lavorando con tecnologia sconosciuto o modello di progettazione, credo che la modellazione non è quasi come utile durante la lettura dirty esplorativo modificandone le mani.
  • Se un'idea di progettazione è molto più semplice per poter visualizzare in un modello più nel codice, in tutti i modo disegnare alcuni modelli.
  • Se si conosce alcun punto di partenza nel codice, non solo stare la finestra IDE speranza di ispirazione. Estrarre una carta e penna e prendere nota attività logiche e le responsabilità per l'attività che si sta lavorando.
  • Passare alla codifica al secondo che si raggiunge un punto di resa con modellazione. (Ricordare, fumetti non bloccarsi!) Allineamento migliore le caselle nel diagramma non consente la scrittura di codice migliore!
  • Se si salto direttamente nel codice e si inizia avere difficoltà, interrompere e tornare alla creazione di modelli.
  • Tenere presente che è possibile passare dalla codifica e modellazione. Numero di volte quando si corrono con un difficile problema di codifica, la cosa migliore da fare è selezionare le attività più semplice, quelli di isolamento del codice e utilizzare il modulo del codice per determinare cosa dovrebbe essere simile al resto del codice.

Un altro aspetto da tenere a mente è che alcuni moduli di modellazione sono più leggeri rispetto ad altri. Se UML non consentono di un problema, passare alla schede CRC o anche entità relazione diagrammi.

Novità in quantità send-ahead

In questo articolo non era Nessun tipo di codice, ma fortemente ritiene che questi concetti applicano a quasi tutte le decisioni di progettazione. In una colonna futura, verrà spiegare alcuni concetti specifici e le strategie per lo sviluppo di progetti che consentono di utilizzare principi di progettazione continua. Verrà inoltre descritto in maggiore dettaglio come refactoring si inserisce nel continuo di progettazione.

Per inviare domande e commenti per mmpatt@microsoft.com.

Jeremy Miller, un Microsoft MVP per C#, è anche autore delstrumento StructureMap open sourceper l'inserimento di dipendenze con .NET e il forthcomingStoryTellerstrumento per l'accettazione automatica test in. NET. Visitare il suo blog "Il Shade Tree Developer" parte del sito CodeBetter.