Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adicionando os trechos restantes sobre testes #16

Merged
merged 15 commits into from
Oct 27, 2020
4 changes: 4 additions & 0 deletions manuscript/Book.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ o_que_e_pr.md
estrategia_de_testes.md
por_que_escrever_testes.md
definindo_testes.md
desafios_em_testes.md
testes_continuous.md
testes_e_tomada_de_decisao.md
testes_conclusao.md
migracao_banco_dados_relacionais.md
o_que_tem_que_ter_no_pipeline.md
4 changes: 3 additions & 1 deletion manuscript/definindo_testes.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ São 3 as categorizações:
- Médio: aqui temos testes que executam múltiplos processos mas ainda assim sem acessar componentes externos, nessa categoria entram os testes que acessam banco de dados por exemplo;
- Grande: esses testes são os que necessitam de uma maior complexidade para execução, nesse momento os sistemas já estão integrados. São mais lentos e menos determinísticos.

Dentro de cada um desses tipos de teste podemos ainda categorizar quais características de qualidade estão sendo avaliadas em funcionais e não funcionais. Quando falarmos de **testes funcionais** nos referimos à validação de características relacionadas ao comportamento da aplicação durante a utilização do sistema; quando falarmos de **testes não funcionais**, nos referimos à avaliação de aspectos de qualidade como desempenho, usabilidade, compatibilidade e outras "idades" onde o objetivo é validar essas características ao invés da funcionalidade em si.

### Testes Pequenos

#### Testes Unitários
Expand Down Expand Up @@ -360,7 +362,7 @@ Seja o seu serviço um consumidor ou provedor, é importante se preocupar com os

### Testes Grandes

Existem alguns pontos cegos entre os testes que comentamos anteriormente:
Existem alguns pontos não cobertos entre os testes que comentamos anteriormente:

- Se estamos usando dublês por exemplo, quem garante que aqueles dublês são fiéis a implementação real? E se o time esquecer de atualizar um dublê de um comportamento que foi alterado?
- Questões de configuração de ambiente, e se o time esquecer de configurar aquela variável na especificação do container? E se tiver um problema na conexão do container da aplicação com o banco de dados?
Expand Down
17 changes: 9 additions & 8 deletions manuscript/desafios_em_testes.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
## Desafios

Agora que já entendemos a importância de ter testes para garantir nossas entregas em produção é importante falarmos um pouco sobre os desafios que ter esses testes automatizados podem trazer e algumas sugestões sobre como lidar com eles.

### Testes Intermitentes
TODO

### Consumo de Recursos
TODO
Como vimos anteriormente, temos diferentes tipos de teste e cada um deles abraça diferentes níveis dentro da nossa aplicação. Alguns estão apenas no escopo reduzido de uma função, enquanto outros exercitam diferentes componentes incluindo serviços externos e infraestrtura. Quanto mais integrados os testes são maior a chance de serem intermitentes. Testes intermitentes são aqueles que uma hora passam e na outra falham sem nenhum motivo aparente. É inevitável ter algum nível de intermitência posto que trabalhamos cada vez mais com aplicações complexas e cheias de integração, a diferença está na estratégia que adotamos para mitigar esse risco de intermitência. A primeira dica aqui é não testar serviços de terceiros dentro do seu fluxo de desenvolvimento, prefira mockar esses componentes porque caso esse serviço externo esteja indisponível em ambiente de teste, seu fluxo não será prejudicado. Testes intermitentes podem ser causados por componentes internos também, por exemplo se o seu teste utiliza dados de um teste anterior para seguir e esse teste anterior falhar ou demorar mais do que o normal, seu teste irá falhar por um motivo externo a ele mesmo.

### Isolar as falhas
TODO
Ao se deparar com um teste intermitente, a primeira coisa que você deve fazer é movê-lo para uma outra suíte, que normalmente chamamos de quarentena e ali analisar esse teste de forma isolada e sem atrapalhar o dia a dia do time.

### Quais testes rodar no pré-hook
TODO
### Consumo de Recursos

Outro ponto importante quando falamos de testes médios e grandes é o consumo de recursos. Nem sempre você terá disponível um ambiente cópia de produção para executar os seus testes, seja pela dificuldade de reprodução desse ambiente ou até mesmo pelo custo de mantê-lo. Para isso você pode adotar algumas estratégias que te auxiliem a ter um ambiente que atenda a todas as necessidades. Para componentes externos você pode utilizar um serviço como [WireMock](http://wiremock.org/) para ser o servidor dublê desse componente externo. Você pode também utilizar um ambiente compartilhado com outros times (aqui tome cuidado porque essa decisão pode aumentar sua intermitência posto que existem várias pessoas manipulando o mesmo ambiente).

### Gestão das falhas
TODO

Por último, é muito importante fazer a gestão dos testes que falharem e para isso é necessário ter visibilidade do que está acontecendo através de relatórios de execução de testes e fluxos automáticos que parem a "linha de produção" quando algum teste falha. Isso vai te ajudar a entender melhor qual foi o motivo da falha do teste, se é um caso de intermitência ou um bug mesmo.
10 changes: 9 additions & 1 deletion manuscript/testes_conclusao.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## Conclusão

TODO
Uma estratégia de testes que traga confiança para que você introduza mudanças no código requer a utilização de diferentes tipos de teste, testes pequenos, testes médios e testes grandes, onde cada um vai ser responsável pela cobertura de diferentes componentes da sua aplicação, desde as pequenas funções até o fluxo completo de uma compra on-line por exemplo. Quanto mais complexos os testes forem em termos de componentes envolvidos, mais recursos serão necessários para executá-los e mais tempo também.

Apesar dos desafios envolvidos é um fato que testes são indispensáveis em desenvolvimento de software moderno e são a peça chave para fazer entregas em produção com segurança e qualidade.

Prefira ter uma cobertura maior em testes pequenos e médios onde a complexidade de componentes é menor e seus testes serão mais assertivos e menos intermitentes. Mas isso não significa não ter testes grandes, eles também tem sua importância em cobrir pontos que não são abraçados pelos tipos anteriores, aqui prefira validar os comportamentos mais focados na jornada do usuário.

E de nada adianta ter todos esses testes mas não executá-los de forma automatizada no seu pipeline. Quanto mais cedo eles forem executados mais cedo eles te darão o feedback de como a mudança feita afetou o código existente e mais cedo você consegue investigar e resolver os problemas.

A última dica é se preocupar com o design dos seus testes e não apenas em automatizá-los, os testes devem ser úteis e encontrar problemas caso eles apareçam, pensar em testes desde o início do projeto faz com que a aplicação já nasça com cultura de testes.
31 changes: 25 additions & 6 deletions manuscript/testes_continuous.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
## Testes Contínuos

### Pré-Hook
TODO
Depois de entender quais testes fazem sentido dentro do seu projeto, é hora de encaixar todos esses testes dentro da esteira de desenvolvimento sempre pensando em como viabilizar a produtividade, por isso executamos os testes o mais cedo possível dentro do ciclo para encontrar os problemas e já corrigí-los antes que impactem o cliente final. Esse é o famoso conceito de *shift-left* que ouvimos por aí, trazer o feedback que os testes nos dão para o nosso dia a dia.

### Pós-Hook
TODO
### Pré-Submit

Pré-submit é o momento antes de enviar as alterações para o repositório. Nesse momento devemos executar os testes que são mais rápidos e confiáveis, como os testes pequenos que vimos na seção anterior. Eles podem ser executados em segundos ou no máximo minutos e já vão informar se houver algum problema antes mesmo que isso vá para o repositório. Aqui podemos usar ferramentas específicas de cada linguagem para criar esse tipo de regra, se você está trabalhando com JavaScript, por exemplo, existe o [Husky](https://www.npmjs.com/package/husky) que você pode configurar no seu package.json com os comandos que serão executados automaticamente quando você fizer o `git push`. No caso do JavaScript por exemplo, você configuraria para executar `npm run test`.
gomex marked this conversation as resolved.
Show resolved Hide resolved

gomex marked this conversation as resolved.
Show resolved Hide resolved
```javascript
"husky": {
"hooks": {
"pre-push": "npm run test",
"...": "..."
}
},
```

Você pode conferir o exemplo completo neste [repositório](https://github.com/samycici/auth-app/blob/master/package.json#L59-L64).

### Pós-Submit

Depois que o código é enviado para o repositório, partimos para o processo de integrar esse novo código no código já existente e garantir que tudo continua funcionando, aqui já executamos os testes médios. Se tudo correr bem, temos uma versão candidata que pode ser lançada em ambiente de teste. Esse é o primeiro passo do seu pipeline.

### Versão Candidata
TODO

Como resultado do passo anterior você terá sua versão candidata, ou seja, um pacote com o código já alterado e que passou por todos os testes. Depois que temos uma versão candidata já publicada em algum ambiente de testes é a hora de executar os testes grandes para validar que os fluxos de negócio estão funcionando de forma integrada com todos os componentes envolvidos. Aqui você pode ter de 1 a N ambientes de teste, algumas empresas tem o ambiente de staging, pré-prod, homolog, os nomes são variados, mas o importante é ter ambientes de teste onde a sua versão será publicada e testada antes de prosseguir para produção.

Depois dessa validação finalmente podemos enviar a nossa mudança para ambiente de produção. :rocket:

### Produção
gomex marked this conversation as resolved.
Show resolved Hide resolved
TODO

Chegando em produção nós podemos reaproveitar os testes grandes e executar os que sejam mais relevantes para garantir que os fluxos principais continuam funcionando, além de se aproveitar das informações que recebemos dos monitoramentos (teremos uma seção dedicada a falar sobre isso nos próximos capítulos) para continuar observando que a mudança introduzida não causou nenhum problema.
4 changes: 3 additions & 1 deletion manuscript/testes_e_tomada_de_decisao.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
## Como usar a estratégia de testes para tomada de decisão

TODO
Sua estratégia de testes vai ser a grande aliada na tomada de decisão desde a chegada das demandas até o resultado final na mão do cliente. Com a análise estática e os testes de mutação você terá uma visibilidade melhor da qualidade das entregas e isso poderá ser usado de entrada para criação de tarefas que tenham por objetivo aumentar a confiança nos testes e garantir que as partes mais críticas estão sendo bem testadas.

Durante o fluxo de desenvolvimento, o resultado dos testes vai te ajudar a entender se você pode prosseguir e lançar uma nova versão por exemplo, ou se existe algum problema que necessita de ação imediata. E após entregar uma nova funcionalidade para o cliente, você será capaz de avaliar se realmente a sua estratégia está trazendo resultados (software de qualidade em produção) ou se os clientes continuam enfrentando problemas e você precisa entender quais os pontos dentro do processo precisam ser modificados para endereçar isso.