Prévia do material em texto
Prof.ª Érica Souza
Cornélio Procópio
Critérios de Teste
Como eu seleciono meus casos de teste?
Como eu sei se meus casos de teste são de
qualidade (tem maior chance de revelar um defeito)?
Critérios de Teste
3
O critério de teste define um conjunto de propriedades
(requisitos de teste) que precisam ser testados (cobertos)
para que os casos de teste tenham qualidade
O critério de teste define um número finito n de
requisitos, seja coberto por um conjunto x de testes
Critérios de Teste
4
Nem sempre e possível atingir 100% de cobertura de um
critério
Exemplo
Requisitos → {req1, req2, req3, req4, req5}
Conjunto de teste con1 cobriu req1.
Conjunto de teste con2 cobriu req1, req2, req3.
Critérios de Teste
5
Um critério pode ser usado para selecionar/projetar os
casos de teste
Critérios de Teste
6
O critério de teste define um conjunto de propriedades
(requisitos de teste) que precisam ser testados (cobertos) para
que os casos de teste tenham qualidade
Qualidade = maior chance de detectar defeitos!
Existem várias intuições/suposições sobre onde e como os
defeitos se manifestam
Toda a informação sobre o software nem sempre está disponível
para o testador
Logo, existem vários critérios de teste
Técnicas de Teste
7
Os critérios de teste podem ser agrupados com base na visão ou
fonte de informação utilizada para derivar os requisitos de teste
Técnica funcional (caixa-preta)
Técnica estrutural (caixa-branca)
Técnicas de Teste
8
Teste Funcional (Caixa-preta)
O testador analisa e projeta os casos de teste sem
conhecimento da estrutura interna do software
Especificação do software
Requisitos, modelos, conhecimento de domínio, o próprio SUT
Técnicas de Teste
9
Critérios de Teste Funcional (Caixa-preta)
Particionamento em classes de equivalência
Análise de valor limite
Grafo causa-efeito (tabela de decisão)
Método partição-categoria
Teste funcional sistemático
Técnicas de Teste
10
Teste Estrutura (Caixa-branca)
O testador analisa e projeta os casos de teste usando a
logica interna do programa
Código-fonte do software
Técnicas de Teste
11
Critérios de Teste Estrutura (Caixa-branca)
Critérios baseados no grafo
Grafo de fluxo de controle
Grafo de fluxo de dados
Teste de mutação
Critérios baseado em lógica
Técnicas de Teste
12
Os critérios da técnica funcional e da técnica estrutural
não são concorrentes
Adotados de maneira complementar
Prof.ª Érica Souza
Cornélio Procópio
Técnicas de Teste
2
Critérios de Teste Funcional (Caixa-preta)
Particionamento em classes de equivalência
Análise de valor limite
Grafo causa-efeito (tabela de decisão)
Método partição-categoria
Teste funcional sistemático
Todos os critérios das técnicas funcionais baseiam-se
apenas na especificação do produto testado e,
portanto, o teste funcional depende fortemente da
qualidade da especificação de requisitos
3
Particionamento em classes de
equivalência
Part. em Classes de Equivalência
4
Busca definir casos de teste que descobrem classes de erros, reduzindo o
número total de casos de teste
Divide o domínio de entrada em classes de equivalência, de acordo com a
especificação do programa
Uma classe de equivalência representa um conjunto de estados válidos
ou inválidos para as condições de entrada
Part. em Classes de Equivalência
5
Uma vez identificadas as classes de equivalência, devem-se definir os casos
de teste, escolhendo um elemento de cada classe
Se o programa funciona para um caso dessa classe, é improvável que outro
caso de teste dessa mesma classe ira revelar um novo defeito
Qualquer elemento da classe pode ser considerado um representante
desta e, portanto, basta definir um caso de teste por classe de
equivalência
Part. em Classes de Equivalência
6
Passos:
1. Identificar as classes de equivalência, tomando por base a
especificação e, sobretudo, as entradas e as saídas
Identificar uma condição de entrada
Particionar em 2 ou mais classes
Identificar 2 grupos de classes
Válidas e Inválidas
Uma classe válida para cada valor
Uma classe inválida (fora do conjunto)
Part. em Classes de Equivalência
7
Passos:
2. Gerar casos de teste selecionando um elemento de cada
classe, de modo a ter o menor número possível de casos de
teste
Atribuir um valor para cada classe
Escrever casos de teste que cubram o máximo de classes validas
(até cobrir todas)
Part. em Classes de Equivalência
8
Uma forma de enumerar as classes de equivalência
Condição de Entrada Classes válidas Classes inválidas
Part. em Classes de Equivalência
9
Especificação
“No sistema as notas dos alunos são classificadas em A, B, C
ou D de acordo com a pontuação de cada um. Para conseguir
uma classificação A, o aluno tem que tirar nota entre 90 e 100,
B entre 80 e 89, C entre 70 e 79 e D abaixo de 70, sendo que
o sistema só aceita caracteres numéricos.”
Part. em Classes de Equivalência
10
Para exercitar todas as classificações de notas que são as partições de
equivalência A, B, C e D é necessário ter como entradas dos casos de teste
pelo menos um representante de cada classe de equivalência
Condição de entrada Classes Válidas Classes Inválidas
A ≥ 90 e ≤ 100 “%” (Caractere especial)
B ≥ 80 e ≤ 89 “A” (Letra)
C ≥ 70 e ≤ 79
D ≥0 e < 69
Casos de teste gerados
11
Casos de Teste Entrada Saída Esperado
CT01 60 D
CT02 75 C
CT03 84 B
CT04 93 A
CT05 “A” Inválido
CT06 % Inválido
Para a especificação apresentada, devemos ter pelo menos 6 casos de teste
para atingir todas as classes de equivalência.
Part. em Classes de Equivalência
12
Um programa solicita do usuário um inteiro positivo no intervalo entre
1 e 20 e então solicita uma cadeia de caracteres desse comprimento.
Após isso, o programa solicita um caractere e retorna a posição na
cadeia em que o caractere é encontrado pela primeira vez ou uma
mensagem indicando que o caractere não está presente na cadeia.
Para qualquer entrada inválida, uma mensagem de erro deve ser
apresentada e a entrada deve ser solicitada novamente.
Part. em Classes de Equivalência
13
Part. em Classes de Equivalência
14
Atribuindo valores para cada classe
Part. em Classes de Equivalência
15
Elaborar CTs que cubram as classes válidas e
inválidas
Part. em Classes de Equivalência
16
Resposta (entradas; saídas esperadas):
(7, “abcdefg”, 'c'; “posição 3”)
(-20, “abcdefg”, 'c'; “comprimento invalido”)
(35, “abcdefg”, 'c'; “comprimento invalido”)
(7, “abc”, 'c'; “cadeia com tamanho inconsistente”)
(7, “abcdefgh”, 'c'; “cadeia com tamanho inconsistente”)
(7, “abcdefgh”, 'y'; “caractere nao esta na cadeia fornecida”)
17
Análise de Valor Limite
Análise de Valor Limite
18
CTs que exploram situações limite possuem grande chance de
revelar defeitos
Assim como classes inválidas, as situações limite costumam ter um
tratamento de “segunda linha” por parte dos desenvolvedores
Introdução de defeitos!
Análise de Valor Limite
19
Como aplicar o critério
Pode-se usar as classes de equivalência do critério PCE*
Complementar pois os valores serão selecionados no limite
das classes de equivalência
Selecionar valores no limite ou ao redor do limites das classes de
equivalência
*PCE → Particionamento em classes de equivalência
Análise de Valor Limite
20
Análise de Valor Limite
Passosde Aplicação
1. Identificar as classes de equivalência
2. Identificar os limites de cada classe
3. Criar casos de teste para os limites escolhendo:
1. Um ponto abaixo do limite
2. O limite
3. Um ponto acima do limite
4. Observe que “acima” e “abaixo” são termos relativos e
dependente do valor dos dados
1. Números inteiros: limite = 16; abaixo = 15; acima = 17.
2. Números reais: limite = $5,00; abaixo = $4,99; acima = $5,01.
21
Análise de Valor Limite
22
Exemplo com um valor de intervalo:
Se a condição de entrada especifica um intervalo de valores de 1 a
255:
1. Nenhum valor de entrada (Zero)
2. 1 valor
3. 255 valores
4. 256 valores de entrada
Análise de Valor Limite
Exemplo
Um campo de entrada referente ao ano de aniversário
aceita valores de 1900 até 2004. Utilizando a análise
do valor limite o teste usaria quais valores?
a) 0, 1900, 2004, 2005
b) 1900, 2004
c) 1899, 1900, 2004, 2005
d) 1899, 1900, 1901, 2003, 2004, 2005
23
Análise de Valor Limite
Resolução
Um campo de entrada referente ao ano de aniversário
aceita valores de 1900 até 2004. Utilizando a análise do
valor limite o teste usaria quais valores?
a) 0, 1900, 2004, 2005
b) 1900, 2004
c) 1899, 1900, 2004, 2005
d) 1899, 1900, 1901, 2003, 2004, 2005
24
Exercício
25
Em um sistema de gestão de contratos, a idade dos
clientes varia de 18 a 120 anos. Apresente as classes de
equivalência e os casos de teste dos valores limite.
Entrada Classes Casos de teste para valores limite
Idade
18 a 120 Idade = 17
Idade = 18
Idade = 120
Idade = 121
< 18 Idade = 17
> 120 Idade = 121
Prof.ª Érica Souza
Cornélio Procópio
Critérios de Teste Funcional
Tabela de Decisão
Tabela de Decisão
Testes baseados em partições de equivalência ou análise de
valores-limite consideram cada valor de entrada isoladamente
E se existirem combinações de valores que constituam
situações interessantes a serem testadas?
Tabelas de Decisão:
As restrições na entradas e efeitos esperados (saídas), bem como
suas combinações podem ajudar na seleção de casos de teste
efetivos
Tabela de Decisão
4
Também conhecida como Grafo causa-efeito
Causas:
restrições de entrada (valor lógico)
Efeitos
ações realizadas em resposta às diferentes condições de entrada
ex.:
causa: preço item ≥ 50 e quantidade comprada ≥ 2 itens
efeito: fornecer 10% de desconto
Como Aplicar
5
(1) Identificar as restrições nas entradas
As restrições devem assumir valores verdadeiro ou falso**
(2) Identificar os efeitos (causas)
Em geral, um comportamento observável do sistema
(3) Montar a tabela de decisão que mapeia quando combinações de
determinados valores as restrições produzem os efeitos
(4) Gerar os casos de teste
Cada coluna é um CT
** As restrições não precisam ser Booleanas, embora tal fato facilite a aplicação do critério
Modelo de Tabela
6
Combinações
Restrições
Restrição 1
Restrição 2
Restrição 3
...
Efeitos
Efeito 1
Efeito 2
...
Exemplo 1
7
Um caixa eletrônico mostra o menu de opções se:
Um cartão com chip for inserido
O cartão bancário deve ser válido
O cartão deve possuir uma conta bancária ativa
Caso alguma condição seja falsa, uma mensagem de erro é
apresentada.
Exemplo 1
8
(1) Identificar as restrições nas entradas
As restrições devem assumir valores verdadeiro ou falso
Exemplo 1
9
(2) Identificar os efeitos (causas)
Em geral, um comportamento observável do sistema
Exemplo 1
10
(3) Montar a tabela de decisão que mapeia quando combinações
de determinados valores das restrições produzem os efeitos
Caso o valor de alguma restrição não importe, o símbolo “-” (don't care)
pode ser utilizado
Combinações
Restrições
Cartão com chip F
Cartão válido -
Conta Ativa -
Efeitos
Menu
Msg Erro
Qual o
efeito?
Exemplo 1
11
(3) Montar a tabela de decisão que mapeia quando combinações
de determinados valores das restrições produzem os efeitos
Caso o valor de alguma restrição não importe, o símbolo “-” (don't care)
pode ser utilizado
Combinações
Restrições
Cartão com chip F
Cartão válido -
Conta Ativa -
Efeitos
Menu
Msg Erro V
E as outras
combinações?
Exemplo 1
12
(3) Montar a tabela de decisão que mapeia quando combinações
de determinados valores das restrições produzem os efeitos
Caso o valor de alguma restrição não importe, o símbolo “-” (don't care)
pode ser utilizado
Combinações
Restrições
Cartão com chip F V V V
Cartão válido - F V V
Conta Ativa - - F V
Efeitos
Menu V
Msg Erro V V V
Exemplo 1
13
(4) Gerar os casos de teste (cada coluna é um CT)
As restrições e seus valores determinam as pré-condições e
as entradas
E os efeitos determinam as saídas esperadas
Combinações
Restrições
Cartão com chip F V V V
Cartão válido - F V V
Conta Ativa - - F V
Efeitos
Menu V
Msg Erro V V V
CT1 CT2 CT3 CT4
Exemplo 2
14
Um a loja apresenta as seguintes condições:
Se segue a página da loja nas redes sociais e é aluno da UTFPR, tem 60% de
desconto nas compras
Se segue a página da loja nas redes sociais e não é aluno da UTFPR, tem 25%
de desconto nas compras
...
Combinações
Restrições
Segue a página V V F F
Aluno da UTFPR V F V F
Efeitos Desconto 60% 25% 50% 0
Tabela de Decisão
15
Se o SUT tem regras de negócio complexas e se elas não estão bem
documentadas, os testadores têm que as obter e as representar em
forma de tabela de decisão
É preciso pelo menos um caso de teste para cada regra
Se as condições são binárias, um único teste para cada combinação é
suficiente
Se a condição é um intervalo de valores, você pode testar os limites
superiores e inferiores de cada intervalo usando os critérios de teste (ex.
PCE e AVL)
Lista de Exercícios 04: Critérios de Testes Funcionais
1. Tabela de decisão. Cálculo da hipoteca. Considere os seguintes requisitos:
• R1- O sistema deve receber três valores como entrada: gênero (1 → feminino e 0 →
masculino), idade ([21, 70]) e salário ([0-10000]). Como saída, o sistema deve calcular o
valor máximo da hipoteca para essa pessoa.
• R2- O valor máximo da hipoteca é calculado pela multiplicação do valor do salário com
um fator (ver tabela).
• R3- Mensagens de erro especificas devem ser geradas para valores inválidos de idade e
salário.
• R4- O fator para calcular a hipoteca (R2) e definido pela tabela a seguir:
Homem Fator Mulher Fator
21-40 anos 80 21-43 anos 60
41-70 anos 40 44-70 anos 30
Implemente uma classe Java que calcula o valor máximo da hipoteca e casos de teste JUnit
derivados da tabela de decisão. Elabore uma planilha que ilustra a tabela de decisão criada.
Resposta:
CT1 CT2 CT3 CT4 CT5 CT6
Restrições
Idade ([21, 70]) F V V V V V
Salário ([0-10000]) - F V V V V
Hipoteca
(Mulher 21-43)
- - V F F F
Hipoteca
(Mulher 44-70)
V F F
Hipoteca
(Homem 21-40)
V F
Hipoteca
(Homem 41-70)
V
Efeitos
Msg Erro V V - - - -
Calcula Hipoteca - - 60 * Salário 30* Salário 80* Salário 40*Salário
Observação: Pelo menos as combinações apresentadas na tabela acima devem ser consideradas
para teste, ou seja, pelo menos 6 casos de testes devem ser implementados no JUnit.
2. Tabela de decisão. A classe Calculadora e usada para calcular o salário dos empregados de
acordo com as seguintes regras:
• Se o tipo de empregado e “Assalariado40H” seu salário e 4.000.
• Se o tipo de empregadoe “Assalariado20H” seu salário e 1.500.
• Se o tipo de empregado e “Horista” seu salário e o número de horas trabalhadas vezes
15.
o Caso o horista trabalhe exatamente 40 horas nenhuma pendência é gerada
(atributo pendência da classe Salário).
o Caso o horista trabalhe menos de 40 horas, a pendência “relatório de ausência”
é gerada.
o Caso o horista trabalhe mais de 40 horas, a pendência “autorização de hora
extra” é gerada.
Elabore uma tabela de decisão para a descrição apresentada. Derive casos de teste da tabela e
implemente os casos de teste em JUnit, considerando as classes a seguir.
Salario.java
public class Salario {
int valorSalario;
String pendencia;
public String getPendencia() {
return pendencia;
}
public int getValorSalario() {
return valorSalario;
}
}
Calculadora.java
public class Calculadora {
public Salario calcularSalario(String tipoEmpregado, int horasTrabalhadas) {
//todo
return null;
}
}
Resposta:
CT1 CT2 CT3 CT4 CT5
Tipo
Empregado
Assalariado40H V F F F F
Assalariado20H F V F F F
Horista 40H F F V F F
Horista Menos 40H F F F V F
Horista Mais 40H F F F F V
Salário
4000 V - - - -
1500 - V - - -
SalarioHoristaSemPend - - HT*15 - -
SalarioHComAusencia
- - - HT*15
“Relatório de
Ausência”
-
SalarioHComHoraExtra
- - - - HT*15
“autorização de
hora extra”
Observação: Pelo menos as combinações apresentadas na tabela acima devem ser consideradas
para teste, ou seja, pelo menos 5 casos de testes devem ser implementados no JUnit.
3. Partição em Classes de Equivalências. Uma universidade considera aprovado o aluno que
obtém nota maior ou igual a 7. Porém, com nota maior ou igual a 4 ele terá direito a uma
prova de recuperação, mas com nota inferior a 4 estará reprovado. Considerando apenas
valores para uma nota válida (entre 0 e 10), qual alternativa apresenta uma nota para cada
partição equivalente?
a) 2.5, 6.0, 8.9
b) 3.0, 5.5, 6.0
c) 3.5, 7.8, 9.0
d) 4.5, 5.5, 9.0
Implemente uma classe Java que calcula os valores de cada classe de equivalência e casos de
teste JUnit.
4. Partição em Classes de Equivalências. Um sistema solicita a nota bimestral de um aluno. As
notas permitidas são entre 0 e 10. Notas fora desse intervalo são consideradas “notas
inválidas”. Considerando o critério Partição por Classes de Equivalência, identifique as
possíveis classes existentes e implemente em JUnit um caso de teste para cada classe.
Elabore uma tabela com os casos de teste para a descrição apresentada.
Resposta:
Classe 01 – Classe inválida (nota < 0)
Classe 02 – Classe válida (nota entre 0 a 10)
Classe 03 – Classe invalida (nota>10)
Casos de Teste Entrada Saída Prevista
CT01 – Classe 01 Nota = -5 Nota inválida
CT02 – Classe 02 Nota = 6 OK
CT03 – Classe 03 Nota = 12 Nota inválida
Observação: Pelo menos os 3 casos de testes apresentados devem ser implementados no
JUnit.
5. Partição em Classes de Equivalências. Considerando a idade do eleitor, o sistema deve
informar se ele não pode votar, é obrigado a votar ou se o voto é facultativo. Para ser
obrigado a votar o eleitor deve ter idade entre 18 e 70 anos. É proibido eleitores menores
de 16 anos a votarem. E é facultativo os eleitores com menos de 18 ou mais de 70 anos.
Elabore uma tabela com os casos de teste para a descrição apresentada.
Resposta:
Classe 01 – Menores de 16 anos - proibido
Classe 02 – Entre 16 e 17 anos - facultativo
Classe 03 – Entre 18 e 70 anos - obrigatório
Classe 04 – Mais de 70 anos - facultativo
Casos de Teste Entrada Saída Prevista
CT01 – Classe 01 Idade = 12 Proibido votar
CT02 – Classe 02 Idade = 17 Voto facultativo
CT03 – Classe 03 Idade = 25 Voto obrigatório
CT04 – Classe 04 Idade = 75 Voto facultativo
6. Análise de Valor Limite. Considerando os exercícios 4 e 5, complemente os casos de teste
usando o critério de análise do valor limite. Implemente em JUnit e complemente as tabelas
criadas para os casos de teste.
Complemento da tabela exercício 4:
Classe 01 – Classe inválida (nota < 0)
Classe 02 – Classe válida (nota entre 0 a 10)
Classe 03 – Classe invalida (nota>10)
Casos de Teste Entrada Saída Prevista
CT01 – Classe 01 Nota = -5 Nota inválida
CT02 – Classe 02 Nota = 6 OK
CT03 – Classe 03 Nota = 12 Nota inválida
Valor Limite:
Classe 01
-0,1 Nota inválida
0 OK
0,1 OK
Classe 02
-0,1 Nota inválida
0 OK
10 OK
10,1 Nota inválida
Classe 03
9,9 OK
10 OK
10,1 Nota inválida
Complemento da tabela exercício 5:
Classe 01 – Menores de 16 anos
Classe 02 – Entre 16 e 17 anos
Classe 03 – Entre 18 e 70 anos
Classe 04 – Mais de 70 anos
Casos de Teste Entrada Saída Prevista
CT01 – Classe 01 Idade = 12 Proibido votar
CT02 – Classe 02 Idade = 17 Voto facultativo
CT03 – Classe 03 Idade = 25 Voto obrigatório
CT04 – Classe 04 Idade = 75 Voto facultativo
Valor Limite:
Classe 01
15 Proibido votar
16 Voto facultativo
17 Voto facultativo
Classe 02
15 Proibido votar
16 Voto facultativo
17 Voto facultativo
18 Voto obrigatório
Classe 03
17 Voto facultativo
18 Voto obrigatório
70 Voto obrigatório
71 Voto facultativo
Classe 04
69 Voto obrigatório
70 Voto obrigatório
71 Voto facultativo
Prof.ª Érica Souza
Cornélio Procópio
Técnicas de Teste
Teste Funcional (Caixa Preta)
Testes baseados na especificação (de requisitos)
A funcionalidade testada e considerada uma caixa preta
Teste Estrutural (Caixa Branca)
Testes baseados na estrutura interna do programa
Analisar o código fonte (caixa branca)
Critérios de Teste
3
Quais casos de teste com maior chance de revelar
defeitos
Um critério pode ser usado para selecionar/projetar os
casos de teste
Critérios de Teste Estrutural
4
Vários critérios de teste estrutural
Critérios baseado em Fluxo de controle
Teste de Mutação
Em geral, a maioria dos critérios da técnica estrutural utiliza uma
representação de programa conhecida como “grafo de fluxo de
controle” (GFC)
A representação de um programa P m um GFC consiste em
estabelecer uma representação entre vértices (nós) dos blocos de
código e em indicar possíveis fluxos de controles entre blocos por
meio de arestas (arcos)
Grafo de Fluxo de Controle
5
Grafo direcionado G = (V, E, s)
Construído com base no fluxo de controle do programa
Sendo:
V → Nós (Vértices)
Blocos de instrução que não possuem desvios de execução
E →Arcos (Arestas)
Representa mudanças no fluxo de execução
s V é o nó de entrada
Grafo de Fluxo de Controle
6
Mapeando o programa para GFC
If
If-else
While
For
Do-While
Switch
Condições compostas
And (&&) e Or (||)
Grafo de Fluxo de Controle
7
Mapeando o programa para o GFC
If e If-else
Grafo de Fluxo de Controle
8
Mapeando o programa para GFC
While, For, Do-While
Grafo de Fluxo de Controle
9
Mapeando o programa para GFC
Switch
Grafo de Fluxo de Controle
10
Mapeando o programa para GFC
Condições Compostas
And (&&) e Or (II)
Exemplo 01
11
q = 1;
b = 2;
c = 3;
if (a ==2) {
x = x + 2;
} else {
x = x / 2;
}
p = q / r ;
if (b / c >3) {
z = x + y ;
}
Exemplo 01
12
q = 1;
b = 2;
c = 3;
if (a ==2) {
x = x + 2;
} else {
x = x / 2;
}
p = q / r ;
if (b / c >3) {
z = x + y ;
} ...
1
2
3
4
5
6
71
2
4 3
if (a ==2)
x = x + 2
x = x / 2
5
p = q / r;
6
7 z = x + y
if (b/c>3)
...
Exemplo 02 – Bubble Sort
13
public int[] bolha (int[] a, int size){
int i, j, aux ;
for (i = 0; i < size ; i ++) {
for ( j = size - 1; j > i ; j--) {
if( a [ j - 1] > a [ j ] ) {
aux = a [ j - 1 ];
a [ j - 1] = a [ j ] ;
a [ j ] = aux ;
}
}
}
return a;
}
Exemplo 02 – Bubble Sort
14
public int[] bolha (int[] a, int size){
int i, j, aux;
for (i = 0; i < size; i ++) {
for ( j = size - 1; j > i; j--) {
if( a [ j - 1] > a [ j ] ) {
aux = a [ j - 1 ];
a [ j - 1] = a [ j ] ;
a [ j ] = aux ;
}
}
}
return a;
}
1
2 3 4
5 6 7
8
9
10
1
2
3
4
5
6
7
10
8
9
Critérios de Teste
15
Todos-Nós→ CTs que executem cada
nó ao menos uma vez (line-coverage) –
cobertura das linhas de código
Todos-Arcos → CTs que executem cada
arco ao menos uma vez (branch-coverage) -
cobertura por desvios
1
2
3
4
5
6
7
10
8
9
Ferramenta de cobertura de código
16
Para cobertura de código utilizar o plugin TikiOne
JaCoCoverage
Instalação:
Olhar pdf no Moodle “Fluxo de controle Ferramenta”
Exercício
17
Elabore um casos de teste (JUnit)
para o exemplo do Bubble Sort
considerando a execução de
diferentes arcos.
Use a ferramenta JaCoCo para
confirmar a cobertura dos arcos
1
2
3
4
5
6
7
10
8
9
Teste Estrutural
Prof. André Takeshi Endo
Até o momento, vimos uma abordagem de teste funcional ou teste
caixa preta. Basicamente, apenas os requisitos e as funcionalidades do
software são utilizadas para projetar e implementar os casos de teste.
Em alguns casos, é preciso que o teste parta de um código já
implementado. Nesse caso, dize-se que o teste realizado é estrutural ou teste
caixa branca. Nesse tipo de teste, a estrutura interna do software (ou seja, o
código fonte dos programas) pode ser utilizada para guiar o projeto e a
implementação dos casos de teste.
No teste estrutural, a qualidade dos testes gerados podem ser medidos
pela porcentagem de cobertura de um dado critério. A seguir, serão
apresentados dois critérios baseados no fluxo de controle.
Line Coverage: o primeiro critério que será abordado é a “cobertura de linhas”
(em Inglês, Line Coverage). Esse critério é bem simples e objetiva cobrir as
linhas de código em programa. Por exemplo, considere a classe em Java na
Figura 1.
Ao testar o método safe_add, para conseguir 100% de cobertura do
critério Line Coverage, casos de teste deveriam ser implementados de forma
que, ao executá-los, o fluxo de execução passe ao menos uma vez pelas
Figura 1: método que faz uma adição segura de inteiros.
Linhas 9 a 22. A porcentagem de cobertura do Line Coverage é dado pelo total
de linhas executadas pelos testes dividido pelo total de linhas do método.
• Nota: quando medir a porcentagem de cobertura, desconsidere as
linhas em branco e as linhas que contém apenas o símbolos “{“ e
“}”.
Exercício 1: para cada um dos casos de teste listados na Figura 2, diga
quais são as linhas de código executadas no método da Figura 1. Conseguiu-
se 100% de cobertura para o critério Line Coverage?
Exercício 2: implemente um projeto Java (usando uma IDE, Netbeans
ou Eclipse) com o código apresentado nas Figuras 1 e 2.
Branch Coverage: esse critério é referente a “cobertura de desvios” (em
Inglês, Branch Coverage). Esse critério objetiva cobrir um valor verdadeiro e
um valor falso para cada condição existente em um programa. As diferentes
direções que são tomadas nessas condições (verdadeiro ou falso) são
Figura 2: Casos de teste em JUnit.
chamados de desvios. Em Java, essas condições existem nas instruções if,
while, for, do-while, switch e expressões ternárias (“? : ”).
No código apresentado na Figura 1, nós temos exatamente três
condições, nas Linhas 12, 13 e 17; isso implica no total de seis desvios. A
porcentagem de cobertura do Branch Coverage é dado pelo total de desvios
executados pelos testes dividido pelo total de desvios do método.
Exercício 3: usando os casos de teste na Figura 2, qual a porcentagem
de cobertura para o critério Branch Coverage? Caso a cobertura seja menor
que 100%, adicione os casos de teste necessários para cobrir os desvios
(branches) faltantes.
Exercício 4 (Vincenzi e de Deus): implemente uma classe Java e os
testes em JUnit para cobrir 100% dos critérios Line Coverage e Branch
Coverage, considerando o método a seguir.
Exercício 5 (Vincenzi e de Deus): implemente uma classe Java e os
testes em JUnit para cobrir 100% dos critérios Line Coverage e Branch
Coverage, considerando o método a seguir.
Exercício 6: implemente uma classe Java e os testes em JUnit para cobrir
100% dos critérios Line Coverage e Branch Coverage, considerando os
métodos a seguir.
Instalação de plugin do Netbeans para os critérios Line e Branch
coverage
1. No Netbeans, escolha a opção de menu “Ferramentas” → Plugins
2. Na aba plugins disponíveis, pesquisar por “Jacocoverage”.
3. Selecione o plugin TikiOne JaCoCoverage e instalar.
Caso tenha problemas via IDE, você pode baixar o plugin diretamente de:
http://plugins.netbeans.org/plugin/48570/tikione-jacocoverage
Explore a ferramenta.
• Botão direito no projeto → “Test with JaCoCoverage”
• Verifique o relatório.
• O que é verde, vermelho e amarelo?
• Para limpar informações de cobertura, botão direito → “reset coverage
data”
Lista de Exercícios 05: Critérios de Testes Estruturais
1. Considere a classe abaixo:
public class Calculadora {
/**
* @param n - inteiro
* @param valorMaximo - valor maximo que pode ter o somatorio
* @return - o somatorio de 0 ate |n|, caso somatorio seja <= valorMaximo
* @throws Exception - caso o somatorio seja > valorMaximo
*/
public int somatoriaLimitada(int n, int valorMaximo) throws Exception {
int resultado = 0, i = 0;
if(n < 0) {
n = -n;
}
while(i<=n && resultado <= valorMaximo) {
resultado = resultado + i;
i++;
}
if(resultado > valorMaximo)
throw new Exception("valor maximo foi ultrapassado");
else
return resultado;
}
}
Desenhe o grafo de fluxo de controle (GFC) para o método. Elabore casos de teste em
JUnit de forma a alcançar 100% de cobertura do critério de teste estrutural todos-arcos
(branch coverage). Comente cada caso de teste com o caminho que foi executado de
acordo com o GFC. Enumere os nós no grafo para identificar corretamente os caminhos.
2. Considere a classe abaixo
public class NovaLinha {
/**
* @param argStr string da qual os caracteres de new
line ‘\n’ serão aglutinados
* @return String
*/
public String collapseNewlines(String argStr) {
char last = argStr.charAt(0);
StringBuffer sBuf = new StringBuffer();
for (int i = 0; i < argStr.length(); i++) {
char ch = argStr.charAt(i);
if (ch != '\n' || last != '\n') {
sBuf.append(ch);
last = ch;
}
}
return sBuf.toString();
}
}
Considerando o grafo de fluxo de controle (GFC) do método collapseNewlines, elabore os
casos de teste em JUnit de forma a:
a) Executar os arcos (3,9).
b)A alcançar 100% de cobertura do critério de teste estrutural todos-arcos (branch
coverage).
c) Comente cada caso de teste anteriores com o caminho que foi executado de
acordo com o GFC.
3) Considere as quatro classes a seguir. Observe que existe um programa original e três
mutantes; as mutações aplicadas em cada mutante estão destacadas em negrito.
Original.java
public class Original {
//método retorna o maior elemento do
vetor
public int getMaior(int vetor[]) {
int maior = vetor[0];
for (int i = 1; i < vetor.length; i++) {
if(vetor[i] > maior)
maior = vetor[i];
}
return maior;
}
}
Mutante1.java
public class Mutante1 {
//método retorna o maior elemento do
vetor
public int getMaior(int vetor[]) {
int maior = vetor[0];
for (int i = 1; i < vetor.length; i++) {
if(vetor[i] != maior)
maior = vetor[i];
}
return maior;
}
}
Mutante2.java Mutante3.java
public class Mutante2 {
//método retorna o maior elemento do
vetor
public int getMaior(int vetor[]) {
int maior = vetor[0];
for (int i = 2; i < vetor.length; i++) {
if(vetor[i] > maior)
maior = vetor[i];
}
return maior;
}
}
public class Mutante3 {
//método retorna o maior elemento do
vetor
public int getMaior(int vetor[]) {
int maior = vetor[0];
for (int i = 0; i < vetor.length; i++) {
if(vetor[i] > maior)
maior = vetor[i];
}
return maior;
}
}
Implemente casos de teste em JUnit para matar cada um dos três mutantes; se algum dos
mutantes for equivalente, justifique.
4) Considere as quatro classes a seguir. Observe que existe um programa original e três
mutantes; as mutações aplicadas em cada mutante estão destacadas em negrito.
Original.java
public class Original {
public int contarA(String word) {
int contador = 0;
for(int i = 0; i < word.length(); i++) {
if(word.charAt(i) == 'a' ||
word.charAt(i) == 'A')
contador++;
}
return contador;
}
}
Mutante1.java
public class Mutante1 {
public int contarA(String word) {
int contador = 0;
for(int i = 0; i < word.length(); i++) {
if(word.charAt(i) == 'a' ||
word.charAt(i) == 'a')
contador++;
}
return contador;
}
}
Mutante2.java
public class Mutante2 {
public int contarA(String word) {
int contador = 0;
for(int i = 0; i < word.length(); i++) {
if(word.charAt(i) == 'a' ||
word.charAt(i) == 'A')
contador=contador+1;
}
return contador;
}
}
Mutante3.java
public class Mutante3 {
public int contarA(String word) {
int contador = 0;
for(int i = 0; i < word.length()-1; i++) {
if(word.charAt(i) == 'a' ||
word.charAt(i) == 'A')
contador++;
}
return contador;
}
}