Like A Girl

Pushing the conversation on gender equality.

Code Like A Girl

Especificação Por Exemplo e Qualidade de Produto

Photo by Ashim D’Silva on Unsplash

Tenho certeza que alguma vez na sua jornada de trabalho com desenvolvimento de software você já ouviu palavras como BDD, ATDD, Especificação Por Exemplo. A maioria delas atrela esses termos apenas à parte de testes de uma aplicação, mas não observa como elas são práticas poderosas que, muito mais que apenas contribuir para o teste que seu time está desenvolvendo, ajudam a garantir que ele está fazendo realmente a coisa certa, aquilo que o seu cliente precisa.

Pra tentar elucidar um pouquinho melhor de onde vieram essas palavras e como chegamos até aqui, montei uma linha do tempo baseada em vários autores diferentes (que no final estão dizendo basicamente a mesma coisa), mas que apresentam o tema de acordo com o seu ponto de vista.

Um pouco de história

Linha do tempo sobre Especificação Por Exemplo na visão de alguns autores

1999 —Kent Beck (Extreme Programming Explained: Embrace Change)

Nesse livro, Kent Beck apresenta os valores, práticas e princípios do XP. Apesar de não citar o termo "Especificação Por Exemplo", ele fala sobre especificar e refinar continuamente durante o desenvolvimento para que o aprendizado com os clientes seja refletido no software desenvolvido.

No ciclo que ele propõe, as histórias são especificadas imediatamente antes de serem implementadas e, depois disso, são extraídos testes dessas especificações. A interface é projetada para atender às necessidades do teste. O código é escrito para corresponder aos testes e à interface. O design é refinado para corresponder às necessidades do código escrito. Isso leva a uma decisão sobre qual história especificar em seguida. Enquanto isso, o restante das histórias permanece parada até ser escolhida para implementação.

De cara vemos aí os conceitos de refinamento, priorização e orientação ao valor para nosso cliente final, nosso usuário.

Extreme Programming Explained: Embrace Change — Kent Beck

2004— Martin Fowler (Specification by Example)

Nesse artigo, Fowler usa a expressão "Especificação Por Exemplo" para se referir ao que Kent Beck tinha chamado de especificações na parte do XP que fala de testes. Ao invés de lidar só com as especificações do comportamento (pensando em pré-condições e pós-condições), é adicionada a palavra exemplo para nos fazer pensar de forma mais humanizada em termos de uso real. Um ponto importante que ele levanta é que Especificação Por Exemplo sozinha não resolve todos os problemas, você precisa sempre ter o apoio de mais de uma ferramenta para alcançar seus objetivos ou resolver os problemas.

Ele também reforça que isso só funciona em ambientes de colaboração, onde todas as pessoas envolvidas no desenvolvimento do software estão juntas construindo o melhor produto. Não por coincidências, esta técnica está em linha com as práticas de design thinking e user experience, que estão em voga. As premissas de design centrado no usuário e de orientação à resolução de um problema do cliente e do valor que entregamos ficam muito claras nesta técnica.

2005 — Lisa Crispin (Customer Test-Driven Development)

Comunicação e colaboração são duas palavras chave nesse artigo de Lisa Crispin. Para cada história ela perguntava ao cliente como ele saberia que aquela história estava completa, na forma de testes e exemplos. Assim como no TDD, antes de escrever qualquer código, os testes são desenhados primeiro e, depois, se eles passam, significa que o código atende aos requisitos. Os testes deveriam, idealmente, ser escritos de uma forma que possam ser entendidos por uma ferramenta de automação, mas também em alto nível para que possam guiar os testes exploratórios. Durante um refinamento, ter este tipo de mindset é imprescindível para buscar validar o que é realmente esperado do que estamos criando. Desta forma, podemos entender melhor os diversos cenários vinculados ao problema que estamos tentando resolver, e co-criar com time e usuários uma solução que seja de fato eficaz.

2006 — Dan North — Introducing BDD (Behavior Driven Development)

Durante sua jornada usando TDD, Dan North observou algumas dificuldades como: por onde começar, o que testar e o que não testar, como chamar os testes e como entender por que um teste falha.

O BDD então é uma prática ágil que permite uma melhor comunicação entre todas as pessoas técnicas e não técnicas envolvidas, 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. Ele deixa claro quais são as hipóteses de comportamento que esperamos ter, buscando novamente uma visão humanizada e tangível do uso da solução.

2008 — Elisabeth Hendrickson — Driving Development with Tests: ATDD (Acceptance Test-Driven Development) and TDD

Nesse material, Elisabeth fala de requisitos executáveis, onde você cria testes antes de codificar e esses testes representam o comportamento que o software deveria ter. Lembrando que é muito importante que esse trabalho seja feito em conjunto com os stakeholders.

Segundo ela, as especificações dão feedback sobre o quanto o time está próximo do "done" de uma história, dando até uma ideia de progresso em direção ao objetivo. Isso é viável porque podemos mapear cada cenário que precisa ser testado e quais deles já foram cobertos frente ao todo, apresentando uma visão de andamento.

2009 — Gojko Adzic — Bridging the Communication Gap: Specification by Example and Agile Acceptance Testing

O ponto mais relevante aqui nessa publicação do Gojko é que especificação não se trata de uma técnica de programação, mas uma técnica de comunicação que traz as pessoas envolvidas no desenvolvimento do software para mais perto do projeto.

2010 — Lisa Crispin — ATDD X BDD X Specification By Example

No Agile 2010, durante um workshop sobre Testes Funcionais, cerca de 20 pessoas da comunidade de software internacional foram discutir o que realmente significava o ATDD.

Como pudemos ver nos resumos de cada uma das sessões acima, temos várias pessoas falando a mesma coisa com nomes diferentes e algumas particularidades (exemplos, testes de aceitação, cenários, testes de usuário, comportamento, testes funcionais, especificação executável…).

Isso acontece porque todas estavam tentando resolver o mesmo problema.

Como resultado desse workshop, eles chegaram a uma definição de Especificação Por Exemplo que seria descrita em 2011 no livro do Gojko, de mesmo nome.

Resultado do Workshop sobre Testes no Agile 2010

2010 — Craig Larman — Specification By Example

Quando o Craig fala sobre Less, ele dedica uma parte a técnicas que auxiliam a alcançar a excelência técnica, e, adivinhem, a Especificação Por Exemplo está lá (assim como Integração e Entrega Contínua, Código Limpo, TDD e outros).

Segundo ele, testes devem ser encarados como requisitos e requisitos como testes, dado que se você tem um teste que descreve o comportamento esperado, e no final do desenvolvimento esse teste passa, significa que você atingiu o objetivo daquela funcionalidade.

Além disso ele cita outros elementos que já vimos nos blocos anteriores, como fazer workshops para colaborar e descobrir os requisitos, atuar em ciclos curtos de desenvolvimento e focar em prevenção de problemas ao invés de encontrar.

https://less.works/less/technical-excellence/specification-by-example.html

2011 — Gojko Adzic — Specification by example: How successful teams deliver the right software

Foi através desse livro que eu conheci o tema. Dois anos atrás, assim que eu entrei na Concrete, foi o primeiro livro que recebi como referência sobre o trabalho de QA. Nesse livro o Gojko reune uma série de padrões que foram observados em vários projetos de sucesso e define a Especificação por Exemplo como um conjunto desses padrões que ajudam a desenvolver o software certo.

Tem uma série de posts meus sobre o assunto:

Desde então, passei a usar as referências desse livro do Gojko ao falar de Especificação Por Exemplo, mas ao fazer a pesquisa para esse post vi que o livro dele é um resumo do que muitas outras pessoas estavam falando pelo mundo. Ele basicamente escreveu o livro em cima do resultado do Workshop do Agile 2010 que eu já citei acima.

Agora, chega de história e vamos ao que interessa:

Voltando ao início desse texto, muitas pessoas associam Especificação Por Exemplo apenas à parte de testes da aplicação mas não utilizam de todo seu ferramental para efetivamente construir produtos de qualidade tanto no quesito de atender as especificações funcionais, quanto deser realmente aquilo que o cliente precisa.

Eu encaro Especificação Por Exemplo como uma abordagem muito focada em descoberta, onde a colaboração entre os envolvidos no processo de desenvolvimento (produto e engenharia) é extremamente importante de forma a descobrir os requisitos necessários para atender a necessidade do cliente, exemplificá-los de forma que todas essas pessoas possam entender o que está sendo dito (por isso utiliza uma linguagem de domínio) e utilizando o apoio de engenharia (com testes automatizados e práticas de Integração e Entrega Contínua) para garantir uma entrega de software de qualidade.

E como aplicar isso na prática?

Para cada uma das práticas da Especificação Por Exemplo, vou dar exemplos de como podemos aplicar:

Derivar o escopo a partir dos objetivos:

Descobrir o que o cliente realmente precisa e dar liberdade para que o time de desenvolvimento possa sugerir a melhor forma de fazer isso (mais simples de implementar, mais rápida e até mais barata).

Nosso foco, então, deve ser entender qual o problema que o cliente quer resolver, ou a meta que ele quer atingir, e a partir daí o time todo colabora para chegar ao design da solução.

Objetivos de negócio > derivar o escopo > criar as histórias

Por exemplo, se temos como objetivo resolver um problema de clientes que querem pagar uma conta rapidamente, podemos derivar o seguinte escopo:

O titular da conta bancária irá pagar um boleto através do código de barras. Ele pode digitar o código de barras, o que é lento, ou pode usar a câmera do celular para capturar a imagem do código de barras. A aplicação deve interpretar esta imagem e preencher os dados do boleto a ser pago sem a necessidade de intervenção do usuário. O usuário pode revisar os dados e confirmar o pagamento.

A opção mais rápida deve ser oferecida como primeira opção ao usuário, enquanto a mais lenta deve ser adicional.

História 1: Eu, como titular de uma conta corrente, quero usar minha câmera do celular e identificar um código de barras, para que os dados de meu boleto sejam preenchidos rapidamente.

História 2: Eu, como titular de uma conta corrente, quero preencher manualmente o número do código de barras de um boleto, para pagá-lo ainda que o código de barras esteja ilegível.

História 3: Eu, como titular de uma conta corrente, quero revisar os dados preenchidos de um boleto informados via código de barras, para confirmá-los e efetivar o pagamento.

Especificar Colaborativamente:

Aqui é onde algumas pessoas que tentam implementar Especificação Por Exemplos acabam se perdendo. Muitas vezes apenas uma pessoa dentro do time (normalmente quem tem o papel de QA) escreve as especificações e o restante do time nem olha. Se é isso que acontece, perdemos totalmente o sentido de colaboração. A ideia é que todos os envolvidos participem, pode ser através de workshops, ou escrita e revisagem. O importante é que as especificações são escritas pelo time e para o time (incluindo o cliente). A linguagem tem que fazer parte do domínio de negócio e ser entendida por todos.

Ilustrar usando exemplos:

Seres humanos compreendem melhor com exemplos práticos. Isso ajuda a evitar a ambiguidade e comunica com precisão.

É importante utilizar exemplos concretos do negócio e pensar nos outputs esperados.

Além disso, os exemplos ajudam a gerar discussão e eliminar as dúvidas.

Exemplificando:

Funcionalidade: Entrega Grátis

1 — Oferecida para clientes VIP, uma vez que eles comprem um certo número de livros;

2 — Não é oferecida para clientes comuns nem para clientes VIPs que comprem qualquer coisa diferente de livros;

3 — O número mínimo de livros para a entrega grátis é 5;

Exemplos:

Algumas características de bons exemplos:

  • devem ser precisos: ajuda a evitar ambiguidade, deve informar claramente o contexto e como o sistema deveria se comportar em cada caso;
  • devem ser completos: é importante combinar diferentes inputs e pensar nos resultados esperados, além de experimentar com dados;
  • devem ser realistas: pensar sempre em situações reais do usuário (tendo cuidado com informações sigilosas);
  • fáceis de entender: todos os envolvidos devem ler os exemplos e entender sem muita dificuldade. Pode-se usar de abstrações — por exemplo, usar “carro” como exemplo em vez de ficar descrevendo exaustivamente as características do mesmo: carro com 4 rodas, 2 portas etc., a menos que essas características influenciem no resultado final.

Também pode-se usar exemplos para requisitos não funcionais.

Performance: “o sistema precisa importar X registros em Y minutos consumindo Z de cpus”.

UI: protótipos de telas são bons exemplos também.

Automatizar as especificações:

Hoje temos várias ferramentas disponíveis que permitem automatizar as especificações, a mais conhecida é o Cucumber. Aqui, todos os cenários que você escreveu utilizando o formato Gherkin são interpretados e implementados a partir de qualquer outro framework de automação, por exemplo o Appium ou Selenium. A cada nova funcionalidade ou alteração em alguma já existente, você consegue acrescentar ou modificar suas especificações e garantir que o regressivo continua funcionando.

Validar frequentemente:

De nada adiantar ter vários testes automatizados que não são executados continuamente. Depois de tê-los implementados, para garantir que a sua especificação seja viva, é necessário utilizar mecanismos como Integração Contínua para que esses testes (lembrando que são testes elaborados a partir das especificações e que garantem que o que foi desenvolvido atende as necessidades de negócio) sejam executados com frequência (a cada nova mudança por exemplo) de forma a garantir que se houver algum problema, os testes te darão um feedback rápido e indicaram o que deve ser corrigido. Aqui você pode usar ferramentas como o Jenkins, Bamboo, CircleCI, entre outras

Conclusão:

O objetivo desse textão todo era mostrar que desenvolver a partir de especificações não é novidade, já se fala disso há muito tempo em engenharia de software. Mas o ponto mais importante da especificação como conhecemos hoje é a constante descoberta de requisitos relacionados ao produto e a utilização desse conhecimento para gerar uma linguagem de domínio do negócio que será utilizada na escrita de uma documentação viva e executável.

Referências:

https://www.amazon.com/Extreme-Programming-Explained-Embrace-Change/dp/0321278658

https://martinfowler.com/bliki/SpecificationByExample.html

https://dannorth.net/introducing-bdd/

http://www.methodsandtools.com/archive/archive.php?id=23

https://less.works/less/technical-excellence/specification-by-example.html

https://janetgregory.ca/atdd-vs-bdd-vs-specification-by-example-vs/

http://testobsessed.com/wp-content/uploads/2011/04/atddexample.pdf

https://www.amazon.com.br/Specification-Example-Successful-Deliver-Software

Siga a tag codelikeagirlBR para ver nossos posts! 😀

Quer escrever ou traduzir artigos em português para a Code Like A Girl? Se você já faz parte do time de escritoras(es) da Code Like A Girl basta enviar seu artigo diretamente para nossa publicação. Se você ainda não faz parte do nosso time, envie uma mensagem direta para a conta de twitter CodeLikeAGirlBr ou um email para brazil@codelikeagirl.io. Nós avaliaremos seu artigo e ajudaremos a refiná-lo para publicação.