Behavior Driven Development

Origem: Wikipédia, a enciclopédia livre.
Ir para: navegação, pesquisa


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. 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 a 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.


Práticas de BDD[editar | editar código-fonte]

As práticas de BDD incluem:

  • Envolver as partes interessadas no processo através de Outside-in Development (Desenvolvimento de Fora pra 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 | editar código-fonte]

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 | editar código-fonte]

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 | editar código-fonte]

  • 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 | editar código-fonte]

  • Dado que uma cliente compra um vestido azul
  • E eu tenho dois vestidos azuis no estoque
  • E eu tenho três vestidos pretos no estoque
  • Quando ela 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 pergutam se a saída descrita sempre resulta daqueles eventos ocorridos no dado contexto. Isso ajuda a desvendar outros cenários e esclarecer os requisitos[4] . 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 se uma ferramenta para que a automatização a nível de interface de usuário possa ser feita 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 | editar código-fonte]

Os mesmos princípios de exemplos, usando contextos, eventos e resultados podem ser usados para guiar o desenvolvimento a nível de unidade. Por exemplo, 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 estaVazia 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 encapsualado 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.estaVazia());
 
      Lista lista2 = new Lista();
      lista2.adiciona(new Object());
      assertFalse(lista2.estaVazia());
   }
}

À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(!frame.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 | editar código-fonte]

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 | editar código-fonte]

  • 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
  • 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
  • XSpec - XPath, XSLT, XQuery

Referências[editar | editar código-fonte]


Ligações Externas[editar | editar código-fonte]