Como o ATDD Guia Você na Criação Colaborativa Centradas no Usuário de Aplicações

Centric Application

Conduza a Aceitação do Usuário e do Cliente com ATDD

O cenário da engenharia de software é um enigma com jargões e inicialismos. A área parece particularmente apaixonada por inicialismos terminando com “DD”, por exemplo. Muitas vezes pode ser frustrante tentar acompanhar tantos conceitos. Neste post, falaremos sobre um dos muitos inicialismos que terminam com “DD” em software: Acceptance Test-Driven Development. O Acceptance Test-Driven Development, ou ATDD, é uma metodologia de desenvolvimento de software, muitas vezes associada a metodologias ágeis, que promove a colaboração entre desenvolvedores, testadores e partes interessadas da empresa, e na qual a automação de testes desempenha um papel importante.

Como seu nome sugere, o ATDD está relacionado ao TDD, ou Test-Driven Development. Ele também tem semelhanças com abordagens como SBE (Specification by Example) e BDD (Behavior-driven development.) Ao longo do artigo, você entenderá as semelhanças e diferenças entre estas abordagens.

O que é Acceptance Test Driven Development?

Vamos começar contando o que o ATDD não é. Não é uma técnica de teste, apesar do que seu nome possa sugerir. Em vez disso, o desenvolvimento orientado a testes de aceitação é uma técnica de programação. Da mesma forma que seu “primo” TDD, o ATDD coloca a automação de testes na frente e no centro. Ao adotá-lo, as equipes usarão casos de testes automatizados para impulsionar o desenvolvimento do código de produção.

Ao contrário do TDD, que é geralmente considerado como uma prática de engenharia, o ATDD é um esforço de equipe: ele traz diferentes atores no processo de desenvolvimento de software — testadores, engenheiros, partes interessadas empresariais — para colaborar. O resultado dessa colaboração são os requisitos para a aplicação, expressos em um formato compreensível por todos, que depois são transformados em testes de aceitação automatizados.

Qual é o Principal Objetivo do Acceptance Test Driven Development?

O ATDD procura fomentar a colaboração que dá origem a uma compreensão compartilhada dos requisitos do sistema, na forma de especificações escritas em inglês simples. As especificações são então transformadas em casos de testes de aceitação automatizados. Qual é o benefício em fazer isso?

Para entender por que isso é útil, pense primeiro em testes unitários. Esta é uma forma de teste que, por sua natureza, é muito centrada no desenvolvimento. Ele ajuda os engenheiros a documentar suas suposições sobre seu código em formato executável. Os testes unitários resolvem o problema de “estamos construindo a coisa certa?

Entretanto, os testes unitários não resolvem o problema de “estamos construindo a coisa certa?”. Para isso, você teria que recorrer a testes de aceitação, que verificam o funcionamento da aplicação em relação a um conjunto de critérios de aceitação descobertos através de conversas com um especialista no domínio. Em poucas palavras, o Acceptance Test-driven Development resolve o problema da equipe de desenvolvimento implementando funcionalidades que não resolvem as necessidades do cliente. Um componente essencial do ATDD é a automação: as especificações criadas a partir das discussões são transformadas em testes executáveis que garantem que os engenheiros de software implementem as características de acordo com os requisitos.

Breve História

Em seu livro seminal “Test-driven development: By Example”, publicado pela primeira vez em 2000, Kent Beck menciona brevemente o ATDD — que ele chama de Application Test-Driven Development — mas rejeita a ideia.

Entretanto, a abordagem começou a ganhar força de qualquer forma, provavelmente devido ao sucesso de ferramentas como Fit e Fitnesse.

Em 2006, Dan North introduziu o conceito de Behavior-driven Development, que originalmente era apenas para substituir parte do vocabulário de TDD, mas acabou evoluindo para a análise de requisitos. O BDD compartilha muitas semelhanças com o ATDD e, com o tempo, grande parte do vocabulário, ferramentas e abordagens de um foi adotado pelo outro.

Como Funciona / Princípios e Práticas?

Uma Visão Geral do ATDD

O desenvolvimento orientado por testes de aceitação tem um fluxo de trabalho semelhante ao do TDD, uma vez que consiste em criar testes antes de escrever o código de produção. Ao contrário do TDD, que se baseia em testes unitários, os testes de ATDD são testes de aceitação. Os testes nascem de especificações que surgem de discussões envolvendo desenvolvedores, testadores e stakeholders ou clientes comerciais.

Src: Mysoftwarequality & Gojko Adzic

Após a criação dos testes, os desenvolvedores escrevem o código para que esses testes sejam aprovados, implementando as funcionalidades de acordo com as especificações.

Dessa forma, você não só obtém especificações abrangentes que todos podem entender e contribuir para — independentemente das habilidades de programação — mas também garante que os desenvolvedores realmente desenvolvam o que o cliente precisa.

Ciclo do Acceptance Test-driven Development

Embora não haja um acordo universal sobre as fases do ciclo de desenvolvimento orientado por testes de aceitação, você verá muitas vezes estes 4 passos: discutir, destilar, desenvolver e demonstrar.

Discutir

Durante a reunião de planejamento — comum a praticamente todas as metodologias/frameworks sob o conceito Agile — testadores e desenvolvedores discutirão as tarefas/histórias de usuários escolhidas para implementação para a próxima iteração ou sprint com o stakeholder/product owner/cliente, a fim de extrair o máximo de informação possível delas. Durante a fase de discussão, a equipe tem a oportunidade de esclarecer mal-entendidos nos requisitos, o que pode levar a equipe a evitar que um bug seja introduzido na aplicação, o que é muito mais barato do que ter que debugar, diagnosticar e corrigir em seguida. Além disso, a fase de discussão pode levar a equipe a descobrir que o que parecia ser uma simples história de usuário é, na verdade, muito mais complexo. Em tal circunstância, a equipe, juntamente com as partes interessadas, poderia optar por dividir a história em duas ou mais. Os resultados desta fase são testes de aceitação na forma de frases ou tabelas em inglês simples que podem ser compreendidas por todos na organização.

Destilar

A segunda fase consiste em converter os testes produzidos na etapa anterior para um formato compatível com qualquer ferramenta de teste de aceitação que você esteja utilizando. Dependendo da ferramenta, esses formatos incluem:
  • tabelas
  • páginas de wiki
  • ou mesmo código em uma DSL (linguagem específica do domínio).
Portanto, o resultado desta fase são os testes de aceitação. Entretanto, eles não estão totalmente prontos para a execução, como você verá. Desenvolver Até este ponto, o teste produzido na etapa anterior ainda não pode realmente testar o sistema em teste. Eles são meramente esqueletos, nesta etapa; você precisa ligá-los ao código de teste real que executará o código da aplicação. Os detalhes desta conexão variam de acordo com as ferramentas reais que estão sendo utilizadas. Basta dizer que depois que a conexão estiver completa, os testes falharão, já que as funcionalidades que eles estão testando ainda não existem. Então, os desenvolvedores implementam a funcionalidade de acordo com as especificações reunidas na fase “discutir” e que foram convertidas em testes na fase “destilar”.

Demonstrar

Depois que os desenvolvedores implementam a funcionalidade, eles a demonstram às partes interessadas. Ter uma reunião no final de cada ciclo em que a equipe discute o produto e/ou como melhorar o próprio processo é uma característica muito comum de muitas metodologias ágeis. Portanto, a fase de demonstração do ATDD se encaixa bem com isso. Após a implementação estar completa, os testadores também podem realizar alguns testes exploratórios manuais. Tais testes podem encontrar defeitos, mas também encontrar espaço para melhorias que podem então ser transformadas em outras histórias.

Exemplo de Acceptance Test-driven Development

Agora vamos lhe dar um breve exemplo de desenvolvimento orientado por testes de aceitação.

A história do usuário

Para este exemplo, suponha que você esteja trabalhando em um site de comércio eletrônico, e que precise implementar um carrinho de compras. Em metodologias ágeis, os requisitos são frequentemente expressos como histórias de usuários. Um modelo comum para histórias de usuários é o seguinte: Eu como Eu quero Para que eu possa Portanto, a história do usuário para o carrinho de compras poderia ser a seguinte: Como comprador Quero ser capaz de adicionar itens ao meu carrinho de compras Para que eu possa comprá-los

Discutir: Elaborando os critérios de aceitação

Durante a fase de discussão, os desenvolvedores e testadores fazem o maior número possível de perguntas ao especialista de domínio/stakeholder, com o objetivo de encontrar pontos cegos nos requisitos, aprender sobre os caminhos felizes e tristes, e desvendar casos de vantagem.

Aqui estão alguns exemplos de possíveis perguntas:

  • Se eu adicionar outra instância do mesmo produto ao carrinho, devo aumentar o número ou adicioná-lo como um novo item?
  • Existe um limite para quantas unidades do mesmo produto eu posso adicionar ao meu carrinho de compras?
  • Existe um limite para quantos itens eu posso adicionar ao meu carrinho?
Com base nos resultados da discussão, os testadores e desenvolvedores podem apresentar a seguinte tabela detalhando os cenários de testes de aceitação:

_____________________________

Cenário InicialAçãoResultado Esperado
Carrinho vazioAdicionar ao carrinho o produto “Livro ‘Test-Driven Development By Example’”, que custa $29O carrinho deve conter um item, e o total deve ser de $29.
Carrinho com um só produto (“Livro ‘Test-driven development by example’”, custando $29)Retirar o item do carrinhoCarrinho vazio. Total de $0.
Carrinho contendo 3 unidades do mesmo produto.Acrescentar outra unidade do mesmo produto.Carrinho ainda com três itens. A mensagem é exibida dizendo que os clientes não podem comprar mais de três itens do mesmo produto.

_____________________________

Destilar: Transformar os critérios em testes automatizados

Na fase de destilação, os desenvolvedores e testadores convertem os testes de aceitação escritos em linguagem simples em formatos compatíveis com as ferramentas de automação que eles utilizam. Vejamos agora como isso seria, para nosso exemplo, usando duas ferramentas/formatos diferentes.

Fitnesse

A Fitnesse é uma das ferramentas mais populares para testes de aceitação automatizados. É única entre outras ferramentas de testes no formato peculiar que adota para expressar testes: tabelas em uma Wiki.

Isto é o que uma tabela de Fitnesse para testar o cenário de “adicionar itens a um carrinho” poderia parecer:

A tabela acima não é uma mera tabela. Esses são testes reais que podem ser executados. Entretanto, uma tentativa de executá-los resulta no seguinte erro:

We still don’t have a fixture, that is, an actual class that “glues” our Fitnesse test to actual code.

Ainda não temos uma fixação, ou seja, uma classe real que “cola” nosso teste do Fitnesse ao código real. Linguagem Gherkin (Cucumber) Vejamos agora como poderíamos representar os mesmos critérios de aceitação usando Gherkin, que é a linguagem especial usada pela ferramenta Cucumber. Usando Gherkin, os usuários podem descrever cenários usando um modelo comum, conhecido como dado-quando-então: Dado Quando Então Aqui está um exemplo: Funcionalidade: Carrinho de compras Os compradores precisam ser capazes de adicionar itens a seus carrinhos Cenário: Adicionando um produto a um carrinho vazio Dado que meu carrinho está vazio Quando eu adiciono um produto chamado “Book TDD By Example” que custa $29 ao meu carrinho Então meu carrinho deve conter esse produto E o total deve ser de $29 A tentativa de executar o teste acima produz um resultado semelhante ao que você viu no Fitnesse:

Ele diz que o cenário tem passos faltando, e então vai mais além e nos dá conselhos sobre como realmente preencher esses espaços em branco.

Desenvolver: Ligando os testes e implementando a funcionalidade

Para o exemplo acima, foi assim que pudemos preencher os espaços em branco: Given(“my cart is empty”, () -> { this.cart = new ShoppingCart(); }); When(“I add a product called {string} which costs ${int} to my cart”, (String string, Integer int1) -> { this.product = new Product(string, int1); this.cart.add(this.product); }); Then(“my cart should contain that product”, () -> { assertEquals(1, this.cart.getItemsQuantity()); assertEquals(this.product, this.cart.items[0]); }); Then(“the total should be ${int}”, (Integer int1) -> { assertEquals(int1, this.cart.total); });
Estamos usando variáveis de instância para guardar uma instância de uma classe de ShoppingCart, que representa — você adivinhou — nosso carrinho de compras. Tal classe poderia — e deveria — ser desenvolvida utilizando a abordagem test-first (TDD). Como você pode ver, o Cucumber é inteligente o suficiente para substituir o nome e o preço do produto por placeholders, que são então transformados em variáveis. Dessa forma, podemos parametrizar esses testes, reutilizando a mesma lógica com uma série de valores de entrada diferentes.

Semelhanças e Diferenças

Vamos agora discutir como o ATDD é semelhante ou diferente de outras práticas.

Acceptance Test-driven Development vs Test-Driven Development

O Acceptance Test-driven Development é frequentemente comparado ao Test-driven Development. Obviamente, eles estão relacionados, mas como os dois se comparam?

TDD — Test-driven Development — é uma metodologia na qual os desenvolvedores começam o desenvolvimento escrevendo um teste unitário reprovado e só depois escrevem o código de produção para que o teste seja aprovado.

Ao utilizar TDD, os desenvolvedores visam criar um código limpo e simples, composto de módulos frouxamente acoplados, levando a uma maior capacidade de manutenção. Entretanto, o TDD é uma abordagem centrada no desenvolvimento que se baseia em testes unitários. Como você já viu, os testes unitários podem levar ao problema de implementar corretamente as funcionalidades erradas.

O ATDD não se concentra no desenvolvedor, mas incentiva a colaboração entre os desenvolvedores e outros membros da equipe, mesmo aqueles sem habilidades de programação.

Você pode e deve usar TDD e ATDD juntos. No início de cada iteração, comece criando testes de aceitação automatizados com base em discussões com o especialista do domínio.

Quando chegar a hora de realmente implementar o código de produção, use TDD para testar o desenvolvimento do código. Em outras palavras, o TDD é um teste de aceitação automatizado: O TDD pode ser alavancado como um ciclo “interno” dentro das fases gerais do ATDD.

Acceptance Test-driven Development vs Behavior Driven Development

O BDD — Behavior-Driven Development — foi originalmente introduzido por Dan North como um substituto para o TDD. Ele sentiu que a palavra “teste” era problemática, e procurou criar um novo vocabulário centrado em comportamentos e cenários. Assim, o BDD originou-se no nível de teste unitário. Somente quando um amigo indicou que sua abordagem soou como análise, ele começou a aplicar a abordagem aos requisitos. Quando comparado ao Acceptance Test-Driven Development, o BDD tem um foco mais forte na criação de uma compreensão compartilhada do comportamento esperado do sistema. Os conceitos do livro Domain Driven Design de Eric Evans — como a linguagem ubíqua — também foram muito influentes no desenvolvimento do BDD.

Armadilhas Comuns

As ferramentas ATDD podem ser uma fonte de complexidade/curva de aprendizagem. Por exemplo, o Fitnesse exige que as pessoas usem sua linguagem de markup. Embora existam alternativas — como criar os testes usando uma planilha de Excel e depois importar para o Fitnesse — não há como negar que há uma certa complexidade envolvida.

Para implementar com sucesso não apenas o ATDD, mas os testes de aceitação em geral exigirão treinamento e orientação para que as pessoas estejam prontas para desempenhar o que se espera de suas funções. Você também precisará de uma efetiva defesa ou evangelização para colocar todos a bordo e prontos para aplicar a abordagem.

Sem tudo isso, é provável que você obtenha apenas benefícios limitados.

Começando

Como começar com o ATDD? Aqui estão alguns passos práticos.

  • Treine todos sobre o assunto para que fiquem na mesma página. Comece assegurando que todos na organização tenham acesso a materiais de treinamento para que possam ser instruídos quando se trata de ATDD.
  • Capacite a todos nas habilidades para suas funções e responsabilidades. A implementação do ATDD requer habilidades muito específicas, incluindo as sociais — sabendo como discutir e colaborar com especialistas de domínio, por exemplo. Naturalmente, também são necessárias habilidades técnicas, tais como competência em ferramentas de teste.
  • Familiarize-se com os requisitos no formato de histórias de usuários. As histórias de usuários são certamente um dos fundamentos do ATDD. É crucial que todos os membros da equipe se sintam à vontade para ler e também escrever os requisitos de software usando este formato. Mais tarde, você deve expandir isto para também ser competente na linguagem Gherkin.
  • Durante a reunião inicial, no início de cada iteração, comece a praticar a extração de cenários/critérios de aceitação dos stakeholders e escreva testes em inglês simples com elas. Não é necessário utilizar um formato ou linguagem específica para isto.
  • Após melhorar na etapa anterior, procure por um tutorial ou guia sobre um framework de ATDD específico de testes de aceitação. Adote esse framework e comece a implementar os testes de aceitação de acordo com o ciclo ATDD.
  • Avalie regularmente a abordagem e adapte-se quando necessário.

Leitura Adicional

  • Test Driven Development: By Example, por Kent Beck
  • ATDD by Example: A Practical Guide to Acceptance Test-Driven Development por Markus Gärtner
  • Driving Development with Tests: ATDD and TDD – Artigo por Elisabeth Hendrickson
  • Behavior Driven Development (BDD): Creating Useful Software Customers Want

Entregue Software que Resolva os Problemas de seus Usuários

Infelizmente, é comum as equipes de desenvolvimento criarem softwares que não fazem o que o cliente realmente pediu. O desenvolvimento orientado a testes de aceitação procura resolver este problema usando a automação de testes para capturar os requisitos do usuário em um formato bem compreendido por todos.

A vida é boa quando suas equipes Agile estão sincronizadas!

Contate-Nos hoje para uma demonstração personalizada do SwiftEnterprise! Ou inscreva-se para atualizações abaixo.