Este artigo foi traduzido por máquina.

Prévia do BDD

Desenvolvimento controlado por comportamento com o SpecFlow e o WatiN

Brandon Satrom

Baixe o código de exemplo

Como testes de unidade automatizada torna-se mais onipresente no desenvolvimento de software, o mesmo acontece com a adopção de vários métodos de teste primeiro. Estas práticas apresentam um conjunto único de oportunidades e desafios para as equipes de desenvolvimento, mas todos nos esforçamos para estabelecer uma mentalidade "teste como design" com os profissionais.

Durante grande parte da era do primeiro teste, no entanto, o método para expressar o comportamento de um usuário tem sido através da unidade testes escritos na linguagem do sistema — uma linguagem desconectada do que do usuário. Com o advento das técnicas de desenvolvimento de Behavior-Driven (BDD), essa dinâmica está mudando. Usando técnicas BDD, que você pode criar automatizado testes na linguagem dos negócios, ao mesmo tempo em que mantém uma conexão ao seu sistema implementado.

É claro, várias ferramentas foram criadas para ajudá-lo a implementar o BDD no seu processo de desenvolvimento. Estes incluem pepino em Ruby e SpecFlow e WatiN para a Microsoft.NET Framework. SpecFlow ajuda-a escrever e executar especificações dentro do Visual Studio, enquanto WatiN permite conduzir o navegador para testes de sistema automatizado de ponta a ponta.

Neste artigo, vou fornecer uma visão geral do BDD e, em seguida, explique como o ciclo BDD envolve o tradicional ciclo de Test-Driven Development (TDD) com testes de nível de recurso que nível de unidade a unidade de execução. Uma vez que eu preparei o terreno para os métodos de teste-primeiro, vou introduzir SpecFlow e WatiN e mostram exemplos de como estas ferramentas podem ser usadas com MSTest para implementar o BDD para seus projetos.

Uma breve história de teste automatizado

Uma das práticas mais valiosas a emergir do movimento de Software ágil é um estilo de desenvolvimento automatizado, teste-primeiro, muitas vezes referido como Test-Driven Development ou TDD. Um princípio fundamental do TDD é que criação de teste é tanto sobre orientações de design e desenvolvimento, uma vez é sobre a verificação e regressão. Trata-se também usar o teste para especificar uma unidade de funcionalidade necessária e usando esse teste para, em seguida, escreva apenas o código necessário para fornecer essa funcionalidade. Portanto, a primeira etapa na implementação de qualquer nova funcionalidade é descrever as suas expectativas com uma falha teste (veja de Figura 1).

Figura 1 do ciclo de desenvolvimento orientado a testes

Muitos desenvolvedores e equipes têm tido grande sucesso com TDD. Outros não e achar que eles lutam com o gerenciamento do processo ao longo do tempo, especialmente porque o volume de testes começa a crescer e a flexibilidade desses testes começa a cair. Alguns não tem certeza de como iniciar com TDD, enquanto outros acham TDD fácil iniciar, só para assistir abandonado como prazos pendências próximo e grandes tear. Finalmente, muitos desenvolvedores interessados encontram resistência para a prática em suas organizações, quer porque a palavra "teste" implica uma função que pertence a outra equipe ou devido a falsa percepção que TDD resulta em muito código extra e diminui a projetos.

Steve Freeman e Nat Pryce, em seu livro, "Growing Object-Oriented Software, guiados por testes" (Addison-Wesley Professional, 2009), nota que "tradicional" TDD perde alguns dos benefícios do verdadeiro desenvolvimento de teste-primeiro:

"É tentador para iniciar o processo de TDD, escrevendo testes de unidade para classes no aplicativo. Isso é melhor do que não ter nenhum teste de todo e pode pegar esses erros de programação básicos que todos sabemos mas encontrar tão difícil evitar... Mas um projeto com testes de unidade só está faltando para fora em benefícios essenciais do processo de TDD. Já vimos projetos com alta qualidade, bem testado de unidade que não virou fora a ser chamado de qualquer parte do código, ou que não poderia ser integrada com o resto do sistema e teve que ser reescrito."

Em 2006, Dan Norte documentado muitos desses desafios em um artigo em Melhor Software revista ( blog.dannorth.net/introducing-bdd ). Em seu artigo, Norte descreveu uma série de práticas que ele tinha adoptado sobre a prévia três anos em trincheiras com testes. Enquanto ainda TDD por definição, estas práticas Norte levaram a adoptar uma visão mais centrada em análise de testes e a cunhar o termo desenvolvimento de Behavior-Driven para encapsular essa mudança.

Um aplicativo popular do BDD tenta estender TDD apertando o foco e o processo de criação de testes através de testes de aceitação ou especificações executáveis. Cada especificação serve como um ponto de entrada para o ciclo de desenvolvimento e descreve, do ponto de vista do usuário e de forma passo a passo, como o sistema deve se comportar. Uma vez escrito, o desenvolvedor usa a especificação e o seu processo de TDD existente para implementar apenas o suficiente código de produção para produzir um cenário de passagem (veja de Figura 2).

Figura 2 do ciclo de desenvolvimento controlado por comportamento

Onde começa a Design

BDD é considerado por muitos um superconjunto do TDD, não um substituto para ele. A principal diferença é o foco na criação de design e teste inicial. Em vez de se concentrar nos testes contra unidades ou objetos, com TDD, me concentrar nos objectivos dos meus usuários e as etapas para atingir essas metas. Porque eu já não estou começando com testes de pequenas unidades, eu sou menos inclinado a especular sobre detalhes de uso ou design refinados. Em vez disso, eu estou documentando especificações executáveis que provam meu sistema. Eu ainda escrever testes de unidade, mas BDD encoraja uma abordagem de fora que começa com uma descrição completa do recurso para ser implementada.

Vejamos um exemplo da diferença. Em uma tradicional prática de TDD, você pode escrever o ensaio em Figura 3 para exercer o método Create de um CustomersController.

Figura 3 de teste de unidade para a criação de um 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);
}

Com TDD, isso tende a ser um dos primeiros testes que eu escrevo. Eu desenho uma API pública ao meu objeto de CustomersController definindo as expectativas de como ela vai se comportar. Com BDD ainda criar esse teste, mas não em primeiro lugar. Em vez disso, eu elevar o foco ao nível de recurso funcionalidade, escrever algo mais como de Figura 4. Em seguida, utilizo esse cenário como orientação para a implementação de cada unidade de código necessário para fazer este cenário passar.

Figura 4 de especificação de nível de recurso

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                |

Este é o loop externo em Figura 2 , a falha teste de aceitação. Uma vez que este teste foi criado e falha, implementar cada etapa de cada cenário em meu recurso seguindo o loop interno de TDD retratado em de Figura 2. Em caso de CustomersController em de Figura 3, eu vou escrever este teste assim que eu chegar a etapa adequada no meu recurso, mas antes de implementar a lógica de controlador necessária para dar esse passo passar.

BDD e testes automatizados

Desde o início, a Comunidade BDD procurou oferecer o mesmo nível de teste automatizado com testes de aceitação que tem sido a norma na unidade de testes por algum tempo. Um exemplo notável é o pepino ( cukes.info ), uma ferramenta de teste baseado em Ruby que enfatiza a criação de testes de aceitação de nível de recurso escrito em um "negócio legível, domain-specific language."

Pepino testes são escritos usando a sintaxe de história de usuário para cada arquivo de recurso e um dado, quando, em seguida, (GWT) sintaxe para cada cenário. (Para obter detalhes sobre a sintaxe da história de usuário, consulte c2.com/cgi/wiki?UserStory.) GWT descreve o contexto atual do cenário (dado), as medidas tomadas como parte do ensaio (quando) e os resultados esperados, observáveis (então). O recurso em de Figura 4 é um exemplo de tal sintaxe.

Em pepino, os arquivos de recurso legível pelo usuário são analisados e cada etapa de cenário é correspondente ao código Ruby que exerce as interfaces públicas do sistema em questão e determina se essa etapa passa ou falha.

Nos últimos anos, inovações, permitindo o uso de cenários como testes automatizados estenderam-se na.NET Framework ecossistema. Os desenvolvedores agora têm ferramentas que permitem que as especificações a serem gravados usando a mesma estruturado sintaxe inglês que utiliza de pepino, e que, em seguida, pode usar essas especificações como testes que exercem o código. BDD Testando ferramentas como o SpecFlow ( specflow.org ), Cuke4Nuke ( github.com/richardlawrence/Cuke4Nuke ) e outros permitem que você criar especificações executáveis pela primeira vez no processo, aproveitar essas especificações como construir funcionalidade e terminar com um recurso documentado que está ligado diretamente ao seu desenvolvimento e o processo de teste.

Introdução ao SpecFlow e WatiN

Neste artigo, eu vou utilizar SpecFlow para testar um aplicativo MVC (Model-View-Controller). Para começar com SpecFlow, você precisa primeiro fazer o download e instalá-lo. Uma vez SpecFlow é instalado, crie um novo ASP.NET MVC aplicativo com um projeto de teste de unidade. Eu prefiro que meu projeto de teste de unidade contêm somente testes de unidade (controlador de testes, testes de repositório e assim por diante), então também de criar um projeto de teste de AcceptanceTests para meus testes de SpecFlow.

Depois de adicionado um projeto de AcceptanceTests e adicionadas referências para o assembly TechTalk.SpecFlow, adiciona um novo recurso usando o Adicionar | Novos modelos de Item que SpecFlow cria na instalação e nomeie-CreateCustomer.feature.

Observe que o arquivo é criado com uma extensão de .feature, e que Visual Studio reconhece isso como um arquivo com suporte, graças a ferramentas integradas do SpecFlow. Você também pode observar que o arquivo de recurso tem um arquivo de code-behind relacionados. CS. Cada vez que você salva um arquivo de .feature, SpecFlow analisa o arquivo e converte o texto desse arquivo em um suporte de ensaio. O código no arquivo associado. CS representa esse suporte, que é o código que realmente executado cada vez que executar o pacote de teste.

Por padrão, SpecFlow usa NUnit como seu executor de teste, mas também suporta MSTest com uma alteração de configuração simples. Tudo que você precisa fazer é adicionar um arquivo app. config para seu projeto de teste e adicione os seguintes elementos:

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

O primeiro teste de aceitação

Quando você cria um novo recurso, SpecFlow preenche esse arquivo com texto padrão para ilustrar a sintaxe usada para descrever um recurso. Substitua o texto padrão no seu arquivo CreateCustomer.feature com o texto em de Figura 4.

Cada arquivo de recurso tem duas partes. A primeira parte é o nome do recurso e a descrição na parte superior, que usa a sintaxe de história de usuário para descrever a função do usuário, objetivo do usuário e os tipos de coisas que o usuário precisa ser capaz de fazer para alcançar esse objetivo no sistema. Esta seção é exigida pela SpecFlow para geração automática de testes, mas o conteúdo propriamente dito não é usado em desses testes.

A segunda parte de cada arquivo de recurso é um ou mais cenários. Cada cenário é usado para gerar um método de teste na associada. feature.cs arquivo, conforme mostrado em de Figura 5 e cada passo dentro de um cenário é passado para o corredor de teste SpecFlow, que faz a correspondência baseada em RegEx de etapa para uma entrada em um arquivo de SpecFlow chamado arquivo de definição de passo.

Método de ensaio de Figura 5 gerado pelo 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();
}

Uma vez que você definiu seu primeiro longa, pressione Ctrl + R, T para executar os testes de SpecFlow. O teste de CreateCustomer irá falhar como inconclusivo porque SpecFlow não é possível encontrar uma definição de etapa correspondente para a primeira etapa no seu teste (veja de Figura 6). Observe como a exceção é relatada no arquivo .feature real, ao contrário do arquivo code-behind.

image: SpecFlow Cannot Find a Step Definition

Figura 6 do SpecFlow não é possível encontrar uma definição de etapa

Porque você ainda não criou um arquivo de definição de etapa, essa exceção é esperada. Clique em OK na caixa de diálogo de exceção e olhar para o teste de CreateABasicCustomerRecord na janela de resultados de teste do Visual Studio. Se uma etapa correspondente não for encontrada, o SpecFlow usa seu arquivo de recurso para gerar o código que você precisa em seu arquivo de definição de passo, que você pode copiar e usar para iniciar a execução dessas etapas.

Em seu projeto de AcceptanceTests, criar um arquivo de definição de passo usando o modelo de definição de etapa de SpecFlow e o nome CreateCustomer.cs. Em seguida, copie a saída de SpecFlow para a classe. Você notará que cada método é decorado com um atributo de SpecFlow que designa o método como um dado, quando ou então passo e fornece que a RegEx usado para coincidir com o método para uma etapa no arquivo de recurso.

Integração de WatiN para teste de navegador

Parte da meta com BDD é criar um conjunto de testes automatizados que exerce tanta funcionalidade de ponta a ponta sistema quanto possível. Porque eu estou construindo um ASP.NET MVC aplicativo, posso usar ferramentas que ajudam o navegador da Web para interagir com o site de script.

Uma dessas ferramentas é WatiN, uma biblioteca de código aberto para automação de teste de navegador da Web. Você pode baixar WatiN de watin.sourceforge.net e adicionar uma referência a WatiN.Core ao seu projeto de testes de aceitação para usá-lo.

A principal maneira de interagir com WatiN é por meio de um objeto de navegador — IE() ou FireFox(), dependendo do navegador de escolha — que fornece uma interface pública para controlar uma instância de um navegador instalado. Porque você precisa andar o navegador por meio de várias etapas em um cenário, você precisa uma maneira de passar o mesmo objeto de navegador entre as etapas em passo definição de classe. Para lidar com isso, eu costumo criar uma classe estática do navegador da Web como parte do meu projeto de AcceptanceTests e usar essa classe para trabalhar com o objeto de WatiN IE e o ScenarioContext que SpecFlow usa para armazenar o estado entre as etapas em um cenário:

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;
    }
  }
}

A primeira etapa que será necessário implementar em CreateCustomer.cs é o passo dado, que começa o teste através do login do usuário no site como administrador:

[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);
}

Lembre-se que a determinada parte de um cenário é para a criação do contexto do teste atual. Com WatiN, você pode ter seu test drive e interagir com o navegador para implementar esta etapa.

Para esta etapa, uso WatiN para abrir o Internet Explorer, navegue até a página de logon do site, preencha o nome de usuário e senha caixas de texto e, em seguida, clique no botão Log On no ecrã. Quando eu executar os testes novamente, uma janela do Internet Explorer abrirá automaticamente e posso observar WatiN em ação como ele interage com o site, clicar em links e inserir texto (veja de Figura 7).

A Figura 7 O navegador no piloto automático com WatiN

O passo dado agora vai passar e eu sou um passo mais perto para implementar o recurso. SpecFlow vai agora falha no primeiro quando passo porque a etapa ainda não está implementada. Você pode implementá-lo com o seguinte código:

[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();
}

Agora, quando eu executar os testes novamente, eles falham porque WatiN não pode encontrar um link com o texto "Criar novo cliente" na página. Simplesmente adicionando um link com esse texto para a página inicial, o próximo passo vai passar.

Sentindo um padrão ainda? SpecFlow encoraja a mesma metodologia de vermelho-verde-Refatorar é um grampo de métodos de teste-primeiro desenvolvimento. A granularidade de cada etapa em um recurso funciona como virtuais antolhos para implementação, incentivando a implementação somente a funcionalidade que você precisa para dar esse passo passar.

Mas o que sobre TDD dentro do BDD processar? Eu só estou trabalhando no nível da página neste momento e eu ainda tenho que implementar a funcionalidade que realmente cria o registro do cliente. Por uma questão de brevidade, vamos implementar o resto das etapas agora (veja de Figura 8).

Figura 8 de etapas restantes na definição da etapa

[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));
  }
}

Eu novamente meus testes, e as coisas agora falham porque eu não tenho uma página para inserir informações do cliente. Para permitir que os clientes a ser criado, preciso de uma página de criar modo de exibição de cliente. Para fornecer um modo de exibição em ASP.NET MVC, eu preciso de um CustomersController que oferece esse ponto de vista. Agora preciso de novo código, o que significa que eu estou pisando do loop externo do BDD e no loop interno do TDD, como mostrado em de Figura 2.

O primeiro passo é criar uma falha teste de unidade.

Escrever testes de unidade para implementar medidas

Depois de criar uma classe de teste de CustomerControllersTests no projeto UnitTest, você precisará criar um método de teste que exerce a funcionalidade para ser exposto no CustomersController. Especificamente, você deseja criar uma nova instância do controlador, chame o método Create e garantir que você receba a exibição e o modelo adequado no retorno:

[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));
}

Este código não compilar ainda porque você não tiver criado seu método de criar ou CustomersController. Ao criar esse controlador e um método de criar vazio, o código é compilado e o teste agora falhar, qual é o próximo passo desejado. Se você concluir o método Create, o teste passa agora:

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

Se você executar novamente os testes de SpecFlow, você obter um pouco mais, mas o recurso ainda não passa. Desta vez, o teste falha porque você não tem uma página de exibição de Create. aspx. Se você adicioná-lo juntamente com os campos apropriados, conforme orientado pelo recurso, você vai passar mais um passo mais perto de um recurso completo.

O processo de fora para implementar essa funcionalidade de criar é algo como Figura 9 .

image: Scenario-to-Unit Test Process

Figura 9 de processo de teste de unidade de cenário

Essas mesmas etapas vão repetir-se muitas vezes neste processo, e sua velocidade na iteração sobre eles aumentará consideravelmente ao longo do tempo, especialmente como implementar medidas auxiliar (clicando em links e botões, preenchimento de formulários e assim por diante) no projeto AcceptanceTests e começar a testar a funcionalidade fundamental em cada cenário.

Vista criar válido, o recurso agora preenche os campos de forma adequada e irá tentar enviar o formulário. Você pode imaginar agora o que acontece a seguir: O teste falha porque você ainda não possui a lógica necessária para salvar o registro do cliente.

Seguindo o mesmo processo como antes, crie o teste usando o código de teste de unidade mostrado anteriormente em de Figura 3. Depois de adicionar um método Create vazio que aceita um objeto de cliente para permitir que este teste compilar, você assistir ele falhar e, em seguida, completa o método Create como para:

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

  return View("Details", customer);
}

O controlador é apenas um controlador, e a criação do registro de cliente pertence a um objeto de repositório que tem conhecimento de um mecanismo de armazenamento de dados. Eu deixei que a aplicação do presente artigo para resumir, mas é importante notar que, em um cenário real, a necessidade de um repositório salvar um cliente deve lançar outro sub-lacete de testes de unidade. Quando você precisa de acesso a qualquer objeto colaboradoras e esse objeto ainda não existe, ou não oferece a funcionalidade necessária, você deve seguir o mesmo loop de teste de unidade que você está seguindo para o seu recurso e controladores.

Depois que você implementou o método Create e tem um repositório de trabalho, você precisará criar o modo de exibição de detalhes, que leva o novo registro de cliente e o exibe na página. Em seguida, você pode executar SpecFlow mais uma vez. Finalmente, depois de muitas TDD loops e lacetes, tem agora um recurso de passagem que comprove fora alguma funcionalidade de ponta a ponta no seu sistema.

Parabéns! Agora você já implementou uma unidade de funcionalidade de ponta a ponta com um teste de aceitação e um conjunto completo de testes de unidade que garantirá a nova funcionalidade continuará a trabalhar como seu sistema se expande para adicionar novos recursos.

Uma palavra sobre a refatoração

Esperemos que, como criar testes de unidade-nível em seu projeto de UnitTests, você está constantemente refatoração com cada criação de teste. Como você voltar a Cadeia de passar testes de unidade para uma aceitação de passagem de teste, você deve seguir o mesmo processo, assistindo oportunidades Refatorar e refinar sua implementação para cada recurso e todos os recursos que vêm depois.

Estar à procura de oportunidades Refatorar o código em seu projeto de AcceptanceTests. Você encontrará que algumas etapas tendem a ser repetido muitas vezes através de vários recursos, especialmente seus passos determinados. Com SpecFlow, você pode mover facilmente estes passos em arquivos de definição de etapa separados organizados por função, como LogInSteps.cs. Isso deixa seus arquivos de definição de etapa principais limpo e orientado o cenário exclusivo que você está especificando.

BDD é sobre o foco em design e desenvolvimento. Por elevar seu foco de um objeto para um recurso, você habilitar-se e sua equipe de design do ponto de vista do usuário de um sistema. Como recurso de design se torna unidade design, certifique-se de autor testes com seu recurso em mente e certifique-se dos que testes são guiados por etapas distintas ou tarefas.

Como qualquer outra prática ou disciplina, BDD leva tempo para se ajustar ao seu fluxo de trabalho. Encorajamos você a experimentá-lo por si mesmo, usando qualquer uma das ferramentas disponíveis e ver como ele funciona ao longo do tempo. À medida que desenvolve neste estilo, preste atenção para as questões que BDD encoraja você a pedir. Constantemente pausar e encontrar maneiras de melhorar o seu processo e prática e colaborar com outras pessoas em idéias para melhoria. Minha esperança é que, independentemente do seu conjunto de ferramentas, o estudo do BDD acrescenta valor e foco para sua própria prática de desenvolvimento de software.

Brandon Satrom funciona como um evangelista de desenvolvedor para a Microsoft em Austin, Texas. Ele bloga em userinexperience.com e pode ser encontrado no Twitter como @ BrandonSatrom.

Graças aos seguintes especialistas técnicos para refviewing este artigo: Paul Rayner e venda de Clark