Fala Galera,

Quando nós construímos uma aplicação temos diversas variáveis para nos preocupar. Essas variáveis geralmente são performance, ser escalável, uma boa usabilidade e atender aos requisitos de negócio. Existe uma outra variável que temos que nos preocupar também a nossa aplicação deve ter qualidade. E por que não coloquei a qualidade nas variáveis acima citadas, por que é implícito que devemos construir algo com qualidade ou alguém já pensou em construir uma aplicação sem qualidade ? Acredito que não.

Porém obter qualidade não é tão simples quanto parece. Quais métricas iremos usar ? Quantidade de Bug ? Números de Teste? Cobertura de Código ? Não existe uma resposta correta nem uma bala de prata.

Qualidade é importante ? Claro que é. A empresa no qual trabalha espera por isso, seu cliente espera por isso, sua equipe espera por isso. Isso ninguém questiona.

E como podemos aumentar a qualidade do nosso software ? A resposta é testando seu software ao máximo. Testes são importantes, porém poucas pessoas fazem ou fazem os testes de forma correta.

Conceito do TDD (Test Driven Design)

Todo o ciclo do TDD se baseia em você fazer os testes antes de implementar seu código, essa quebra de paradigma é um pouco complicada no inicio pois estamos acostumados a primeiro desenvolver e depois testar. Isso força os desenvolvedores a pensar mais como será a funcionalidade, como será seu comportamento e o quais regras de negócio aplicar. Daí temos o famoso conceito do TDD que é o RED, GREEN, REFACTOR.

Esse conceito é o core do TDD, se baseia no ciclo no qual seu teste no começo será vermelho, depois ele ficará verde e após temos que fazer o refactor do nosso código até ficar verde de novo

Esse ciclo se repete para todas as funcionalidades que iremos implementar. No final teremos todos os testes da nossa aplicação mapeada e nosso código sempre estará sendo testado pelos os testes unitários.

O Behavior Driven Design

O BDD é uma técnica de desenvolvimento ágil que encoraja a colaboração entre os Desenvolvedores, a equipe de QA (Quality Assurance) e a equipe de negócio ou uma equipe não técnica.

O BDD é mais voltado para especificações de negócio do que propriamente soluções técnicas. O analista de negócio escreve uma estória de negócio em um português estruturado e nós temos que desenvolver nosso código baseado nessa regra de negócio.

Logo nossa funcionalidade deve atender a estória de negócio e os testes garantirão que essa regra foi atendida como o esperado.

Os principais conceitos do BDD são

  • Uma estória testável (deve ser pequena para se encaixar em um ciclo)
  • O título deve descrever uma atividade
  • A narrativa deve incluir um ator, uma característica e um benefício.
  • A narrativa deve descreve somente um evento baseado no contexto da estória
  • O evento deve descrever uma funcionalidade

Ferramentas essenciais para BDD

  • SpecFlow – Framework que suporta a especificações BDD para .NET
  • MSTest ou outro Framework de testes de sua preferência
  • Selenium – Framework para testes de interfaces utilizando Browsers como Chrome, Firefox e etc

Configuração Inicial

Para usar essas ferramentas iremos criar um projeto ASP.NET MVC, o SpecFlow suporta as versões do Visual Studio 2012, 2013, 2015.

Para instalar o SpecFlow iremos adicionar o plugin do SpecFlow no Visual Studio conforme imagem abaixo:

BDD1

Com o plugin instalado, poderemos usar as especificações do BDD.

Entendo os cenários com o SpecFlow.

Devemos criar os cenários de testes no qual usaremos para realizar os testes. O SpecFlow permite que você crie testes em uma linguagem de fácil compreensão utilizando o Cucumber . O Cucumber é uma linguagem estruturada e que permite você escrever especificações no formato Gherkin Syntax. Um cenário é formato por três passos: GIVEN, WHEN, and THEN

Sabendo desses conceitos vamos criar nossos cenários. Crie um projeto de Unit Tests no Visual Studio e adicione um novo item. Com o plugin do SpecFlow instalado irá aparecer um novo formato o SpecFlow Feature File, iremos adicionar este arquivo.

BBD2

 

Para saber mais sobre o Cucumber, clique aqui
Para saber mais sobre o Gherkin Project, clique aqui

Escrevendo os cenários com o SpecFlow.

Para escrever os cenários utilizaremos o Cucumber, nele será possível criar cenários testáveis no qual qualquer pessoa pode ler e o melhor podemos usar nossa língua mãe o português. Veja na imagem abaixo:

BBD4-1

 

Criando os Testes Unitários:

Com os cenários já criados, devemos criar nossos testes unitários baseados nos cenários escritos anteriormente. Primeiro temos que instalar o pacote do SpecFlow ao projeto de testes. Ele está disponível via NuGet basta rodar o comando no Package Manager Console Install-Package SpecFlow.MsTest.

Agora basta clicar com o botão direito e escolher a opção Generate Step Definition, o SpecFlow irá gerar nossa classe de teste conforme especificado.

 

using System;
using TechTalk.SpecFlow;

namespace BDD.Tests
{
    [Binding]
    public class RegistroOnlineSteps
    {
        [Given(@"que sou um novo usuário")]
        public void DadoQueSouUmNovoUsuario()
        {
            ScenarioContext.Current.Pending();
        }
        
        [When(@"o eu navegar para a página de cadastro")]
        public void QuandoOEuNavegarParaAPaginaDeCadastro()
        {
            ScenarioContext.Current.Pending();
        }
        
        [When(@"inseri todas as informações do formulário corretas")]
        public void QuandoInseriTodasAsInformacoesDoFormularioCorretas()
        {
            ScenarioContext.Current.Pending();
        }
        
        [When(@"clicar no botão de criar conta")]
        public void QuandoClicarNoBotaoDeCriarConta()
        {
            ScenarioContext.Current.Pending();
        }
        
        [When(@"não inseri as informações de email")]
        public void QuandoNaoInseriAsInformacoesDeEmail()
        {
            ScenarioContext.Current.Pending();
        }
        
        [Then(@"o usuário deve ser redirecionado para a Home Page")]
        public void EntaoOUsuarioDeveSerRedirecionadoParaAHomePage()
        {
            ScenarioContext.Current.Pending();
        }
        
        [Then(@"a pagina de cadastro deve exibir uma mensagem de erro")]
        public void EntaoAPaginaDeCadastroDeveExibirUmaMensagemDeErro()
        {
            ScenarioContext.Current.Pending();
        }
    }
}

Utilizando o Selenium WebDriver

Para escrever as validações dos nossos testes unitários usaremos uma biblioteca chamada Selenium (clique aqui para saber mais), essa biblioteca é feita para facilitar os testes de interfaces utilizando os browsers como ferramenta de validação. Com essa biblioteca podemos criar uma instancia de um browser, navegar por páginas e selecionar elementos dentro de uma página. Precisaremos de todos essas funcionalidades para validar os requisitos escritos nos nossos testes.

Vamos adicionar o Selenium utilizando o Package Manager Console. O Selenium está disponível via NuGet então vamos executar o seguinte comando Install-Package Selenium.WebDriver também iremos instalar o suporte ao UI para facilitar a seleção dos elementos da tela utilizando o seguinte comando Install-Package Selenium.Support

Com o Selenium instalado vamos ajustar nossos testes e validar os requisitos, conforme código abaixo.

using System;
using TechTalk.SpecFlow;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;

namespace BDD.Tests
{
    [Binding]
    public class RegistroOnlineSteps
    {
        IWebDriver Browser;

        [BeforeScenario]
        public void CreateWebDriver()
        {
            //Cria a instancia do browser antes de executar os cenarios
            this.Browser = new ChromeDriver();
        }

        [AfterScenario]
        public void CloseWebDriver()
        {
            //Fecha o browser depois que termina os cenarios
            this.Browser.Close();
            this.Browser.Dispose();
        }


        [Given(@"que sou um novo usuário")]
        public void DadoQueSouUmNovoUsuario()
        {
            //Faz Nada
        }
        
        [When(@"o eu navegar para a página de cadastro")]
        public void QuandoOEuNavegarParaAPaginaDeCadastro()
        {
            //Navega para a URL da pagina de Cadastro
            this.Browser.Navigate().GoToUrl("http://localhost:23324/Account/Create");
        }
        
        [When(@"inseri todas as informações do formulário corretas")]
        public void QuandoInseriTodasAsInformacoesDoFormularioCorretas()
        {
            //Pegando os elementos e gerando valores de testes
            var txtNome = this.Browser.FindElement(By.Id("Nome"));
            var txtEmail = this.Browser.FindElement(By.Id("Email"));
            var txtPassword = this.Browser.FindElement(By.Id("Password"));

            //Envia os dados para o formulário
            txtNome.SendKeys("Rafael Cruz");
            txtEmail.SendKeys("[email protected]");
            txtPassword.SendKeys("123Mudar");
        }
        
        [When(@"clicar no botão de criar conta")]
        public void QuandoClicarNoBotaoDeCriarConta()
        {
            var btnCriarConta = this.Browser.FindElement(By.Id("btnSubmit"));

            //Faz o submit no formulario
            btnCriarConta.Submit();

        }
        
        [When(@"não inseri as informações de email")]
        public void QuandoNaoInseriAsInformacoesDeEmail()
        {
            //Pegando os elementos e gerando valores de testes
            var txtNome = this.Browser.FindElement(By.Id("Nome"));
            var txtPassword = this.Browser.FindElement(By.Id("Password"));

            //Envia os dados para o formulário
            txtNome.SendKeys("Rafael Cruz");
            txtPassword.SendKeys("123Mudar");
        }
        
        [Then(@"o usuário deve ser redirecionado para a Home Page")]
        public void EntaoOUsuarioDeveSerRedirecionadoParaAHomePage()
        {
            Assert.IsTrue(this.Browser.Title == "Home Page - My ASP.NET MVC Application");
        }
        
        [Then(@"a pagina de cadastro deve exibir uma mensagem de erro")]
        public void EntaoAPaginaDeCadastroDeveExibirUmaMensagemDeErro()
        {
            Assert.IsTrue(this.Browser.FindElement(By.XPath("//span[@data-valmsg-for='Email']")).Text == "Email é obrigatório");
        }
    }
}

 

Com isso nosso teste unitário irá levantar uma instância de um browser, irá navegar até a tela de cadastro e executará os requisitos de negócio conforme especificado no arquivo Feature do SpecFlow

Como podemos ver na imagem abaixo, todos os nossos testes passaram e agora estão verdinhos. =]

 

BDD6 (1)

 

Dica: Para usar o Chrome, devemos fazer o download do Chrome Driver neste Link 

Com a junção dessas ferramentas conseguimos garantir uma qualidade maior ao nosso software sem contar que podemos colocar em um servidor de integração como Team City ou Team Foundation. Outro ponto importante é que o Cucumber é uma linguagem estruturada não precisando de domínio em informatica ou seja nossos usuários estariam aptos a escrever estórias e nos implementaríamos no nossos testes unitários

Gostaram ? Não deixem de comentar.

Faça download do código clicando aqui

Abs e até a próxima

Rafael Cruz

É desenvolvedor .NET há mais de 12 anos, certificado Microsoft desde de 2006, instrutor oficial Microsoft há 5 anos, Pós Graduado em Engenharia de Software pela UFRJ, suas certificações são Microsoft Certified Trainer, Microsoft Certified Solution Developer (Web, Application Lifecycle Management), Microsoft Certified Professional Developer, Microsoft Certified Tecnology Specialist.
Atualmente trabalha como arquiteto de sistema, escreve artigos no .NET Coders e no seu blog rafaelcruz.azurewebsites.net para compartilhar experiências na área de desenvolvimento Web, Aplicativos Móveis e Cloud Solutions.

Twitter LinkedIn 

Comentários

comentarios