Behavior Driven Development

Behavior Driven Development (BDD ou ainda uma tradução Desenvolvimento Guiado por Comportamento) é uma técnica de desenvolvimento Ágil que encoraja colaboração entre desenvolvedores, setores de qualidade e pessoas não-técnicas ou de negócios num projeto de software, relaciona-se com o conceito de verificação e validação. Foi originalmente concebido em 2003, por Dan North[1] como uma resposta à Test Driven Development (Desenvolvimento Guiado por Testes), e tem se expandido bastante nos últimos anos.[2]

Os focos do BDD são a linguagem e as interações usadas no processo de desenvolvimento de software. Desenvolvedores usam sua língua nativa em combinação com a linguagem ubíqua (ubiquitous language), que lhes permite concentrar nas razões pelas quais o código deve ser criado, e não em detalhes técnicos, além de minimizar traduções entre a linguagem técnica na qual o código é escrito e outras linguagens de domínio, usuários, clientes, gerência do projeto, etc.

Dan North criou o primeiro framework de BDD, JBehave,[1] em Java, seguido de um framework em Ruby em nível de história chamado RBehave,[1] o qual foi depois incorporado ao projeto RSpec. Ele também trabalhou com David Chelimsky, Aslak Hellesøy e outros para desenvolver o framework RSpec e também escrever "The RSpec Book: Behaviour Driven Development with RSpec, Cucumber, and Friends". O primeiro framework baseado em histórias no RSpec foi posteriormente substituído pelo Cucumber,[3] desenvolvido principalmente por Alask Hellesøy.

História editar

O Desenvolvimento Orientado a Comportamento (Behavior-driven development) ou BDD é uma extensão do Test-driven development:[4] (Desenvolvimento Orientado a testes). Esse tipo de desenvolvimento faz uso de uma linguagem simples e de domínio específico (DSL). Essas DSLs convertem afirmações em linguagem natural estruturada em testes executáveis. O resultado é uma relação aproximada ao critério de aceitação para uma função e os testes usados para validar essa funcionalidade. Sendo assim, é uma extensão natural de TDD (Desenvolvimento Orientado a Testes).

Os focos de BDD são:

  • Onde iniciar no processo
  • O que testar e o que não testar
  • O quanto deve ser testado de uma vez
  • Como chamar os testes
  • Como entender porque um teste falha

Em seu núcleo, BDD é sobre repensar a abordagem a teste de unidade e teste de aceitação com objetivo de evitar problemas que naturalmente surgem. Por exemplo, BDD sugere que o nome dos testes unitários sejam sentenças começando com um verbo ("deve" por exemplo) e deveria ser escrito na ordem de valor comercial. Testes de aceitação deveriam ser escritos usando o framework ágil padrão de uma história de usuário: "Como um [um papel ou função] eu quero [funcionalidade] para que [benefício]". O critério de aceitação deveria ser escrito em termos de cenários e implementados como classes: [[Dado-Quando-Então]| Dado [contexto inicial], quando [ocorre um evento], então [garante que algo acontece]].

A partir deste ponto, muitas pessoas desenvolveram frameworks BDD por um período de anos, enfim enquadrando-o como framework de comunicação e colaboração para desenvolvedores, QA e participantes não técnicos ou de negócios em um projeto de software.[5] Durante o evento "Agile specifications, BDD and Testing eXchange" em novembro de 2009 em Londres, Dan North[6] deu a seguinte descrição de BDD:

BDD é uma metodologia ágil de segunda geração, externa-interna, baseada em tração, de múltiplos stakeholders, múltipla escala e de alta capacidade de automação. Ela descreve um ciclo de interações com saídas bem definidas, resultando na entrega de um software funcionando e bem testado e que importa.

Durante uma entrevista com Dan North na GOTO Conference em 2013, Liz Keogh[7] define BDD como:

BDD é como usar exemplos para falar sobre como um aplicativo se comporta... E ter conversas sobre esses exemplos. (Pesquisar: "GOTO 2013 • Interview with Liz Keogh & Dan North")

Dan North criou um framework BDD, JBehave, seguido de framwork BDD em nível de histórias para Ruby chamado RBehave[8] que após um tempo foi integrado no projeto RSpec.[9] Ele também trabalhou com David Chelimsky, Aslak Hellesøy e outros para desenvolver Rspec e também para escrever "The RSpec Book: Behaviour Driven Development with RSpec, Cucumber, and Friends". O primeiro framework baseado em história em RSpec foi depois substituido por Cucumber desenvolvido príncipalmente por Aslak Hellesøy. Capybara, que é uma parte do framework de testes Cucumber é um software de automação de testes baseado em redes.

Práticas de BDD editar

As práticas de BDD incluem:

  • Envolver as partes interessadas no processo através de Outside-in Development (Desenvolvimento de Fora para Dentro)
  • Usar exemplos para descrever o comportamento de uma aplicação ou unidades de código
  • Automatizar os exemplos para prover um feedback rápido e testes de regressão
  • Usar deve (should em inglês) na hora de descrever o comportamento de software para ajudar esclarecer responsabilidades e permitir que funcionalidades do software sejam questionadas
  • Usar simuladores de teste (mocks, stubs, fakes, dummies, spies) para auxiliar na colaboração entre módulos e códigos que ainda não foram escritos

Desenvolvimento de Fora pra Dentro (Outside-In Development) editar

BDD é guiado pelos valores de negócios; que é o benefício trazido para o negócio no qual a aplicação está sendo produzida. A única maneira na qual o benefício pode ser percebido é através de interfaces de usuário para a aplicação, comumente (mas nem sempre) a interface gráfica de usuário.

Da mesma maneira, cada trecho de código, começando com a interface de usuário, pode ser considerado como sendo um cliente de outros módulos de código no qual a interface é utilizada. Cada elemento de código provê algum comportamento, o qual em colaboração com outros elementos provê o comportamento da aplicação.

A primeira parte de código de produção que os desenvolvedores que usam BDD implementam é a interface de usuário, pois dessa maneira os desenvolvedores podem se beneficiar com um feedback rápido para saber se a interface está adequada ou não. Através de código, e usando princípios de design e refatoração, desenvolvedores descobrem colaboradores para a interface de usuário, e posteriormente para cada unidade de código. Isso os ajuda a aderirem o princípio de YAGNI, desde que cada trecho de código de produção é requerido pelos negócios ou por outro trecho de código já escrito.

Cenários, ou Exemplos da Aplicação editar

Em BDD, um desenvolvedor, algum profissional do setor de qualidade ou até mesmo o cliente podem esclarecer os requisitos quebrando-os em exemplos específicos. Um exemplo de requisito de uma aplicação de vendas poderia ser: "Itens reembolsados ou substituídos devem ser retornados para o estoque". Esse requisito pode ser quebrado em dois exemplos de cenários, como:

Cenário 1: Itens reembolsados devem retornar para o estoque editar

  • Dado que um cliente compra um jumper preto
  • E eu tenho três jumper pretos no estoque
  • Quando ele retorna com o jumper preto para reembolso
  • Então eu devo ter quatro jumpers pretos no estoque

Cenário 2: Itens substituídos devem ser retornados ao estoque editar

  • Dado que um cliente compra um vestido azul
  • E eu tenho dois vestidos azuis no estoque
  • E eu tenho três vestidos pretos no estoque
  • Quando ele retorna com o vestido para uma troca por um preto
  • Então eu devo ter três vestidos azuis no estoque
  • E dois vestidos pretos no estoque

Cada cenário é um exemplo escrito para ilustrar um aspecto específico de comportamento da aplicação.

Ao discutir os cenários os participantes se perguntam se a saída descrita sempre resulta daqueles eventos ocorridos no dado contexto. Isso ajuda a desvendar outros cenários e esclarecer os requisitos.[10] Por exemplo, um especialista do domínio pode notar que itens reembolsados não são sempre devolvidos ao estoque e então reorganizar os requisitos para algo do tipo "Itens reembolsados ou substituídos devem retornar ao estoque a não ser que estejam defeituosos". Este, por sua vez, ajuda os participantes a melhorar os requisitos, levando a uma melhor estimativa de quanto tempo aqueles requisitos levarão para serem implementados.

As palavras Dado que, Quando e Então (Given, When e Then em inglês) são quase sempre usadas para guiar os cenários, mas não são obrigatórias.

Os cenários podem ser automatizados em uma ferramenta para que a automatização a nível de interface de usuário possa existir. Caso não exista alguma ferramenta, então pode ser possível automatizar o próximo nível, como o nível de Controlador, caso esteja sendo usado o padrão de projeto MVC.

Exemplos e Comportamento a nível de Unidade editar

Os mesmos princípios de exemplos, usando contextos, eventos e resultados podem ser usados para guiar o desenvolvimento a nível de unidade. Os exemplos seguintes descrevem um aspecto do comportamento de uma lista:

Exemplo 1: Novas listas são vazias

  • Dado que uma nova lista é criada
  • Então a lista deve estar vazia.

Exemplo 2: Listas com alguma coisa dentro não podem estar vazias

  • Dado que uma nova lista é criada
  • Quando eu adiciono um objeto a ela
  • Então a lista não deve estar vazia

Ambos exemplos são necessários para descrever o comportamento do método esta Vazia de uma lista e obter os benefícios do mesmo. Estes exemplos podem ser automatizados utilizando até mesmo algum framework de TDD. Em BDD cada exemplo é comumente encapsulado num único método de teste, onde o nome do método é a descrição completa do comportamento. Por exemplo, usando Java e JUnit 4, os exemplos acima se tornariam:

public class ListaTest {

   @Test
   public void deveSaberSeEstaVazia() {
      Lista lista1 = new Lista();
      assertTrue(lista1.isEmpty());

      Lista lista2 = new Lista();
      lista2.adiciona(new Object());
      assertFalse(lista2.isEmpty());
   }
}

Às vezes a diferença entre contexto, eventos e resultados pode ser mais explícita. Por exemplo:

public class ComportamentoDoControladorDeJanela {

    @Test
    public void deveFecharJanelas() {

        // Dado que
        ControladorDeJanela controlador = new ControladorDeJanela("Meu Quadro");
        Quadro quadro = new Quadro();

        // Quando
        controlador.fecharJanelas();

        // Então
        garantirQue(!quadro.estaAparecendo());
    }
}

No entanto, o exemplo é fraseado. O efeito deve ser o de descrever o comportamento do código em questão. Por exemplo, a partir dos exemplos acima poderia ser gerado:

  • Lista deve saber quando ela está vazia
  • Controlador de janela deve fechar janelas

A descrição é útil quando o teste falha, provendo documentação do comportamento do código para qualquer um interessado em Listas ou Controladores de janelas. Uma vez que os exemplos foram escritos eles são então rodados e o código para que eles possam rodar e passar é escrito, da mesma maneira que em TDD.

Usando Dublês de Teste editar

Defensores de BDD alegam que o uso de "deve" (should) e "garantirQue" (ensureThat) em exemplos de BDD incentivam os desenvolvedores a questionarem se as responsabilidade que eles estão atribuindo aos seus objetos são apropriados, ou se elas podem ser delegadas ou movidas inteiramente para outros objetos. Um objeto que é mais simples que o código de colaboração e provê a mesma interface, porém com um comportamento mais previsível, pode ser injetado no código que precisa dele, e os exemplos de comportamento do código podem ser escrito usando estes objetos ao invés da versão de produção.

Estes objetos podem ser criados manualmente ou usando um framework de mocks como Mockito, Moq, NMock, Rhino Mocks, JMock, EasyMock.

Questionando responsabilidades dessa maneira, e utilizando dublês de teste para cumprir os papéis necessários para os objetos de colaboração, incentivam o uso de Interfaces Baseadas em Papéis. Isso também ajuda a manter o código de implementação dos objetos pequenos e com baixo acoplamento.

Ferramentas editar

  • ASSpec - ActionScript 3
  • BDoc - Extrai documentação de testes unitários, com suporte a behaviour driven development
  • BDD em Python pode ser feito usando o módulo padrão doctest
  • Behat - PHP
  • Bumblebee - Extrai documentação de testes escritos com JUnit, com suporte para adicionar texto, trechos de código, screenshots e mais. Coloca o foco no usuário final.
  • beanSpec - Java
  • Calabash - Permite rodar testes em aplicativos móveis para Android e iOS
  • CppSpec - C++
  • cfSpec - ColdFusion
  • CSpec - C
  • dSpec - Delphi
  • Concordion - Ferramenta de testes automatizados em Java para fazer BDD usando textos em HTML para descrever comportamentos.
  • Cucumber - Texto plano + Ruby. Roda em Java, .NET, Ruby, Flex ou qualquer aplicação web através do Watir ou Selenium.
  • easyb - Groovy/Java
  • EasySpec - Groovy, usável em Java. Desenvolvedor também trabalhando em Perception uma ferramenta para fazer relatórios do tipo Context/Specification para várias ferramentas diferentes.
  • GSpec - Groovy
  • Instinct - Java
  • JavaStubs - Java - Framework de BDD com suporte a Mock e Method Stubbing
  • JBee - Java
  • JBehave - Java
  • JDave - Java
  • JFXtras Test - JavaFX
  • JSpec - JavaScript
  • JSSpec - JavaScript
  • NBehave - .Net
  • NSpec - .Net
  • NSpecify - .Net
  • NUnit - Outra implementação de um framework de BDD em .Net com foco em testes como especificações.
  • PHPSpec - PHP
  • Pyccuracy - Behavior-driven framework em Python.
  • Pyhistorian - Rodador de Histórias (Story Runner) de propósito geral em Python (DSL interna, sem ser texto plano).
  • PyCukes - Uma ferramenta para BDD em python, parecida com o Cucumber, criada com base no Pyhistorian
  • RSpec - Ruby
  • ScalaTest - Scala
  • specs - Scala
  • spec-cpp - C++
  • Specter - Outra implementação de uma framework de BDD em .Net com foco em legibilidade das especificações.
  • StoryQ - .Net 3.5, pode ser integrado com NUnit para prover especificações e testes legíveis.
  • tspec - Groovy (sintaxe Thai)
  • Twist - ThoughtWorks - Java
  • Yadda - EmberJS
  • XSpec - XPath, XSLT, XQuery

Referências editar

Ligações Externas editar