Engenharia de Software Moderna
Cap. 8 - Testes
Prof. Marco Tulio Valente
https://engsoftmoderna.info
Licença CC-BY; permite copiar, distribuir, adaptar etc; porém, créditos devem ser dados ao autor dos
slides 1
Relembrando Cap. 1 (Introdução)
2
Testes de Software
● Verificam se um programa apresenta um resultado
esperado, ao ser executado com alguns casos de teste
● Podem ser:
○ Manuais
○ Automatizados (nosso foco)
3
Testes de software mostram a presença de bugs,
mas não a sua ausência. --
Edsger W. Dijkstra
principal limitação
principal objetivo
4
Defeitos, Bugs, Fallhas
● O seguinte código possui um defeito (defect) ou um bug:
if (condition)
area = pi * raio * raio * raio; // código defeituoso;
● O certo é "área é igual a pi vezes raio ao quadrado"
● Quando o código for executado ele vai causar uma falha
(failure); ou seja, um resultado errado.
5
Verificação vs Validação
● Verificação: estamos implementando o sistema
corretamente?
○ De acordo com os requisitos e especificações
● Validação: estamos implementando o sistema correto?
○ Aquele que os clientes querem
○ Testes de aceitação com os usuários
6
Testes com Métodos Ágeis
● Automatizados
● Algumas vezes, implementados antes do código (TDD)
● Escritos pelo próprio desenvolvedor do código sob testes
● Outras funções:
○ Detectar regressões
○ Documentação
7
Pirâmide de Testes
8
Tipos de Teste
Unidade Integração Sistema
9
Testes de Unidade
(nosso principal objeto de estudo)
10
Testes de Unidade
● São testes automatizados
de pequenas unidades de
código (normalmente, classes)
11
Primeiro Exemplo: teste de unidade para
uma classe Stack
12
Classe
13
Classe Teste (também é uma classe)
14
Anatomia de um Teste de Unidade
Métodos de teste (sem
parâmetros,
começam com test)
Fixture (contexto)
Chama método sob teste
Comando assert: verifica
se resultado é aquele
esperado; se não for, lança
uma exceção
15
Framework de testes: xUnit
Testes passaram!
16
Framework de testes: xUnit
Testes passaram!
Algum teste falhou!
17
Mais métodos de teste
18
Executado antes de qualquer método @Test
19
Parâmetros: valor esperado (3) e valor
encontrado (size), nesta ordem.
Mensagem quando o assert falha:
Expected 3 but found [valor]
20
assert não seria útil aqui; pois ele não
seria alcançado.
21
Mais alguns conceitos sobre testes
22
Testes tiveram profundo impacto na
indústria de software
23
"Testes de unidade são amplamente usados no Google. Todo
código de produção deve ter testes de unidade"
"No Facebook, engenheiros são responsáveis pelos testes de
unidade de qualquer código novo que eles desenvolvam."
"Código sem testes é código ruim"
-- Michael Feathers
24
Benefícios
● Detectar bugs
○ Na classe C sendo implementada ou modificada
○ Em uma outra classe; mudança em C pode afetar C'
(regressão)
● Documentação
25
Princípios FIRST
● Rápidos (Fast)
● Independentes (ordem não é importante)
● Determinísticos (Repeatable, não-flaky ou não-erráticos)
● Auto-verificáveis (Self-checking): barra verde ou vermelha
● Timely (escritos o quanto antes)
26
Por que alguns testes tem comportamento flaky?
Fonte: An Empirical Analysis of Flaky Tests, FSE 2014.
Concorrência
(65% dos casos)
E se "region server" demorar mais de 2s para dar o "ping"?
27
Número de assert por testes
● Na maioria das vezes, deve-se ter um único assert / teste
28
Número de assert por testes
● Mas existem exceções razoáveis ...
Quantos testes eu tenho que escrever?
30
Cobertura de Testes
● Cobertura de testes = (número de comandos executados
pelos testes) / (total de comandos do programa)
31
100% de cobertura
32
amarelo: apenas um dos
branches do comando de
decisão é avaliado
vermelho: esse comando
não é coberto pelos testes
33
Qual a cobertura de testes ideal?
● Varia de projeto para projeto …
● Mas não precisa ser 100%… mas pelo menos 60%,
segundo alguns autores
34
Exemplo: Google
The median is 78%, the 75th percentile 85% and 90th percentile 90%.
https://docs.google.com/presentation/d1god5/fDDd1aP6PwhPodOnAZSPpD80lqYDrHhuhyD7Tvg/edit#slide=id.g3f5c82004_99_135 35
https://testing.googleblog.com/2020/08/code-coverage-best-practices.html
36
Mas cuidado!
Quando uma medida torna-se uma meta, ela deixa
de ser uma boa medida. -- Lei de Goodhart
37
Outras definições de cobertura
● Cobertura de funções
● Cobertura de chamadas de funções
● Cobertura de branches (um if sempre gera 2 branches)
38
Testabilidade
39
Exemplo: Servlet
Difícil testar doGet, pois ele tem
dependências (parâmetros) para o
pacote de Servlets de Java
40
Solução: extração da regra
de domínio para uma
classe separada (e mais
fácil de testar)
41
Mocks
42
Exemplo motivador:
Método que pesquisa dados de um
livro em um serviço remoto
43
Problema:
Testes de unidade devem ser
rápidos e testar pequenas
unidades
Unidade Integração
44
Solução: Mocks
● Objeto que emula um objeto real
● Porém, é bem mais simples que o objeto real
45
Simula pesquisa em um único ISBN
46
Teste agora usa o mock
47
Frameworks de Mocks
48
Exemplo: Mockito
● Facilita a criação de mocks
● E a "programação" do comportamento do mock, via uma
linguagem de domínio específico (DSL)
● Dispensa a implementação de um mock "manual", como
estudamos antes
49
Cria um mock
Programa o comportamento desse mock
50
Explore e execute o teste anterior
https://repl.it/@mtvalente/ExemploMocks
Como o repl.it é uma IDE online, a compilação e execução desse
código costuma demorar um pouco
51
Popularidade de mocks via Mockito
Davide Spadini et al. Mock objects for testing Java systems - Why and how
developers use them, and how they evolve. EMSE 2019.
52
Popularidade de mocks: Mockito & manuais
Gustavo Pereira, Andre Hora. Assessing Mock Classes:
An Empirical Study. ICSME 2020.
53
Desenvolvimento Dirigido por Testes
(TDD)
54
TDD
● Uma das práticas de programação propostas por XP
● Ideia simples: escrever o teste T antes da classe C
55
Benefícios
● Evita que os devs esqueçam de escrever os testes
● Incentiva a escrita de código com testabilidade; cobertura
pode chegar a 90%
● Melhora o design e/ou usabilidade do código; pois o dev
passa a ser o primeiro cliente do seu código
56
Ciclo TDD
57
Exemplo de TDD: carrinho de compras
58
Vermelho
59
Ainda vermelho, mas
pelo menos compilando
Implementação ainda provisória
60
Primeiro Verde
Só mesmo para ter uma "pequena
vitória" … baby steps
61
Agora um verde mais real
62
Amarelo: podemos refatorar e melhorar o código?
Por exemplo, encapsular esses
campos
63
Próximo passo?
● Precisamos de mais alguma funcionalidade?
● Se sim: mais um ciclo TDD (vermelho-verde-amarelo)
64
Testes de Integração
65
Testes de Integração
● Testam uma funcionalidade ou serviço (do seu sistema)
● Incluindo classes e serviços externos (BD, por exemplo)
66
Relembrando ...
Unidade Integração Sistema
67
Exemplo: Agenda de Compromissos
68
Teste de integração (também via JUnit,
mas sem mocks)
69
Dois testes de unidade, zero testes de integração
70
Testes de Sistema
71
Testes de Sistema
● Testes ponta-a-ponta (end-to-end)
● Testam o sistema inteiro; via sua interface externa
72
Exemplo: Testes de Sistema Web
usando Selenium
73
Robô que entra em uma página,
preenche campos, clica em
botões, testa respostas, etc
74
Anti-padrões de pirâmide de testes: "casca de
sorvete" e "ampulheta"
75
Fonte: Software Engineering at Google. O'Reilly, 2020.
Outros Tipos de Testes
76
Outros Tipos de Testes
● Caixa-preta (funcionais)
● Caixa-branca (estruturais)
● Aceitação (manual)
● Alfa e beta (manual)
● Requisitos não-funcionais
77
Fim
78