Cucumber – Linguagem Gherkin

Cucumber é uma ferramenta que suporta Behavior Driven Development (BDD), traduzindo ao pé da letra significa: “desenvolvimento orientado por comportamento”, simples assim,ou seja, BDD nada mais é do que descrever os COMPORTAMENTOS de um sistema utilizando linguagem Gherkin.

O que é Gherkin ?

Gherkin é uma linguagem natural que tanto o cucumber quanto todos os interessados(usuários, desenvolvedores, testadores, etc…) entendem, dessa forma, todas as necessidades reais do usuário e projeto são descritas, gerando uma documentação viva e valor pro negócio.

Não altere a estrutura padrão

Como já sabemos, o cucumber utiliza linguagem gherkin, que é uma linguagem natural e de fácil entendimento, porém possui algumas palavras “chaves” e são elas:

Dado (Given)
O “Dado” seria básicamente as pré-condições do cenário.

Quando (When)
O “Quando” serve descrever as ações chave que o usuário executa, resumidamente seria qualquer ação de interação do usuário com o sistema.

Então (Then)
O “Então” visa mostrar as saídas, os resultados das ações executadas, seriam basicamente os resultados esperados.

Exemplo:

Dado número A
Quando somar A+B
Então resultado deve ser C

Portanto mantenha sempre esse padrão: Dado, Quando, EntãoNÃO altere isso e NÃO repita essas palavras no mesmo cenário, para não repetir essas palavras, caímos no segundo tópico das melhores práticas.

Faça uso do “E” e “Mas”

E (And)
O “E” visa complementar qualquer uma das palavras chaves citadas anteriormente, por exemplo:

Dado número A
número B
Quando somar A+B
dividir por C
Então resultado deve ser D

Mas (But)

O “Mas” seria a forma negativa do “Então”, basicamente, quando o resultado esperado for que o usuário NÃO DEVE receber.

Dado número A
E número B
Quando somar A+B
E dividir por C
Então resultado deve ser exibido
Mas não deve ser igual a D

Use “Contexto” e ganhe tempo

Uma regra básica que serve para a vida, se você está fazendo o mesmo trabalho duas vezes, de duas uma, ou você não fez direito, ou algo de errado não está certo.

No cucumber é para isso que existe o contexto(background), para remover aquilo que está sendo repetido em todos os cenários e centralizar em um único lugar, no caso o contexto. Vamos dar um exemplo para ficar bem mais fácil e compreensível.

Reparem que no exemplo acima, a seguinte linha está sendo repetida em todos os cenários:

Dado que eu esteja logado

Vamos ao “Contexto”

Viu como diminuímos o retrabalho? Mais fácil do que fazer regime!

“Contexto” é bom quando usado para coisas simples, não é recomendável utilizar para cenários mais complexos complexas.

“Contexto” é executado antes de cada um dos cenários, mas após qualquer um dos Hooks.

Use tags

#VemNeMimSextaFeira, é praticamente a mesma coisa, só que no lugar da hashtag, utiliza o @. Com isso você consegue filtrar e executar cenários específicos, por exemplo:

@validar_login @crítico @wip @cadastrar_cliente

Pode utilizar mais de uma tag por funcionalidade

Seja mais comportamental do que procedural

Não escreva todos os passo a passo de cada cenário, basta descrever o comportamento. exemplo:

Dado que o usuário esteja na tela de login
Quando preencher o campo usuário
E preencher o campo senha
E clicar no botão entrar
Então o sistema deve logar
e exibir dashboard

Pode isso Arnaldo ? Poder pode, mas não é recomendável, o mais correto seria:

Dado que o usuário esteja na tela de login
Quando informar os dados válidos
Então o sistema realizar o login
E o sistema exibir mensagem de “Bem Vindo”

Sempre descreva na terceira pessoa

Pare de utilizar “eu” nas descrições dos cenários, procure utilizar sempre na terceira pessoa. Reparem no cenário abaixo:

Dado que eu esteja…

Quando eu adiciono…

Não, não é assim! utilize na terceira pessoa.

Dado que o usuário ou o cliente esteja logado

Quando usuário ou cliente adicionar um produto no carrinho

Melhorou ?

Utilize Scenario Outline

Quando os cenários têm validações resultados parecidos, podemos utilizar os Scenarios Outline, ou Esquemas de cenário. Vamos ao exemplo:

Cenário: mostrar o resultado quando executar uma operação de adição
Dado que o usuário esteja na calculadora
Quando pressionar o número 4
pressionar o número 2
escolher adição
Então o sistema devera mostrar o resultado igual à 6

Cenário: mostrar o resultado quando executar uma operação de subtração
Dado que o usuário esteja na calculadora
Quando pressionar o número 4
pressionar o número 2
escolher subtração
Então o sistema devera mostrar o resultado igual à 2

Cenário: mostrar o resultado quando executar uma operação de multiplicação
Dado que o usuário esteja na calculadora
Quando pressionar o número 4
pressionar o número 2
escolher multiplicação
Então o sistema devera mostrar o resultado igual à 8

Repare que são praticamente as mesmas validações, para facilitar tanto na implementação e na manutenção, existe no cucumber os scenarios outline. E ficaria da seguinte maneira:

Cenário: mostrar o resultado quando executar uma operação na calculadora
 Dado que o usuário esteja na calculadora
 Quando pressionar o <número1>
 E pressionar o <número2>
 E escolher a <operação>
 Então o sistema devera mostrar o <resultado>
Exemplo:
    | numero1    | numbero2   |    operação    | resultado|
    |     4      |      2     |      soma      |   6      |
    |     4      |      2     |   subtração    |   2      |
    |     4      |      2     | multiplicação  |   8      |
    |     4      |      2     |     divisão    |   2      |

A primeira linha da tabela representa as variáveis escritas assim <variável> nos cenários e as outras linhas são os exemplos para execução dos testes com seus respectivos resultados esperados.

Viu como fica mais fácil de escrever e manter os cenários? Além de serem mais legíveis também.

Organize Diretórios

Existem outras formas de organizar os diretórios dentro do projeto. Porém uma boa prática é criar uma pasta Features e dentro dela criar as seguintes subpastas: pages, onde vão ficar todos os objetos de cada pagina(não precisa se preocupar com isso agora), specifications, onde vão ficar todos os comportamentos do sistema escrito em cucumber, step_definitions, onde vão ficar todos os passo a passo gerados a partir das nossa especificações e support, onde vão ficar algumas configurações, conforme exemplo abaixo:

Lean no Desenvolvimento de Software

Mary e Tom Poppendieck (gurus de Lean voltado a TI, defensores do agile e autores do livro: “Lean Software Development – An Agile Toolkit” que mostra como os princípios Lean podem ser aplicados em abordagens de desenvolvimento de software ágil) usou a seguinte frase para definir Lean:
“What is Lean?

•  Deliver continually increasing customer value
•  Expending continually decreasing effort
•  In the shortest possible timeframe
•  With the highest possible quality
A journey, not a destination. ”

E acrescentam:  “Acelerar a produção do desenvolvimento de Software é geralmente uma questão de melhorar o processo ao invés de adicionar pessoas. Pare de fazer coisas que o cliente não valoriza! Vista os óculos do cliente! ”

Tentando resumir em uma frase, Lean é um princípio ágil cujo foco é cortar a “gordura” do processo de software, focando na eliminação de desperdícios.

Princípios Lean aplicados ao software:

  1.    Elimine Desperdícios
  2.    Inclua a Qualidade no Processo
  3.    Crie Conhecimento
  4.    Adie Decisões e Comprometimentos
  5.    Entregue o quanto antes
  6.    Respeite as Pessoas e “Empower” a equipe
  7.    Otimize o Todo

Vamos ver os 7 princípios de Lean e como transforma-los em práticas ágeis.

Princípio #1 – Eliminar desperdícios
Desperdícios: tudo aquilo que não agrega valor para cliente final e que não são percebidos pelo cliente. Exemplo: passos extras, processo pesado e rígido, burocracia, documentação que nunca vai ser lida, que está na prateleira juntando poeira – não necessária, etc. Outro tipo de desperdício são trabalhos parcialmente prontos, tudo que começa e não termina, funcionalidades extras que não serão utilizadas, etc.image

  1. Enfim, software útil e de funcionando (de qualidade) é o que vai trazer valor ao cliente. Os sete desperdícios de software:
  2. Inventory = Requirements / Partially done work
  3. Extra Processing Steps = Extra processes, steps
  4. Overproduction = Extra features
  5. Transportation = Handoffs, tasks switching
  6. Waiting = Waiting
  7. Defects = Defects
  8. Motion = Finding Information
Não se iluda, embora alguns sejam gritantes não é fácil identificar alguns tipos de desperdício. É preciso aprender a enxergar os desperdícios e existem algumas práticas e exercícios que podem ajudar, tais como: Seeing waste e Value Stream mapping.
Vejamos os tipos de desperdícios mais detalhadamente:
1 – Requisitos
Requisitos, especificados muito cedo que perdem sua credibilidade, eficácia e compromete a usabilidade do sistema.
Trabalho incompleto (“em-progresso”) – Parcialmente feitos
Trabalhos parcialmente iniciados / terminados tendem a se tornar obsoletos.
O maior problema é não ter idéia se eventualmente funcionam ou não. Enquanto os trabalhos não são integrados, não podem ser utilizados e não temos como saber quais problemas podem aparecer. Funcionalidades pela metade apenas atravancam o caminho para trabalhos que poderiam ser feitos. Tornando-se facilmente obsoleto.
Consomem recursos sem trazer retorno.
Exemplos: Documentação não codificada, código não sincronizado, código não testado, código não implantado.
2 – Processos/Passos a mais
Burocracia, atividades, métricas, etc que não geram valor e que diminui o tempo de resposta.
Você alguma vez já se perguntou, toda aquela documentação e papelada é realmente necessária?
Documentação desnecessária e documentação que são esquecidos ou perdem valor e se tornam obsoletos ou documentos que ninguém se importa em ler.
O seu cliente realmente acha que isso torna o produto dele mais eficiente?
Dica: Faça esse questionamento para descobrir quando a documentação tem valor agregado : Tem alguém esperando ou dependendo do que você esta produzindo?.
Ainda assim lembre-se: Mantenha-o enxuto, em alto-nível e documente o mais tardar possível.
3 – Funcionalidades a mais
80% das funcionalidades implementadas não são utilizadas.
20% das funcionalidades é que são realmente úteis.
Código não-utilizado introduz complexidade e a complexidade é um inimigo da manutenção. Mais código para ser mantido. Mais testes para serem realizados. Mais documentos de especificação para serem criados. Se o código não é necessário agora colocá-lo no sistema é desperdício.
4 – Troca de tarefas (Task switching, Handoffs)
Corrida de revezamento deve ser substituída pela equipe multi-funcional.
Quanto maior os handoff’s maior é a perda de conhecimento. Organizar pessoas em múltiplos projetos é outra forma de desperdício.
Quanto tempo se perde para parar uma determinada atividade e iniciar outra, relembrar onde parou, concentrar-se e finalmente produzir algo?
5 – Atrasos
Atrasos na entrega, atrasos em geral são puro desperdício e irão gerar aumento do custo do projeto.
Em muitos casos, atrasos são apenas a ponta do iceberg para problemas muito maiores.
Espera: Um dos maiores desperdícios no desenvolvimento de Software é a espera para que as coisas aconteçam. Espera para o início do projeto, pela montagem da equipe, espera pela produção de documentação extensa, espera por processo de revisão ou aprovação, espera para testar, etc.  Veja, analise o que deve ser mantido, o que agrega valor e o que é puro despedício.
6 – Defeitos
Equipes ágeis se esforçam ao máximo para evitar defeitos.
 “Inspecionar para prevenir defeitos é bom;
Inspecionar para encontrar defeitos é desperdício” — Shigeo Shingo
Defeitos (Bugs) não agregam valor, não satisfazem o cliente, e custam muito muito caro.
7 – Movimento
Tempo e esforço gasto para encontrar informações.
Equipes ágeis valorizam a conversa e por isso trazem o cliente para perto, não devemos perder tempo lendo páginas e páginas de um documento para encontrar uma informação que ao mesmo tempo por estar na forma escrita muitas vezes são imprecisas e pode trazer mais dúvidas do que resolver o problema.
Princípio #2 – Qualidade embutida
Qualidade é inegociável. Entregue qualidade intrínseca e explícita aos seus clientes, se eles perceberem isso, significa que foi uma entrega de qualidade. Mary e Tom Poppendieck em seu livro identificaram duas dimensões de integridade: integridade percebida e integridade conceitual. A integridade percebida significa que a totalidade do produto alcança um equilíbrio entre as funções, usabilidade, confiabilidade, economia e isso encanta o cliente. A integridade conceitual significa que os conceitos centrais do sistema de trabalho em conjunto são facilitados e coesos. Essa última é fator crítico de sucesso para a integridade percebida.
Um produto possui integridade percebida quando o cliente o experimenta e diz: Isso! Era exatamente isso que eu queria! Software com integridade possui boas arquiteturas, possuem um alto nível de usabilidade e facilidade de uso, são fáceis de dar manutenção, de adaptar e de estender.
Dicas:
  • Não verificar a qualidade só no final, verificar durante todo processo e também toda equipe testa!
  • Quanto antes um problema é verificado mais barato ficará
  • Foco na prevenção, não na verificação no final do processo – Ao invés de se esforçar para gerenciar defeitos, evite-os.
  • “Logar” defeitos é desperdício, corrija-os imediatamente.
Práticas sugeridas para promover a qualidade:
  • 4 quadrantes de teste
  • TDD  – Test Driven Development
  • Refactoring
  • Integração contínua
  • Code review / code inspection
  • Standards
  • Testes contínuos e automatizados
Princípio #3 – Criar conhecimentos
Desenvolvimento é um exercício de descoberta, enquanto produção é um exercício de reduzir a variação. Desenvolvimento é como fazer uma nova receita, enquanto produção é como fazer um prato. Receitas são formuladas por chefes de cozinha experientes que de certa forma desenvolveram habilidades e capacidade de combinar os ingredientes disponíveis para produzir o prato desejado. Desenvolver uma receita é um processo de descoberta, até os chefes mais experientes produzem diversas variações de um novo prato, fazem iterações, experimentações, até encontrar a melhor combinação de ingredientes que resulte em um prato rápido e sabor agradável. Não se espera que os chefes obtenham uma receita perfeita de primeira; espera-se produzir diversas variações como parte do processo de aprendizagem. Desenvolvimento de software é melhor concebido se este fizer parte de um processo de aprendizado similar ao de criar uma nova receita. A melhor abordagem para melhorar o ambiente de desenvolvimento de software é pela expansão do conhecimento.
Práticas sugeridas para promover o conhecimento:
  • Ciclos de feedback e inspeções e adaptações;
  • Desenvolvimento iterativo;
  • Equipes pequenas e cross-functional;
  • Treinamentos e Mentoring;
  • Criação e utilização de standards, guidelines e qualquer outro artefato;
  • Code Reviews;
  • Meios de compartilhamento de informações como um Blog ou Wiki;
Princípio #4 – Adiar decisões / compromissos
O principal conceito deste princípio é diminuir as incertezas retardando as decisões até que possam serem feitas com base em acontecimentos mais firmes, previsíveis e conhecidos. Decisões tardias tendem a ser mais acertadas porque as melhores decisões são feitas baseadas em fatos, e não em suposições ou especulações. Uma estratégia chave para adiar decisões/comprometimentos quando desenvolvendo um sistema complexo e com muitas incertas é usar a capacidade e práticas que permitam abraçar as mudanças tardiamente.
Práticas sugeridas para adiar compromissos:
  • Iterações
  • Planning meetings
  • Behaviour/Feature Driven Development
  • Outros
Princípio #5 – Entregar rápido
Sem entregas rápidas não é possível colher feedback. Sem entregas rápidas não é possível aprender com erros. Velocidade na entrega garante que o cliente receberá o que ele precisa hoje e não o que ele precisava ontem.
Práticas sugeridas:
Princípio #6 – Respeitar as pessoas
Envolver os desenvolvedores nos detalhes das decisões técnicas é fundamental para o atingimento da exelência.
Dicas:
  • Um ambiente que favoreça o desenvolvimento das pessoas.
  • Uma empresa que respeita as pessoas, assim as pessoas irão respeitar a empresa
O Software produzido é como um espelho da equipe de desenvolvimento.
Para que as pessoas possam assumir responsabilidades, se sentir motivados e atuar como uma equipe eles precisam de confiança e de respeito.

Práticas sugeridas para promover o empowering do time:

  • Auto-gestão
  • Trabalho em equipe
  • feedback
 

Princípio #7 – Otimizar o todo

Otimizar desde o começo até o final:
  • Utilize Métricas
  • Diminua o número de métricas de desempenho individual mas valorize o desempenho da equipe.
  • Meça para cima:
  • Tempo de ciclo +Mapa de Fluxo de Valor
  • ROI + Modelo de Lucros e Perdas
  • Satisfação do Cliente + Entendimento das suas necessidades
Para tornar o seu processo ágil, pense Lean!
Mas lembre-se Lean requer uma mudança da cultura e dos hábitos organizacionais para que esta possa usufruir das melhorias de performance que um processo enxuto pode proporcionar.
É UMA MUDANÇA DE MENTALIDADE E COMPORTAMENTO !