O Acceptance Test-Driven Development (ATDD), ou "Desenvolvimento Orientado a Testes de Aceitação", é uma prática de obtenção de requisitos de forma colaborativa aplicada por equipes ágeis, onde exemplos concretos e testes automatizados são utilizados para especificar os requisitos, tornando-os mais claros, com o objetivo de criar especificações executáveis. Eles são gerados em sessões de criação do backlog do produto, com a participação da equipe, Product Owner, além dos demais interessados.
Markus Gärtner, em seu livro "ATDD by Example: A Practical Guide to Acceptance Test-Driven Development", cita a seguinte declaração:
Um analista de qualidade e um programador que colaboram juntos para atingir a meta da equipe, em relação a automação de teste, agregam muito valor quando iniciam a abordagem do ATDD.
A imagem abaixo representa o ciclo do desenvolvimento orientado a testes de aceitação, composto por 4 passos para aplicá-lo, conforme Elisabeth Hendrickson.
Traduzido de: http://testobsessed.com/wordpress/wp-content/uploads/2008/12/atddexample.pdf
O ATDD é muito similar ao TDD, diferenciando-se deste último pelo fato de termos uma colaboração maior entre o desenvolvedor, analista de qualidade (tester) e negócio (cliente/partes interessadas). Enquanto o teste unitário está intrinsicamente relacionado com o código, de um ângulo do desenvolvedor (visão interna), o teste de aceitação está voltado ao ponto de vista do usuário, uma visão externa ao sistema.
Aplicando o ATDD
Enquanto Craig Larman e Bas Vodde, em seu artigo, consideram a aplicação do ATDD como um fluxo de 3 etapas, ou seja: debater, desenvolver e revisar; Hendrickson incluiu mais um passo: refinar. Portanto, exploraremos os 4 passos de Hendrickson para ficar mais claro e detalhado como o processo funciona.
Debater os Requisitos
As histórias de usuário (user story) são refinadas em um workshop ou em uma reunião de preparação do backlog do produto (backlog grooming), antes da reunião de planejamento da iteração/sprint. Em ambos os casos, os participantes são uma equipe multifuncional, o Product Owner e, algum outro interessado que potencialmente tem mais informações sobre as histórias.
Algumas perguntas devem ser feitas para elencar exemplos de utilização ou cenários de uso dessas histórias de usuário e, assim, entendermos melhor o que está sendo conversado, de tal forma que esses cenários possam ser escritos como testes.
Suponhamos que um possível comprador entre em um site de e-commerce e após buscar um produto desejado, ele recebe a mensagem que o produto está indisponível. Como o site poderá ajudar a fidelizar um iminente cliente? Permitindo que o cliente seja avisado quando o produto voltar a ter estoque. Para exemplificar, vamos criar uma história de usuário e depois faremos perguntas que poderiam ser feitas durante a reunião.
"Como comprador do site, eu quero ser avisado por email quando um produto voltar a ficar disponível para compra, assim eu posso adquiri-lo".
Algumas perguntas que poderiam ser realizadas são as seguintes:
- O usuário deve possuir uma conta no site? Se sim, o que acontece se o usuário não está logado no site?
- O que acontece caso o usuário já tenha criado um alerta para o mesmo produto?
Após a obtenção dessas respostas, existe um entendimento melhor do que o Product Owner espera que o produto faça ou não. Então, pode-se começar a estruturar os testes de aceitação em colaboração com todos. Fazemos isso em uma linguagem que todos entendam, por exemplo:
- usuário deve ser cadastrado no site; senão estiver, remeta-o para a página de cadastro;
- usuário deverá estar logado; senão estiver, solicite o usuário e senha;
- usuário cadastrado e logado deverá confirmar o alerta para o e-mail que está no cadastro.
Refinar os Testes de Aceitação
O próximo passo é organizar os testes de aceitação em um formato requerido pelo framework de automação de testes. Existem diversos frameworks de automação de teste: FIT, FitNesse, Cucumber, Concordian, Robot Framework, RSpec, Jnario, entre outros. Para exemplificar, utilizaremos o Cucumber.
Implementar o Código com TDD
O próximo passo é implementar a funcionalidade para fazer com que o teste de aceitação passe.
E, para tanto, o desenvolvimento deve iniciar pelos testes unitários, incluindo todas as condições propostas para as expectativas existentes. Um exemplo para um cenário é exibido abaixo.
Depois de codificados todos os testes unitários, eles são executados e passamos a uma fase para ajustar aqueles que estão falhando (frameworks de testes unitários sinalizam por meio de "barras de progresso" vermelha e verde (vide imagem abaixo), onde uma barra vermelha é porque o teste está "quebrado" e verde é quando ele passa com sucesso), partindo então para a implementação da história de usuário.
Dois tipos de testes unitários, o da direita falhou e o da esquerda passou com sucesso
Apresentar os Resultados dos Testes de Aceitação
Após os testes passarem com sucesso, a história é verificada pelo Product Owner, normalmente em uma reunião de Review/Showcase, onde ele poderá aprová-la ou não. O resultado pode levar à criação de uma nova história ou uma alteração nos testes existentes, afim de contemplar novos cenários. Outra forma que também funciona bem, e não posterga a validação em uma reunião específica, é a validação de cada história (Review), imediatamente após ela ser desenvolvida pela equipe, de tal maneira que o Product Owner possa fazer isso com o desenvolvedor ou o par de desenvolvedores que a finalizaram.
Finalmente, encerramos o ciclo do ATDD.
Diferenças entre ATDD e BDD
Agora, o que muito se confunde na comunidade ágil são as diferenças entre o ATDD e o BDD, pois eles são muito similares na essência.
O Behavior-Driven Development (BDD), ou "Desenvolvimento Orientado a Comportamento", foi concebido por Dan North, autor do livro "The RSpec Book - Behavior-Drive Development with RSpec, Cucumber, and Friends", como uma evolução a algumas questões encontradas no TDD (Test-Driven Development):
- Por onde começar no processo?
- O que testar e o que não testar?
- O quanto testar de uma só vez?
- O que chamamos de testes?
- Como entender o por quê um teste falha?
Então, North apresentou a seguinte definição:
O BDD é uma prática ágil que permite uma melhor comunicação entre desenvolvedores, analistas de qualidade, áreas de negócio e pessoas não-técnicas, durante um projeto de software, descrevendo um ciclo de iterações com saídas bem definidas e resultando na entrega de software testado e que funciona.
North criou o primeiro framework BDD para Java chamado JBehave e depois o RBehave para Ruby, vindo depois a ser integrado no RSpec.
Segundo Janet Gregory, co-autora do consagrado livro "Agile Testing", juntamente com Lisa Crispin, ela declara em seu artigo "ATDD vs. BDD vs. Specification by Example vs …", sobre as diferenças entre ATDD, BDD e Especificação por Exemplo:
Ao chamarmos de "BDD", ou "ATDD", ou "Especificação por Exemplo", queremos o mesmo resultado - um entendimento comum compartilhado do que será construído para tentar entregar o que é certo, da primeira vez. Sabemos que nunca será, mas com menos retrabalho, ficará melhor.
Depois, Gregory finaliza:
Continuarei a usar o termo "Acceptance Test Driven Development (ATDD)", a menos que a indústria decida sobre um vocabulário comum, porque acho que as áreas de negócio da empresa não só entenderão como dar exemplos, mas também compreenderão quando eu falar sobre os testes de aceitação que comprovam a intenção da história ou funcionalidade. A equipe entenderá suficientemente o escopo para então iniciar a codificação e os testes.
Conclusões
A proposta do ATDD é favorecer uma colaboração e comunicação maior entre todos os envolvidos no desenvolvimento de um produto, o que resulta em um entendimento mais claro e refinado dos requisitos, possibilitando um acordo entre ambas as partes do que será desenvolvido durante uma iteração/sprint. No final, o resultado estará alinhado às expectativas do cliente.
Sobre o Autor
Paulo Rebelo é Agile Project Manager & Agile/Lean coach no Walmart.com, editor do InfoQ, revisor do Scrum Gathering e integrante do Program Committee do QCon SP. É apaixonado em ajudar empresas e profissionais a entregarem software de forma contínua, além de criar e desenvolver equipes ágeis de desenvolvimento.