Condividi tramite


Il presente articolo è stato tradotto automaticamente.

Panoramica dello sviluppo basato su comportamenti

Sviluppo basato su comportamenti con SpecFlow e WatiN

Brandon Satrom

Scarica il codice di esempio

Come unit test automatici diventa più onnipresente nello sviluppo di software, in modo non l'adozione di diversi metodi di prova-la prima. Ciascuna di queste pratiche presentano una serie unica di opportunità e sfide ai team di sviluppo, ma tutti si sforzano di istituire una mentalità "testing come design" con gli operatori.

Per gran parte dell'era il primo test, tuttavia, il metodo per esprimere il comportamento di un utente è stato attraverso unità prove scritte nel linguaggio del sistema — un linguaggio disinnestato da quella dell'utente. Con l'avvento delle tecniche di sviluppo Behavior-Driven (BDD), sta cambiando questa dinamica. Utilizzando tecniche BDD che è possibile creare automatizzati test nel linguaggio del business, tutto, mantenendo una connessione al vostro sistema implementato.

Naturalmente, una serie di strumenti è stata creata per aiutarvi a implementare BDD nel processo di sviluppo. Questi includono il cetriolo in Ruby e SpecFlow e WatiN per la Microsoft.NET Framework. SpecFlow ti aiuta a scrivere ed eseguire specifiche all'interno di Visual Studio, mentre WatiN consente di guidare il browser per il testing del sistema automatizzato di end-to-end.

In questo articolo, verrà fornita una breve panoramica di BDD e poi spiegare come il ciclo BDD avvolge il tradizionale ciclo di Test-Driven Development (TDD) con livello di funzionalità di test che implementazione a livello di unità disco. Una volta che ho gettato le basi per i metodi di prova-la prima, I'll introdurre SpecFlow e WatiN e si mostrano esempi di come questi strumenti possono essere utilizzati per implementare BDD per i vostri progetti con MSTest.

Una breve storia di test automatizzati

Una delle pratiche più preziose di emergere dal movimento per il Software Agile è uno stile di sviluppo automatizzato, il primo test, spesso denominato Test-Driven Development, o TDD. Un principio chiave del TDD è che la creazione di test è tanto relativi alle linee guida di progettazione e sviluppo quanto si tratta di verifica e di regressione. È anche sull'utilizzo la prova per specificare un'unità di funzionalità necessarie e tale test quindi scrivere solo il codice necessario per offrire tale funzionalità. Pertanto, il primo passo nella realizzazione di qualsiasi nuova funzionalità è descrivere le vostre aspettative con un difetto di prova (vedi di Figura 1).

image: The Test-Driven Development Cycle

Figura 1 di ciclo di sviluppo basato su Test

Molti sviluppatori e le squadre hanno avuto grande successo con TDD. Altri non hanno e trovare che lottano con la gestione del processo nel corso del tempo, tanto più che il volume delle prove comincia a crescere e la flessibilità di tali test inizia a degradare. Alcuni non sono sicuri come iniziare con TDD, mentre altri trovano facile da avviare, solo per guardare che abbandonato come scadenze vicini e grandi accumuli loom TDD. Infine, molti sviluppatori interessati incontrano resistenza alla pratica all'interno delle loro organizzazioni, sia perché la parola "test" implica una funzione che appartiene a un altro team o perché la falsa percezione che TDD risultato troppo codice supplementare e rallenta i progetti.

Steve Freeman e Nat Pryce, nel loro libro, "Growing Object-Oriented Software, guidato dai test" (Addison-Wesley Professional, 2009), nota che "tradizionale" TDD perde alcuni dei vantaggi della vero prova-primo sviluppo:

È forte la tentazione di avviare il processo di TDD tramite la scrittura di unit test per le classi nell'applicazione. Questo è meglio che non avere nessun test a tutti e può intercettare tali errori di programmazione base che tutti conosciamo ma trova così difficile da evitare... Ma un progetto con solo unit test è mancante su prestazioni critiche del processo TDD. Abbiamo visto progetti di alta qualità, ben collaudato unità che non siano attivate fuori per essere chiamato da qualsiasi punto del codice, o che non potrebbe essere integrato con il resto del sistema e doveva essere riscritta."

Nel 2006, Dan North documentato molte di queste sfide in un articolo di Software migliore rivista ( blog.dannorth.net/introducing-bdd ). Nel suo articolo, North descritta una serie di pratiche che aveva adottato nel corso della prima tre anni mentre in trincea con test. Mentre ancora TDD per definizione, queste pratiche Nord hanno portato ad adottare una visione più incentrata su analisi di test e a coniare il termine sviluppo Behavior-Driven per incapsulare questo spostamento.

Una applicazione popolare di BDD tenta di estendere TDD stringendo il fuoco e il processo di creazione di test attraverso test di accettazione, o eseguibile specifiche. Ogni specifica serve come punto di ingresso nel ciclo di sviluppo e, dal punto di vista dell'utente e in forma dettagliata, descrive come deve comportarsi il sistema. Una volta scritto, lo sviluppatore utilizza le specifiche e il loro processo di TDD esistente per implementare il codice di produzione appena sufficiente per produrre uno scenario di passaggio (vedi di Figura 2).

image: The Behavior-Driven Development Cycle

Figura 2 del ciclo di sviluppo basati sul comportamento

Dove inizia la progettazione

BDD è considerato da molti un superset di TDD, non una sostituzione per esso. La differenza fondamentale è l'accento sulla creazione di test e progettazione iniziale. Piuttosto che concentrarsi su prove contro unità o oggetti, come con TDD, focalizzata sul conseguimento degli obiettivi dei miei utenti e i passaggi che adottano per conseguire tali obiettivi. Perché non sto iniziando con prove di piccole unità, sono meno inclinato a speculare su specifici dettagli di utilizzo o di progettazione. Piuttosto, sto documentando specifiche eseguibile dimostrare che fuori il mio sistema. Ancora scrivere unit test, ma BDD incoraggia un approccio in esterno che inizia con una descrizione completa della funzionalità per essere attuate.

Esaminiamo un esempio della differenza. In una pratica tradizionale TDD, si potrebbe scrivere il test in Figura 3 per esercitare il metodo di creazione di un CustomersController di .

Figura 3 di Unit Test per la creazione di un cliente

[TestMethod]
public void PostCreateShouldSaveCustomerAndReturnDetailsView() {
  var customersController = new CustomersController();
  var customer = new Customer {
    Name = "Hugo Reyes",
    Email = "hreyes@dharmainitiative.com",
    Phone = "720-123-5477" 
  };

  var result = customersController.Create(customer) as ViewResult;

  Assert.IsNotNull(result);
  Assert.AreEqual("Details", result.ViewName);
  Assert.IsInstanceOfType(result.ViewData.Model, typeof(Customer));

  customer = result.ViewData.Model as Customer;
  Assert.IsNotNull(customer);
  Assert.IsTrue(customer.Id > 0);
}

Con TDD, questo tende ad essere uno dei test primo di che scrivere. Progettazione impostando le aspettative di come comporterà un'API pubblica al mio oggetto di CustomersController. Con BDD ancora creare tale test, ma non in un primo momento. Invece, elevare la messa a fuoco a funzionalità a livello di funzionalità scrivendo qualcosa di più simile a di Figura 4. Quindi utilizzare tale scenario come orientamento verso l'implementazione di ogni unità di codice necessari per rendere questo scenario di passare.

Figura 4 specifica caratteristica-Level

Feature: Create a new customer
  In order to improve customer service and visibility
  As a site administrator
  I want to be able to create, view and manage customer records

Scenario: Create a basic customer record
  Given I am logged into the site as an administrator
  When I click the "Create New Customer" link
  And I enter the following information
    | Field | Value                       |
    | Name  | Hugo Reyes                  |
    | Email | hreyes@dharmainitiative.com |
    | Phone | 720-123-5477                |
  And I click the "Create" button
  Then I should see the following details on the screen:
    | Value                       |
    | Hugo Reyes                  |
    | hreyes@dharmainitiative.com |
    | 720-123-5477                |

Questo è il ciclo esterno in Figura 2 , la mancanza di Test di accettazione. Una volta che questo test è stato creato e non riesce, implementare ogni passaggio di ogni scenario nella mia caratteristica seguendo il ciclo interno TDD raffigurato in di Figura 2. Nel caso della CustomersController in di Figura 3, I'll scrivere questo test una volta raggiungere il corretto passaggio nella mia funzione, ma prima implementare la logica di controller necessaria per fare quel passo a passare.

BDD e test automatizzati

Fin dall'inizio, la Comunità BDD ha cercato di fornire lo stesso livello di test automatizzati con test di accettazione che è stata la norma in unit test per qualche tempo. Un esempio notevole è il cetriolo ( cukes.info ), uno strumento di test basato su Ruby che enfatizza la creazione del livello di funzionalità di test di accettazione scritta in un linguaggio"business-leggibile, specifici del dominio".

Test di cetriolo sono scritti utilizzando la sintassi del brano utente per ogni file di funzionalità e un dato, quando, sintassi quindi (GWT) per ogni scenario. (Per ulteriori informazioni sulla sintassi di storia di utente, vedere c2.com/cgi/wiki?UserStory.) GWT descrive il contesto corrente dello scenario (dato), le azioni intraprese, come parte del test (quando) e i risultati attesi, osservabili (allora). La funzione di di Figura 4 è un esempio di tale sintassi.

File leggibile dall'utente funzionalità vengono analizzati cetriolo, e ogni passo scenario corrisponde a codice Ruby che esercita sulle interfacce pubbliche del sistema in questione e determina se tale passaggio passa o fallisce.

Negli ultimi anni, hanno esteso le innovazioni che consente l'uso di scenari di test automatizzati nella.NET Framework ecosistema. Gli sviluppatori hanno ora gli strumenti che consentono di specifiche devono essere scritti utilizzando lo stesso strutturato sintassi inglese che utilizza cetriolo, e che può quindi utilizzare tali specifiche come test che esercitare il codice. BDD test strumenti come SpecFlow ( specflow.org ), Cuke4Nuke ( github.com/richardlawrence/Cuke4Nuke ) e gli altri consentono di creare specifiche eseguibile prima del processo, sfruttare tali specifiche, come si compila funzionalità e terminano con una feature di documentate che è legata direttamente al vostro sviluppo e il processo di testing.

Guida introduttiva a SpecFlow e WatiN

In questo articolo, potrai utilizzare SpecFlow per testare un'applicazione MVC (Model-View-Controller). Per iniziare con SpecFlow, sarà prima necessario scaricarlo e installarlo. Una volta installato SpecFlow, creare un nuovo ASP.Applicazione MVC NET con un progetto di unit test. Preferisco che il mio progetto di unit test contengono solo unit test (test del controller, prove di repository e così via), in modo da creare anche un progetto di test AcceptanceTests per i miei test SpecFlow.

Dopo aver aggiunto un progetto AcceptanceTests e aggiunto i riferimenti all'assembly TechTalk.SpecFlow, aggiungere una nuova funzionalità utilizzando Add | Nuovi modelli di elemento che crea su installazione SpecFlow e il nome CreateCustomer.feature.

Si noti che viene creato il file con estensione .feature, e lo riconosce come un file supportato, grazie alla utensileria integrato del SpecFlow da Visual Studio. Si può anche notare che il tuo file caratteristica ha un file di code-behind CS correlati. Ogni volta che si salva un file .feature, SpecFlow, analizza il file e converte il testo in tale file in un apparecchio di prova. Il codice nel file CS associati rappresenta quell'apparecchio di prova, che è il codice che ha effettivamente eseguito ogni volta che si esegue la suite di test.

Per impostazione predefinita, SpecFlow utilizza NUnit come sua prova-runner, ma supporta anche MSTest con una modifica di configurazione semplice. Tutto quello che devi fare è aggiungere un file app.config al progetto di test e aggiungere i seguenti elementi:

<configSections>
  <section name="specFlow"
    type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow"/>
</configSections>
<specFlow>
  <unitTestProvider name="MsTest" />
</specFlow>

Il primo Test di accettazione

Quando si crea una nuova funzione, SpecFlow compila il file con il testo predefinito per illustrare la sintassi utilizzata per descrivere una caratteristica. Sostituire il testo predefinito nel file CreateCustomer.feature con il testo in di Figura 4.

Ogni file di funzionalità consta di due parti. La prima parte è il nome della feature e descrizione nella parte superiore, che utilizza la sintassi User Story per descrivere il ruolo dell'utente, obiettivo dell'utente e i tipi di cose, che l'utente deve essere in grado di fare per raggiungere tale obiettivo nel sistema. In questa sezione è richiesta da SpecFlow per generare automaticamente i test, ma il contenuto non viene utilizzato in tali test.

La seconda parte di ogni file di funzionalità è uno o più scenari. Ogni scenario viene utilizzato per generare un metodo di test in associati. feature.cs file, come illustrato in di Figura 5 e ogni passo all'interno di uno scenario viene passato per il corridore di prova SpecFlow, che esegue una corrispondenza basata su RegEx del passaggio a una voce in un file di SpecFlow chiamato un file di definizione del passo.

Figura 5 metodo di Test generato da SpecFlow

public virtual void CreateABasicCustomerRecord() {
  TechTalk.SpecFlow.ScenarioInfo scenarioInfo = 
    new TechTalk.SpecFlow.ScenarioInfo(
    "Create a basic customer record", ((string[])(null)));

  this.ScenarioSetup(scenarioInfo);
  testRunner.Given(
    "I am logged into the site as an administrator");
  testRunner.When("I click the \"Create New Customer\" link");

  TechTalk.SpecFlow.Table table1 = 
    new TechTalk.SpecFlow.Table(new string[] {
    "Field", "Value"});
  table1.AddRow(new string[] {
    "Name", "Hugo Reyesv"});
  table1.AddRow(new string[] {
    "Email", "hreyes@dharmainitiative.com"});
  table1.AddRow(new string[] {
    "Phone", "720-123-5477"});

  testRunner.And("I enter the following information", 
    ((string)(null)), table1);
  testRunner.And("I click the \"Create\" button");

  TechTalk.SpecFlow.Table table2 = 
   new TechTalk.SpecFlow.Table(new string[] {
  "Value"});
  table2.AddRow(new string[] {
    "Hugo Reyes"});
  table2.AddRow(new string[] {
    "hreyes@dharmainitiative.com"});
  table2.AddRow(new string[] {
    "720-123-5477"});
  testRunner.Then("I should see the following details on screen:", 
    ((string)(null)), table2);
  testRunner.CollectScenarioErrors();
}

Una volta aver definito la prima feature, premere Ctrl + R, T per eseguire il test di SpecFlow. Il test di CreateCustomer riuscirà come inconcludente perché SpecFlow non riesce a trovare una corrispondente definizione di passaggio per il primo passo nel test (vedi di Figura 6). Si noti come l'eccezione viene segnalato nel file .feature effettivo, a differenza del file code-behind.

image: SpecFlow Cannot Find a Step Definition

Figura 6 SpecFlow non riesce a trovare una definizione di passaggio

Perché lei non ha ancora creato un file di definizione del passo, questa eccezione è prevista. Fare clic su OK nella finestra di dialogo eccezioni e cercare la prova di CreateABasicCustomerRecord nella finestra dei risultati di prova di Visual Studio. Se non viene trovato un passaggio corrispondente, SpecFlow utilizza file di funzionalità per generare il codice che necessario nel tuo file di definizione del passo, che è possibile copiare e utilizzare per avviare l'attuazione di tali misure.

Nel progetto AcceptanceTests, creare un file di definizione del passaggio utilizzando il modello di definizione del passo di SpecFlow e il nome CreateCustomer.cs. Quindi copiare l'output da SpecFlow nella classe. Si noterà che ogni metodo è decorato con un attributo SpecFlow che designa il metodo come un dato, quando o quindi passo e fornisce che la RegEx utilizzato per associare il metodo a un passaggio nel file di funzionalità.

Integrazione di WatiN per il Browser test

Parte dell'obiettivo con BDD è quello di creare una suite di test automatizzati che esercita tanto funzionalità end-to-end sistema possibile. Perché sto costruendo un ASP.Applicazione MVC NET, posso utilizzare strumenti che consentono di creare uno script al browser Web di interagire con il sito.

Una tale strumento è WatiN, una libreria open source per l'automazione di test del Web browser. È possibile scaricare WatiN da watin.sourceforge.net e aggiungere un riferimento a WatiN.Core per il progetto di test di accettazione di utilizzarlo.

Il modo principale di interagire con WatiN è attraverso un oggetto browser — o IE() o FireFox(), a seconda del browser di scelta — che fornisce un'interfaccia pubblica per controllare un'istanza di un browser installato. Perché avete bisogno di camminare il browser attraverso diversi passaggi in uno scenario, è necessario un modo per passare lo stesso oggetto browser tra i passaggi nella classe di definizione di passaggio. Per gestire questa situazione, solitamente creare una classe statica WebBrowser come parte del progetto AcceptanceTests e utilizzare tale classe per lavorare con l'oggetto WatiN IE e il ScenarioContext che SpecFlow utilizza per memorizzare lo stato tra i passaggi in uno scenario:

public static class WebBrowser {
  public static IE Current {
    get {
      if (!ScenarioContext.Current.ContainsKey("browser"))
        ScenarioContext.Current["browser"] = new IE();
      return ScenarioContext.Current["browser"] as IE;
    }
  }
}

Il primo passo che è necessario per implementare in CreateCustomer.cs è il passo determinato, che inizia il test di registrazione dell'utente al sito come amministratore:

[Given(@"I am logged into the site as an administrator")]
public void GivenIAmLoggedIntoTheSiteAsAnAdministrator() {
  WebBrowser.Current.GoTo(http://localhost:24613/Account/LogOn);

  WebBrowser.Current.TextField(Find.ByName("UserName")).TypeText("admin");
  WebBrowser.Current.TextField(Find.ByName("Password")).TypeText("pass123");
  WebBrowser.Current.Button(Find.ByValue("Log On")).Click();

  Assert.IsTrue(WebBrowser.Current.Link(Find.ByText("Log Off")).Exists);
}

Ricordate che la parte di uno scenario è per l'impostazione del contesto del test corrente. Con WatiN, puoi avere il tuo test drive e interagire con il browser per implementare questo passaggio.

Per eseguire questa operazione, utilizzare WatiN per aprire Internet Explorer, passare alla pagina di accesso del sito, compilare il nome utente e la Password di caselle di testo e fare clic sul pulsante Log On sullo schermo. Quando eseguire nuovamente il test, una finestra di Internet Explorer si aprirà automaticamente e io posso osservare WatiN in azione come interagisce con il sito, facendo clic sul link e immissione di testo (vedere di Figura 7).

image: The Browser on Autopilot with WatiN

Figura 7 Browser su autopilota con WatiN

Passerà il determinato passaggio e io sono un passo più vicini all'implementazione della funzionalità. SpecFlow sarà ora fail su quando il primo passo perché il passo non è stato ancora implementato. È possibile implementarlo con il seguente codice:

[When("I click the \" (.*)\" link")]
public void WhenIClickALinkNamed(string linkName) {
  var link = WebBrowser.Link(Find.ByText(linkName));

  if (!link.Exists)
    Assert.Fail(string.Format(
      "Could not find {0} link on the page", linkName));

  link.Click();
}

Ora, quando si esegue il test nuovamente, riescono perché WatiN non riesce a trovare un link con il testo "Crea nuovo cliente" sulla pagina. Semplicemente aggiungendo un link con il testo alla pagina iniziale, si passerà al passaggio successivo.

Un modello di rilevamento ancora? SpecFlow incoraggia la stessa metodologia rosso-verde-refactoring che è un caposaldo dei metodi di prova-primo sviluppo. La granularità di ogni passaggio in una funzione agisce come paraocchi virtuale per l'attuazione, incoraggiando di implementare solo le funzionalità che è necessario fare quel passo a passare.

Ma che cosa circa TDD all'interno di BDD processo? Sto lavorando solo a livello di pagina a questo punto, e devo ancora implementare la funzionalità che consente di creare effettivamente il record del cliente. Per ragioni di brevità, Let's implementare il resto dei passaggi ora (vedi di Figura 8).

Figura 8 di passaggi rimanenti nella definizione del passo

[When(@"I enter the following information")]
public void WhenIEnterTheFollowingInformation(Table table) {
  foreach (var tableRow in table.Rows) {
    var field = WebBrowser.TextField(
      Find.ByName(tableRow["Field"]));

    if (!field.Exists)
      Assert.Fail(string.Format(
        "Could not find {0} field on the page", field));
    field.TypeText(tableRow["Value"]);
  }
}

[When("I click the \"(.*)\" button")]
public void WhenIClickAButtonWithValue(string buttonValue) {
  var button = WebBrowser.Button(Find.ByValue(buttonValue));

  if (!button.Exists)
    Assert.Fail(string.Format(
      "Could not find {0} button on the page", buttonValue));

  button.Click();
}

[Then(@"I should see the following details on the screen:")]
public void ThenIShouldSeeTheFollowingDetailsOnTheScreen(
  Table table) {
  foreach (var tableRow in table.Rows) {
    var value = tableRow["Value"];

    Assert.IsTrue(WebBrowser.ContainsText(value),
      string.Format(
        "Could not find text {0} on the page", value));
  }
}

Nuovamente i miei test, e ora le cose non riescono perché non si dispone di una pagina per immettere le informazioni di cliente. Per consentire ai clienti di essere creato, ho bisogno di una pagina Create View Customer. Al fine di realizzare tale visione in ASP.NET MVC, ho bisogno di un CustomersController che offre tale punto di vista. Ora ho bisogno di nuovo codice, il che significa che sto stepping dal ciclo esterno di BDD e in loop interno di TDD, come mostrato nel di Figura 2.

Il primo passo è quello di creare una mancanza unit test.

Scrittura di Unit test per implementare passaggi

Dopo aver creato una classe di test CustomerControllersTests nel progetto UnitTest, è necessario creare un metodo di prova che esercita la funzionalità per essere esposti nella CustomersController. In particolare, si desidera creare una nuova istanza del Controller, chiamare il metodo Create e assicurarsi di ricevere in cambio la corretta visualizzazione e il modello:

[TestMethod]
public void GetCreateShouldReturnCustomerView() {
  var customersController = new CustomersController();
  var result = customersController.Create() as ViewResult;

  Assert.AreEqual("Create", result.ViewName);
  Assert.IsInstanceOfType(
    result.ViewData.Model, typeof(Customer));
}

Questo codice non compila ancora perché non hai creato CustomersController o il metodo Create. Al momento della creazione che il controller e un metodo Create vuoto, il codice viene compilato, e ora il test fallisce, che è il passo successivo desiderato. Se si completa il metodo Create, ora passa il test:

public ActionResult Create() {
  return View("Create", new Customer());
}

Se si esegue nuovamente il test di SpecFlow, si ottiene un po' ulteriormente, ma non passa ancora la caratteristica. Questa volta, il test avrà esito negativo perché non si dispone di una pagina di visualizzazione Create.aspx. Se si aggiunge con campi appropriati come diretto dalla funzionalità, potrai spostare un altro passo avanti una feature completata.

Il processo esterno per implementare questa funzionalità Create osserva qualcosa come di Figura 9.

image: Scenario-to-Unit Test Process

Figura 9 di Scenario a unità di processo di Test

Questi stessi passaggi si ripetono spesso in questo processo, e la velocità nell'iterazione li aumenterà notevolmente nel corso del tempo, specialmente come implementare misure di supporto (facendo clic su collegamenti e pulsanti, compilazione di moduli e così via) nel progetto AcceptanceTests e scendere per testare la funzionalità chiave in ogni scenario.

Da un valido Create View, la funzionalità sarà ora compilare i campi del modulo appropriato e tenterà di inviare il modulo. Da ora potete indovinare che cosa succede dopo: Il test avrà esito negativo perché non hai ancora la logica necessaria per salvare il record del cliente.

In seguito lo stesso processo come prima, creare la prova utilizzando il codice di unit test illustrato in precedenza in di Figura 3. Dopo l'aggiunta di un metodo Create vuoto che accetta un oggetto customer per consentire questo test compilare, guardate non riescono, quindi completa il metodo Create come così:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Customer customer) {
  _repository.Create(customer);

  return View("Details", customer);
}

Mio Controller è solo una, e l'effettiva creazione del record del cliente appartiene a un oggetto del Repository che è a conoscenza di un meccanismo di archiviazione dei dati. Ho lasciato che l'attuazione di questo articolo per brevità, ma è importante notare che, in uno scenario reale, la necessità di un repository salvare un cliente dovrebbe avviare un'altra sottorete di unit test. Quando è necessario l'accesso a qualsiasi oggetto di collaborazione e di quell'oggetto non esiste ancora, o non offre la funzionalità necessaria, si dovrebbe seguire lo stesso ciclo di test di unità che sei seguenti per la funzionalità e il controller.

Dopo aver implementato il metodo Create e dispone di un repository di lavoro, è necessario creare la visualizzazione dei dettagli, che prende il nuovo record del cliente e lo visualizza nella pagina. È quindi possibile eseguire SpecFlow ancora una volta. Infine, dopo molti cicli di TDD e sottoreti, ora avete una funzione di passaggio che dimostra fuori alcune funzionalità end-to-end nel vostro sistema.

Complimenti! Ora aver implementato un'unità di funzionalità end-to-end con un test di accettazione e un set completo di unit test che garantirà la nuova funzionalità continuerà a funzionare come il sistema si espande per aggiungere nuove funzionalità.

Una parola circa il Refactoring

Speriamo che, come si crea il test di livello di unità nel progetto UnitTests, sta costantemente refactoring con ogni creazione di test. Come ci si sposta indietro fino alla catena dal passaggio di unit test a un accettazione di passaggio test, è necessario seguire lo stesso processo, guardando per opportunità refactoring e perfezionare l'implementazione per ogni caratteristica e tutte le caratteristiche che vengono dopo.

Essere alla ricerca di opportunità di refactoring di codice nel progetto di AcceptanceTests pure. Troverete che tendono a essere ripetuto spesso attraverso diverse funzionalità, soprattutto i passi dato alcuni passaggi. Con SpecFlow, è possibile spostare facilmente questi passaggi in file separati di passo Definition organizzati dalla funzione, ad esempio LogInSteps.cs. Questo lascia i file di definizione del passo principali pulito e mirato allo scenario unico che si specifica.

BDD è circa lo stato attivo nella progettazione e nello sviluppo. Elevare il vostro fuoco da un oggetto a una feature, consente te e la tua squadra per la progettazione dal punto di vista dell'utente di un sistema. Funzionalità di progettazione diventa la progettazione di unità, assicurarsi di autore test con la funzionalità nella mente e assicurare che le prove sono guidate da operazioni discrete o attività.

Come qualsiasi altra pratica o disciplina, BDD richiede tempo per adattarsi nel flusso di lavoro. Invitiamo a provarlo voi stessi, usando uno degli strumenti disponibili e vedere come funziona nel tempo. Come si sviluppano in questo stile, attenzione alle domande che BDD ti incoraggia a chiedere. Costantemente mettere in pausa e cercare modi per migliorare la vostra pratica e il processo e collaborare con altri utenti su idee per il miglioramento. La mia speranza è che, non importa il tuo set di strumenti, lo studio di BDD aggiunge valore e attenzione alla propria pratica di sviluppo software.

Brandon Satrom funziona come un evangelista dello sviluppatore per Microsoft in Austin, Texas. Blog di userinexperience.com e può essere trovato su Twitter come @ BrandonSatrom.

Grazie ai seguenti esperti per refviewing questo articolo: Paul Rayner e vendere di Clark