1
|
|
2
|
- Software Estimation: Demystifying the Black Art (Best Practices
(Microsoft))
by Steve McConnell
- Test-Driven Development: By Example, Kent Beck -
Addison-Wesley, 2003, ISBN
0-321-14653-0
- Refactoring: Improving the Design of Existing Code, Martin
Fowler -
Addison-Wesley, 1999 SBN
0-201-48567-2
|
3
|
- Introdução
- TDD
- Testes em XP
- Boas Práticas de Teste
|
4
|
|
5
|
|
6
|
|
7
|
- Para verificar a validade de uma implementação com respeito aos
requisitos.
- Para especificar formalmente o critério de aceitação de uma
implementação pelo cliente.
- Para detalhar o design e a forma de uso da funcionalidade.
- Para garantir que não quebramos nada quando fazemos uma alteração.
|
8
|
- Teste:
- Execução de um programa através de procedimentos manuais ou
automáticos.
- Revisão/Inspeção:
- Revisão de produtos de trabalho por especialistas: documentos,
código-fonte de programas.
- Prova/Verificação:
- Procedimento sistemático e formal para garantir que uma implementação
está correta.
- Métrica:
- Aferição de características mensuráveis dos produtos de trabalho ou da
execução de programas.
|
9
|
- à Levantamento de
requisitos
- à Análise
- àDesign de alto nível
- à Design detalhado
- à Codificação
- + teste unitário
- à Integração
- + teste de integração
- à Implantação
- + teste de sistema
- àManutenção
- + teste de regressão
|
10
|
- s. f. (do italiano cascata)
- 1. Queda de água em cachoeira, natural ou artificial;
- 2. Brasil, gíria: Conversa fiada; mentira; bazófia
- Fonte:
- Dicionário Universal da Língua Portuguesa
- http://www.priberam.pt/DLPO/
|
11
|
- Inspeções são sempre mais eficientes que testes na contenção de
defeitos.
- Usar uma matriz para mapear casos de teste X requisitos.
- Só se pode rodar os testes depois de implementar.
- Fazer certo da primeira vez, para evitar retrabalho.
- Procedimentos formais garantem uma implementação correta.
|
12
|
- Definir todos os casos de teste antes de começar a programar.
- Se funciona mais ou menos, é melhor não mexer.
- Torcer para o teste dar certo na primeira rodada.
- Automatizar os testes é muito caro: não compensa.
- É impossível que quem vai rodar os testes não entenda este roteiro: está
super claro.
- Vai pegar mal documentar que esse teste falhou: vai ferrar as nossas
métricas.
|
13
|
- O teste passou: está 90% certo.
- Testes (ou inspeções, ou provas, ou métricas) garantem qualidade.
- Quem testa não pode ser quem programou.
- Revisar o código muito cuidadosamente antes de compilar: não depender do
compilador para detectar erros triviais.
- Rodar exaustivamente testes de mesa antes de digitar o código.
|
14
|
|
15
|
|
16
|
|
17
|
- TDD sits nicely in the XP “way of doing things”
- TDD can be used without practicing XP
- Writing articles and giving presentations is one such way of achieving
that goal
- To reduce the amount of re-testing that is required
- Especially with legacy applications
- To avoid introducing new bugs after refactoring existing code
|
18
|
|
19
|
- TDD is a technique whereby you write your test cases before you write
any implementation code
- Tests drive or dictate the code that is developed
- An indication of “intent”
- Tests provide a specification of “what” a piece of code actually does
- Some might argue that “tests are part of the documentation”
|
20
|
- “Before you write code, think about what it will do.
- Write a test that will use
the methods you haven’t even written yet.”
- Extreme Programming Applied: Playing To Win
- Ken Auer, Roy Miller
- “The Purple Book”
- A test is not something you “do”, it is something you “write” and run
once, twice, three times, etc.
- It is a piece of code
- Testing is therefore “automated”
- Repeatedly executed, even after small changes
|
21
|
- In Extreme Programming Explored (The Green Book), Bill Wake describes
the test / code cycle:
- Write a single test
- Compile it. It shouldn’t compile
because you’ve not written the implementation code
- Implement just enough code to get the test to compile
- Run the test and see it fail
- Implement just enough code to get the test to pass
- Run the test and see it pass
- Refactor for clarity and “once and only once”
- Repeat
|
22
|
|
23
|
- Desenvolvimento Guiado por Testes,
define que antes de criarmos um código novo, devemos escrever um teste
para ele.
- E testes serão usados como métrica em todo o tempo de vida do projeto.
|
24
|
|
25
|
- Programmers dislike testing
- They will test reasonably thoroughly the first time
- The second time however, testing is usually less thorough
- The third time, well..
- Testing is considered a “boring” task
- Testing might be the job of another department / person
- TDD encourages programmers to maintain an exhaustive set of repeatable
tests
- Tests live alongside the Class/Code Under Test (CUT)
- With tool support, tests can be run selectively
- The tests can be run after every single change
|
26
|
- Bob Martin:
- “The act of writing a unit test is more an act of design than of
verification”
- Confidence boost
- By practicing TDD, developers will strive to improve their code –
without the fear that is normally associated with code changes
- Isn’t the green bar a feel good factor?
- Remove / Reduce reliance on the debugger
- No more “debug-later” attitudes
|
27
|
- The programmers should write the tests
- The programmers can’t wait for somebody else to write tests
- TDD promotes “small steps”, and lots of them
- Small steps: the shortest distance between two points
- Your destination is closer…
|
28
|
|
29
|
|
30
|
- Testes do programador
- Testes unitários (caixa branca)
- Codificados pelo desenvolvedor.
- Detalham o design da implementação.
- Rodam muito rápido.
- Todo código integrado roda 100% desses testes.
|
31
|
- Testes do cliente
- Testes de sistema (caixa preta)
- Escritos pelo cliente.
- Detalham os critérios de aceitação de uma implementação.
- Podem demorar mais.
- Mais difíceis
- Quando estão rodando 100%, o produto pode ser entregue.
|
32
|
|
33
|
|
34
|
- Entrada: estórias de usuário (requisitos), arquitetura
- Escreva um teste para uma porção ridiculamente pequena da
funcionalidade.
- Compile e rode o teste.
- Escreva o mínimo código funcional para passar o teste (com possível
enganação). Compile.
- Compile e rode o teste
- Melhore o teste para desvendar a enganação, se houver Vá para (2)
- Melhore (refatore) o código funcional. Vá para (2)
|
35
|
- Simplificando
- Depurar - o que se faz quando se sabe que o programa não funciona;
- Teste - tentativas sistemáticas de encontrar erros em programa que você
“acha” que está funcionando.
- “Testes podem mostrar a presença de erros, não a sua ausência
(Dijkstra)”
|
36
|
- Se possível escreva os testes antes mesmo de escrever o código
- quanto antes for encontrado o erro melhor !!
|
37
|
- Teste o código em seus limites;
- Teste de pré e pós condições;
- Uso de premissas (assert);
- Programe defensivamente;
- Use os códigos de erro.
|
38
|
- Para cada pequeno trecho de código (um laço, ou if por exemplo)
verifique o seu bom funcionamento;
- Tente uma entrada vazia, um único item, um vetor cheio, etc.
|
39
|
- Solução possível
- Não existe uma única resposta certa
- A única resposta claramente errada é ignorar o erro !!
- Ex: USS Yorktown.
|
40
|
- Em C e C++ use <assert.h>
- ex:
- assert (n>0);
- se a condição for violadada:
- Assertion failed: n>0, file avgtest.c, line 7.
- Ajuda a identificar “culpados” pelos erros
|
41
|
- Tratar situações que não “podem” acontecer
|
42
|
- Checar os códigos de erro de funções e métodos;
- você sabia que o scanf retorna o número de parâmetros lidos, ou EOF ?
- Sempre verificar se ocorreram erros ao abrir, ler, escrever e
principalmente fechar arquivos.
- Em java sempre tratar as possíveis exceções
|
43
|
- Teste incrementalmente
- durante a construção do sistema
- após testar dois pacotes independentemente teste se eles funcionam
juntos
- Teste primeiro partes simples
- tenha certeza que partes básicas funcionam antes de prosseguir
- testes simples encontram erros simples
- teste as funções/métodos individualmente
- Ex: teste de função que faz a busca binária em inteiros
|
44
|
- Conheça as saídas esperadas
- conheça a resposta certa
- para programas mais complexos valide a saída com exemplos conhecidos
- compiladores - arquivos de teste;
- numéricos - exemplos conhecidos, características;
- gráficos - exemplos, não confie apenas nos seus olhos.
|
45
|
- Verifique as propriedades invariantes
- alguns programas mantém propriedades da entrada
- número de linha
- tamanho da entrada
- freqüência de caracteres
- Ex: a qualquer instante o número de elementos em uma estrutura de
dados deve ser igual ao número de inserções menos o número de
remoções.
|
46
|
- #include <stdio.h>
- #include <ctype.h>
- #include <limits.h>
- unsigned long count[UCHAR_MAX+1];
- int main(void) {
- int c;
- while ((c = getchar()) !=
EOF){
- count[c]++;
- }
- for(c=0; c <= UCHAR_MAX;
c++){
- printf(``%.2x %c %lu\n’’, c,
isprint(c) ? c: `-’,
count[c]);
- return 0;
- }
|
47
|
- Compare implementações independentes
- os resultados devem ser os mesmos
- se forem diferentes pelo menos uma das implementações está incorreta
- Cobertura dos testes
- cada comando do programa deve ser executado por algum teste
- existem profilers que indicam a cobertura de testes
|
48
|
- Testes manuais
- Testes automatizados
- devem ser facilmente executáveis
- junte em um script todos os
testes
|
49
|
- Teste de regressão automáticos
- Comparar a nova versão com a antiga
- verificar se os erros da versão antiga foram corrigidos
- verificar que novos erros não foram criados
- Testes devem rodar de maneira silenciosa
|
50
|
|
51
|
- Crie testes autocontidos
- testes que contém suas próprias entradas e respectivas saídas esperadas
- programas tipo awk podem ajudar
- O quê fazer quando um erro é encontrado
- se não foi encontrado por um teste
- faça um teste que o provoque
- Como fazer um testador automático para o programa de freqüência ?
|
52
|
- As vezes para se testar um componente isoladamente é necessários criar
um ambiente com características de onde este componente será executado
- ex: testar funções mem* do C (como memset)
- /* memset: set the first n bytes of s to the byte c */
- void *memset(void *s, int c, size_t n) {
- size_t i;
- char *p;
- p = (char *)s;
- for (i=0; i<n; i++) p[i] =
c;
- return s;
- }
- // memset(s0 + offset, c, n);
- // memset2(s1 + offset, c, n);
- // compare s0 e s1 byte a byte
- Como testar funções do math.h ?
|
53
|
- Testar com grandes quantidades de dados
- gerados automaticamente
- erros comuns:
- overflow nos buffers de entrada, vetores e contadores
- Exemplo: ataques de segurança
- gets do C - não limita o tamanho da entrada
- o scanf(``%s’’, str) também não...
- Erro conhecido por “buffer overflow error” NYT98
|
54
|
|
55
|
- Cheque os limites dos vetores
- caso a linguagem não faça isto por você
- faça com que o tamanho dos vetores seja pequeno; ao invés de criar
testes muito grandes
- Faça funções de hashing constantes
- Crie versões de malloc que ocasionalmente falham
- Desligue todos os testes antes de lançar a versão final
- Inicialize os vetores e variáveis com um valor não nulo
- ex: 0xDEADBEEF pode ser facilmente encontrado
- Não continue a implementação de novas características se já foram
encontrados erros
- Teste em várias máquinas, compiladores e SOs
|
56
|
- “white box”
- testes feitos por quem conhece (escreveu) o código
- “black box”
- testes sem conhecer o código
- “usuários”
- encontram novos erros pois usam o programa de formas que não foram
previstas
|
57
|
- Testes unitários não podem depender de estado
- Então, como testar:
- Bancos de Dados
- Servidor Web
- Interface Usuário
- ..., etc.
|
58
|
- Coloca-se uma camada que funciona como se o serviço sempre fizesse a
coisa certa, para testar o cliente (mock objects = objetos fajutos)
- O serviço tem testes específicos que verificam seu funcionamento
interno.
|
59
|
- Desempenho (JUnitPerf)
- Métricas de qualidade
- Padrões de projeto (PatternTest)
- Cobertura de testes (Jester)
- ... Todas escritas seguindo o padrão Xunit.
- Vantagens
- Integração com ambientes de desenvolvimento (IDEs)
- Feedback rápido
- Robustez
|
60
|
- Grupo testdrivendevelopment do Yahoo
- http://junit.org
- Test-driven development (Kent Beck, 2003)
- http://www.xispe.com.br
|