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:
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.
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:
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("teste@teste.com.br"); 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. =]
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