1. MAIO 2009
MAIO 2009
Jorge Oliveira
jorge@gotest.biz
http://www.applabs.com/uploads/tool.jpg
Introdução a
Automação de Testes
Introdução a
Automação de Testes
2. AGENDA
AGENDA
JUnit
Recapitulando alguns conceitos ...
Driver, Stub, Mock
Em que ordem testar?
Adequação
Particionamento
Testes Caixa-Branca
Cobertura de Código
Ant
TDD
3. JUnit 4
JUnit 4
Uma classe JUnit 4 é uma classe qualquer!!
Uma classe JUnit 4 é uma classe qualquer!!
Criando caso de testes:
Criando Asserts:
4. JUnit 4
JUnit 4
Uma classe JUnit 4 é uma classe qualquer!!
Uma classe JUnit 4 é uma classe qualquer!!
Métodos de inicialização e limpeza de Casos de Testes
Métodos de inicialização e limpeza de Classes de Testes
Testando Exceções:
8. Recapitulando alguns conceitos ...
Recapitulando alguns conceitos ...
Unit
Test
Unit
Test
Unit
Test
Integration
Test
Integration
Test
System Test
9. Driver, Stub
Driver, Stub
Componente 1 Componente 2
Componente 2
Driver
Stub
• Driver exercita o módulo que está
sendo Testado
• Stub complementa o módulo que
está sendo testado
14. Adequação
Adequação
Quando parar de testar??
Teste é incompleto!!!!
Testar tudo normalmente é impossível.
É necessário uma medida para indicar a completude
de uma suíte de teste.
Critérios de Adequação:
Suíte 1
• Requisito A deve ser executado
• Requisito B deve estar em Fluxo de Exceção 1
Suíte 2
• Requisito C deve ser executado
• Requisito A e B deve estar em Fluxo de
Exceção 1 e 3, respectivamente
15. Particionamento
Particionamento
Espaço Amostral para entradas normalmente
tende ao infinito!
Precisamos agrupar valores de
entrada que representam resultados
esperados teoricamente
semelhantes!!!!
Classes de Equivalência
16. Particionamento
Particionamento
Considerando o seguinte método:
E o seguinte requisito:
“Crianças de até 5 anos não pagam. Idosos a partir de 65 anos
pagam 30% do valor e estudantes pagam 50% do valor total. Os
descontos não podem ser cumulativos”
Classes de Equiv. Estudante (A) Não-Estudante (B)
Idade <= 5 anos (X)
5 < Idade < 65 anos (Y)
Idade >= 65 anos (Z)
17. Particionamento
Particionamento
Combinatorial
Combinação de todas as classes de equivalência em produto cartesiano.
{(A,X), (A,Y), (A,Z), (B,X), (B,Y), (B,Z)}
Pairwise
A maior parte dos bugs provém de apenas um dos parâmetros ou de um par deles.
Pairwise testa todos os possíveis pares de valores
Exemplo: Num sistema de custos, um usuário tem que escolher uma operadora
(TIM, Vivo ou Oi), um plano de minutos (30, 60 ou 90 minutos) e um plano de
mensagens (10, 50 ou 100 mensagens).
18. Particionamento
Particionamento
Pairwise (Cont.)
Particionamento combinatorial geraria 3 x 3 x 3 = 27 combinações
Particionamento pairwise gerou apenas 15 combinações
Curiosidade: Assumamos um programa que contém 75 parâmetros binários. Um
particionamento combinatorial geraria 2 elevado a 75 combinações ... ou seja:
37,778,931,862,957,161,709,568. Utilizando pairwise, é possível conseguir uma
excelente cobertura com apenas 28 combinações.
Catalog Based
Baseado em especificações.
Uma documentação explicitando todas as condições (aninhadas ou não) para cada
entrada deve ser disponibilizada.
Esse método é o mais efetivo e mais trabalhoso.
19. Testes de Caixa Branca
Testes de Caixa Branca
Teste também chamado
de Teste Estrutural, uma
vez que foca na estrutura
do código;
Critérios de adequação
baseados no código.
Semelhante a um grafo
20. Testes de Caixa Branca
Testes de Caixa Branca
expr0;
while (condA){
if (condB){
expr1; expr2;
}
expr3;
}
expr4;
expr0
condA
expr1;
expr2;
expr3
condB
expr4
Teste = Seqüência de Nós!!
Teste = Seqüência de Nós!!
21. Testes de Caixa Branca
Testes de Caixa Branca
expr0
condA
expr1;
expr2;
expr3
condB
expr4
b
b
c
c
a
a
f
f
d
d
e
e
t0
t1 t6
t2
t3
t4
t5
22. Testes de Caixa Branca
Testes de Caixa Branca
b
b
c
c
a
a
f
f
d
d
e
e
t0
t1 t6
t2
t3
t4
t5
• Adequação por Nó
• Adequação por Transição
• Adequação por Caminho
• Adequação Estrutural
Statement
Basic-Block
Branch
Basic Condition
Compound Condition
MC/DC
Path
…
23. Cobertura de Código
Cobertura de Código
Cobertura de código ou Adequação Estrutural
são métricas que indicam o quão forte é o seu
projeto de testes
Cobertura de código ou Adequação Estrutural
são métricas que indicam o quão forte é o seu
projeto de testes
24. Cobertura de Código
Cobertura de Código
JCoverage
- Ferramenta sob licença GPL
- Relatórios de classes, métodos e linhas
- Pouca integração com outras ferramentas
Emma
- Ferramenta open source mais utilizada
- Ferramenta mais rápida
- Integração com Eclipse
- Relatorios de cobertura por instrução, linha, bloco e método
Clover
- Líder do mercado
- Relatório de efetividade de teste
- Diversos tipos de cobertura
- Otimizador de testes
- Relatórios mais completos
Outros: GroboUtils, Hansel, NoUnit
25. Cobertura de Código
Cobertura de Código
1. Cobertura por Expressão ou por Linha
(Statement Coverage ou Line Coverage)
- Métrica que representa a porcentagem de linhas de código executadas
- Muito simples de ser implementada
- Mais utilizada
- Não testa a lógica da aplicação
2. Cobertura por Blocos Básicos
(Basic Block Coverage)
- Métrica que representa a porcentagem de blocos básicos executados
- Bloco básico é tudo que está entre chaves
- Não testa a lógica da aplicação
26. Cobertura de Código
Cobertura de Código
3. Cobertura por Decisão ou por Galho
(Decision Coverage ou Branch Coverage)
- Métrica que representa a porcentagem de condicionais (como “if” ou “while”),
executadas como verdadeiras e falsas
- Relativamente simples de ser implementada
- Não se importa sobre como as expressões condicionais chegaram a um valor
4. Cobertura por Condição
(Condition Coverage)
- Métrica que representa a porcentagem de expressões (tudo que está separado
por um OR ou AND, por exemplo) de condicionais (como “if” ou “while”),
executadas como verdadeiras e falsas
- Extremamente complexa (dependendo da aplicação)
- Pode ser pouco efetiva uma vez que não se importa com o resultado da macro
expressão (condição)
27. Cobertura de Código
Cobertura de Código
5. Cobertura por Condições Múltiplas
(Multiple Condition Coverage)
- Métrica que representa a porcentagem de expressões (tudo que está separado
por um OR ou AND, por exemplo) de condicionais (como “if” ou “while”),
executadas como verdadeiras e falsas, bem como a própria condicional que são
executadas
- Extremamente extensa (dependendo da aplicação)
- É uma combinação entre a cobertura por decisão e cobertura por condição
- É muito efetiva
6. Cobertura por Caminhos
(Path Coverage)
- Métrica que representa a porcentagem de diferentes caminhos da aplicação
que são executados
- Eventualmente existem caminhos impossíveis
- Alguns loops podem determinar caminhos infinitos
- Variações resolvem o problema do loop colocando apenas duas condições:
entrou no loop 0 vezes (ou 1 vez no caso do “do … while”) ou entrou mais de 0
vezes (ou mais de 1 vez no caso do “do … while”).
28. Cobertura de Código
Cobertura de Código
7. Cobertura por Função ou Método
(Function or Method Coverage)
- Métrica que representa a porcentagem de métodos que são executados
- Muito pouco efetivo
- Muito simples de implementar
8. Cobertura por Operador Relacional
(Relational Operator Coverage)
- Métrica que representa a porcentagem de operações relacionais testadas com
valores superiores, inferiores e de fronteira (boundaries)
- Pode ser efetiva
- Pode necessitar de muitos testes
29. Cobertura de Código
Cobertura de Código
9. MC/DC
(Modified Condition/Decision Coverage)
- Utilizada para software Level A (catastróficos)
- Extremamente efetivo.
- Muito simples de implementar.
- Para uma adequação MC/DC (Cobertura 100% MC/DC), pelo menos um teste
deve satisfazer cada uma das condições abaixo:
- Todas as decisões (condicionais) devem ser executadas com todos os
seus possíveis valores
- Todas as expressões de todas as decisões devem ser executadas com
todos os seus possíveis valores
- Todos os pontos de entrada e de saída da aplicação são exercitados
- Cada condição é comprovadamente testada de forma que só ela modifique
a aplicação.
31. Ant
Ant
Propriedades
<property name="src.dir" value="src"/>
<property name="lib.dir" value="lib"/>
…
<property name="lib.common" value="${lib.dir}/common"/>
Propriedades são semelhantes a variáveis. É comum utilizar variáveis com
valores de caminhos, uma vez que esse valores são bem passíveis de mudança
32. Ant
Ant
Criação de Paths
<path id="compile.classpath">
<fileset dir="${lib.dir}/common">
<include name="*.jar"/>
</fileset>
</path>
<path id="test.classpath">
<pathelement location="${build.classes.dir}"/>
<path refid="compile.classpath"/>
</path>
Paths indicam caminhos que deverão representar em algum momento o
classpath de uma compilação java (representado pela diretiva –cp
nos comandos de compilação e execução de uma aplicação JAVA
33. Ant
Ant
Criação de Targets
<target name="init">
<mkdir dir="${build.classes.dir}"/>
</target>
<target name="clean">
<delete dir="${build.classes.dir}"/>
</target>
<target name="compile" depends="init">
<javac srcdir="${src.dir}" destdir="${build.classes.dir}" debug="true">
<classpath refid="compile.classpath"/>
</javac>
</target>
Targets são os principais elementos de um build.xml. Um target representa uma
atividade Ant. Vários comandos podem existir dentro de um target. O código
acima representa apenas uma pequena parte.
34. Ant
Ant
Ant + JUnit
<target name="test" depends="compile.tests">
<junit printsummary="true">
<classpath location="${build.classes.dir}"/>
<classpath refid="test.classpath"/>
<batchtest fork="yes" todir="${reports.tests}”>
<fileset dir="${src.dir}”>
<include name="**/*Test*.java"/>
<exclude name="**/AllTests.java"/>
</fileset>
</batchtest>
</junit>
</target>
Comandos Junit são embutidos nas versões mais novas do Ant, apesar de que,
qualquer aplicação pode incluir seus próprios comandos Ant
35. Ant
Ant
Tarefas Customizadas
(Ex.: Emma)
<!-- directory that contains emma.jar and emma_ant.jar: -->
<property name="emma.dir" value="${basedir}/../lib" />
<path id="emma.lib" >
<pathelement location="${emma.dir}/emma.jar" />
<pathelement location="${emma.dir}/emma_ant.jar" />
</path>
<taskdef resource="emma_ant.properties" classpathref="emma.lib" />
Comandos Taskdef servem para incluir novos comandos ao ANT.
O exemplo acima representa a inclusão de comandos para execução do ANT
utilizando o EMMA.
36. Ant
Ant
Tarefas Customizadas (Cont.)
(Ex.: Emma)
<!-- output directory used for EMMA coverage reports: -->
<property name="coverage.dir" value="${basedir}/coverage" />
<target name="run" depends="init, compile" description="runs the examples" >
<emmajava enabled="${emma.enabled}" libclasspathref="emma.lib”
fullmetadata="yes" sourcepath="${src.dir}”
classname="Main”
classpathref="run.classpath”
>
<filter includes="Main, search.*" />
<txt outfile="${coverage.dir}/coverage.txt" />
<xml outfile="${coverage.dir}/coverage.xml" />
<html outfile="${coverage.dir}/coverage.html" />
</emmajava>
</target>
Apos incusão via taskdef, os comandos (nesse caso “emmajava”) estão
disponíveis para ser utilizado em seu build.xml
40. Test-Driven Development (TDD)
Test-Driven Development (TDD)
• Programadores que escrevem testes são mais produtivos (estudo de
2005)
• Uma maneira de construir software mais rápido
• Habilidade de andar com pequenos passos, certificando-se que esses pão
estão coerentes e corretos
• Cobertura de caminho e de expressão é automaticamente utilizada, sem
nenhum esforço adicional
Vantagens