1
Aula 19Testes 2
Alessandro Garcia
LES/DI/PUC-Rio
Maio 2018
Ago 2008 2 / 35
Especificação
• Objetivo dessa aula
– Apresentar os critérios de suficiência dos testes
– Apresentar 3 critérios de seleção de casos de teste caixa
aberta: cobertura de instruções, de arestas, de decisões
• Referência básica:
– Capítulo 15
• Slides adaptados de: Staa, A.v. Notas de Aula em
Programacao Modular; 2008.
2
3 / 35
Sumário
• O que são critérios de seleção de casos de teste
• Processo de seleção de casos de teste
• Critérios de cobertura de instruções, de arestas e de
decisões
• Teste de repetições, arrasto
• Exemplo de cobertura de decisões
• Transformação de casos de teste abstratos em casos de
teste úteis
4 / 32
Controle da suficiência dos testes
• Podem ser utilizadas diversas formas para controlar a
suficiência dos testes
– medir a cobertura dos testes
• mede-se com o uso de contadores, vide aula de instrumentação
(módulo CONTA)
• esta técnica de controle da suficiência de testes pode ser utilizada
junto com qualquer critério de seleção de casos de teste
• existem vários critérios de completeza
• caso um ou mais dos contadores contenha zero e não for possível
argumentar que o contador será sempre zero para qualquer
instância de uso estamos diante de:
– ou código morto
– ou código de interceptação de falha
3
5 / 32
Controle da suficiência dos testes
• Código morto é uma função ou fragmento de código, que
jamais poderá ser exercitado em qualquer condição de uso
– normal ou de tratamento de falha
• Código morto deve ser excluído do programa
– manutenção de código morto é uma despesa inútil
• Interceptação de falha não é código morto
– interceptação de falhas é proteção contra lesões
• causas endógenas, exógenas ou decorrentes do mau uso
– tipicamente consta de assertivas executáveis e o código de
tratamento para o caso das assertivas falharem
– evidentemente o código de tratamento jamais deveria ser
executado caso o artefato esteja operando de forma correta
– pode ocorrer conflito com o controle de contadores
• dificuldade de provocar os erros: gere mutantes
6 / 32
Controle da suficiência dos testes
• Outra forma de controle da suficiência de testes é o teste
baseado em mutantes
– dado um módulo a testar e uma massa de teste
– injetam-se erros – mutantes – no código
– realizam-se os testes e medem-se
• o número de mutantes identificados
• o número de falhas originais encontradas
– o percentual de mutantes não identificados através dos testes
é um indicador do risco do artefato conter erros remanescentes
4
7 / 32
Controle da suficiência dos testes
• Seja a um artefato que aceita um conjunto de dados D. Seja
Q um conjunto de mutantes do artefato a. Uma massa de
teste T é adequada para a relativamente a Q sse
q Q : se d D | q( d ) ≠ a( d )
t T | q( t ) ≠ a( t )
• Em virtude de q ser um mutante de a conhecem-se os
d D tal que q( d ) ≠ a( d )
– o rigor do teste depende agora da escolha de Q
• número de mutantes
• variedade de operações de mutação utilizadas
– a qualidade do teste: MutantesIdentificados / TotalMutantes
– a qualidade do artefato:
TotalMutantes / ( DefeitosIdentificados + TotalMutantes )risco = 1 – ( TotalMutantes / ( DefeitosIdentificados + TotalMutantes ))
mutantes podem
não gerar erros
8 / 32
Controle da suficiência dos testes
• Uma terceira forma de avaliar a suficiência de testes é
medir o intervalo de tempo entre falhas
– realizam-se continuamente testes (ou utiliza-se o módulo em
produção) com dados variantes
– mede-se o intervalo de tempo decorrido entre falhas
consecutivas
• Caso o intervalo observado seja maior do que um número
estipulado, assume-se que o artefato tenha sido
suficientemente testado
– corre-se o risco de que o artefato ainda contenha um número
possivelmente grande de defeitos desconhecidos
• depende da forma do uso
– MTBF – mean time between failures é um indicador de risco,
quanto maior o MTBF menor o risco
5
9 / 32
Controle da suficiência dos testes
• Não são critérios que determinam a suficiência dos testes:
– esgotamento do prazo para entrega do artefato
– esgotamento dos recursos disponíveis para desenvolver o
artefato
• Infelizmente tendem a ser os critérios mais populares
10 / 35
Critérios de seleção de casos de teste
• Critérios de seleção de casos de teste são utilizados para
gerar os casos de teste que compõem a massa de teste
– a geração pode ser manual, ou parcial ou totalmente
automatizada
• Categorias de critérios de seleção de casos de teste
– teste caixa fechada
• gera os casos utilizando somente a especificação
• a massa pode ser desenvolvida antes ou junto com o código
– teste caixa aberta (teste estrutural)
• gera os casos de teste utilizando o código completo e a
especificação
– teste de estruturas de dados
• gera os casos de teste utilizando modelos e/ou o código de
declaração da estrutura de dados e a especificação
6
11 / 35
Critérios de seleção de casos de teste
• Um critério de seleção de casos de teste é
– válido:
• existindo defeitos no artefato testado, acusa falhas que permitam
localizar esses defeitos
– confiável:
• é indiferente à escolha dos dados e ações usados na massa de
teste
– completo:
• exercita todo o código segundo um padrão de completeza
– eficaz:
• quanto mais falhas encontrar, provocadas por diferentes defeitos
• quanto mais defeitos for capaz de identificar
– eficiente:
• quanto menos recursos necessitar para executar os testes
Critérios: caixa branca
MAT_tpCondRet f1(int i, int j) {
if ( ( i < 10 ) && ( j < 10 ) ) {
i = ( i + j ) / 2;
if ( i > 5 ) {
j = 10;
else {
i = 10;
}
}
return MAT_CondRetOK;
}
• Passo 1: produção do fluxograma
7
Critérios: caixa branca
MAT_tpCondRet f1(int i, int j) {
if ( ( i < 10 ) && ( j < 10 ) ) {
i = ( i + j ) / 2;
if ( i > 5 ) {
j = 10;
else {
i = 10;
}
}
return MAT_CondRetOK;
}
• Passo 1: produção do fluxograma
i = ( i + j ) / 2 ;
j = 10 ; i = 10 ;
if ( ( i < 10 )
&& ( j < 10 ))
if ( i > 5 )
S
N
S N
14 / 32
Critérios de cobertura: instruções
• Cobertura de instruções
(vértices)
– Cada instrução é executada
pelo menos uma vez no
conjunto de todos os casos de
teste
– rotulam-se as instruções e
criam-se os casos de teste
• cada caso percorre pelo
menos uma instrução ainda
não percorrida
• até que todas as instruções
tenham sido percorridas
– i = 4 ; j = 8 A B C D
– i = 4 ; j = 6 A B C E
i = ( i + j ) / 2 ;
j = 10 ; i = 10 ;
if ( ( i < 10 )
&& ( j < 10 ))
if ( i > 5 )
S
N
S N
D E
A
B
C
8
15 / 32
Critérios de cobertura: arestas
• Cobertura de arestas
– Cada aresta é percorrida pelo
menos uma vez no conjunto
de todos os casos de teste
– rotulam-se as arestas e
criam-se os casos de teste
• cada caso percorre pelo
menos uma aresta ainda não
percorrida
• até que todas as arestas
tenham sido percorridas
– i = 4 ; j = 8 I A C D F
– i = 4 ; j = 6 I A C E F
– Suficiente?
i = ( i + j ) / 2 ;
j = 10 ; i = 10 ;
if ( ( i < 10 )
&& ( j < 10 ))
if ( i > 5 )
S
N
S N
D E
B
A
C
F
I
16 / 32
Critérios de cobertura: arestas
• Cobertura de arestas
– Cada aresta é percorrida pelo
menos uma vez no conjunto
de todos os casos de teste
– rotulam-se as arestas e
criam-se os casos de teste
• cada caso percorre pelo
menos uma aresta ainda não
percorrida
• até que todas as arestas
tenham sido percorridas
– i = 4 ; j = 8 I A C D F
– i = 4 ; j = 6 I A C E F
– i = 3 ; j = 10 I B F
i = ( i + j ) / 2 ;
j = 10 ; i = 10 ;
if ( ( i < 10 )
&& ( j < 10 ))
if ( i > 5 )
S
N
S N
D E
B
A
C
F
I
9
17 / 35LES/DI/PUC-Rio
Critérios de cobertura: decisões
• Cobertura de decisões
– Cada combinação ao avaliar
membros das expressões
lógicas é exercitada pelo
menos uma vez no conjunto
de todos os casos de teste
– Neste caso, as decisões são
rotuladas
– i = 4 ; j = 9 A, E
– i = 1 ; j = 1 A, F
– i = 4 ; j = 10 B
– i = 10 ; j = 4 C
– i = 10 ; j = 10 D
i = ( i + j ) / 2 ;
j = 10 ; i = 10 ;
if ( ( i < 10 )
&& ( j < 10 ))
if ( i > 5 )
S
N
S N
A (v, v) D (f, f)
E (v) F (f)
Neste caso, são necessários
no mínimo 5 casos de teste
B (v, f)
C (f, v)
Possíveis combinações de decisões:
v,v,v
v,v,f
v,f
f,v
f,f
18 / 35
Critérios de cobertura: repetições
• Caso cobertura de instrução
– executar a repetição para n > 1 iterações;
• Caso cobertura de arestas
– executar a repetição para:
• n = 0 iterações
• n = 1 iteração
• n >= 2 iterações
• Caso cobertura de decisões
– como na cobertura de arestas
– em adição: cada uma das possibilidades de se decidir pelo
término foi exercitada para os 3 casos acima
• break, ou return no corpo da repetição
• expressão de controle de término composta
10
19 / 35
Critérios de cobertura: repetições
• O custo do teste cresce com o número de iterações
– portanto o número de iterações a testar no caso n > 1 deverá
• ser pequeno e
• ser suficientemente grande para que o teste possa ser assumido
válido
20 / 35
Arrasto
• Arrasto
– é o maior dos menores números de iterações necessárias para
que todas as variáveis ou estados inicializados antes e
modificados durante a repetição passem a depender
exclusivamente de valores computados em iterações anteriores
de uma mesma instância de execução dessa repetição
• Exemplos:
• A[0] = 0 ; A[1] = 0 ; A[2] = 0 ; A[3] = 0 ;
• memset( A , 0 , sizeof( A )) ;
• pElem = ProcurarSimbolo( pTabela , pSimbolo ) ;
– todos têm Arrasto == 0
• Arrasto: força de resistência ao avanço de um objeto em um fluido, resultante da ação do meio
11
21 / 35
Arrasto
• Arrasto
– é o menor número de iterações necessárias para que todas as variáveis
ou estados inicializados antes e modificados durante a repetição
passem a depender exclusivamente de valores modificados em
iterações anteriores de uma mesma instância de execução dessa
repetição
• Exemplos:
• for (i = 0; i < TamVet; i++) {
Vet[i] = 0;
}
• Soma = 0;
for (i = 0; i < TamVet; i++) {
Soma += Vet[i];
}
– todos têm Arrasto == 1
i somente é atualizado
apenas depois do fim da
1a. Interação…
Jun 2009 22 / 35LES/DI/PUC-Rio
Arrasto: exemplos
• Série de Fibonacci: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
– lei de formação Fn = Fn-2 + Fn-1
– tem Arrasto == ?
int main() {
int tam, f1, f2, f3, cont;
do {
printf("Digite o tamanho da sequencia: ");
scanf("%i", &tam);
if (tam <= 0)
printf("Digite um numero positivo!!");
} while (tam <= 0);
printf("0 - 1 - ");
f1 = 0; f2 = 1;
for (cont = 3; cont <= tam ; cont++) {
f3 = f2 + f1;
printf("%i - ", f3);
f1 = f2; f2 = f3;
}
return 0;
}
?
12
Jun 2009 23 / 35LES/DI/PUC-Rio
Arrasto: exemplos
• Série de Fibonacci: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
– lei de formação Fn = Fn-2 + Fn-1
– tem Arrasto == 3
int main() {
int tam, f1, f2, f3, cont;
do {
printf("Digite um numero: ");
scanf("%i", &tam);
if (tam <= 0)
printf("Digite um numero positivo!!");
} while (tam<=0);
printf("0 - 1 - ");
f1 = 0; f2 = 1;
for (cont = 3; cont <= tam ; cont++) {
f3 = f2 + f1;
printf("%i - ", f3);
f1 = f2; f2 = f3;
}
return 0;
}
cont f3 f1 f2
3 1 1 1
4 2 1 2
5 3 2 3
6 5 3 5
7 8 5 8
5 13 8 13
Quando variável passa
depender somente de valores
gerados em iterações anteriores
Ainda não satisfaz as
condições do arrasto
24 / 35
Arrasto: exemplos
• for ( i = 0 ; i < 10 ; i++ ) ...
• for ( pElem = pOrg ; pElem != NULL ; pElem = pElem->pProx ) ...
• fgets, fputs, fread, fwrite
• tpEstado Corrente ;
Corrente = DefinirPrimeiro( ValorProcurado ) ;
while ( !Terminou( Corrente ))
{
if ( Comparar( ObterValor( Corrente ), ValorProcurado )
== EH_IGUAL )
{
return Corrente ;
} /* if */
Corrente = DefinirProximo( Corrente , ValorProcurado ) ;
} /* while */
return ESTADO_NIL ;
• Todos têm Arrasto == 1
13
25 / 35
Arrasto: exemplos
• Tem Arrasto == ?
Intercalararquivos
Abrirarquivos
Efetuar aintercalação
Fechararquivos
Ler 1o. reg de ALer 1o. reg de B
Intercalar paresregs correntes
Transferir reg de A para S
Transferir regsde A para E
e de B para E
Transferir regde B para S
{RegA.Chave < RegB.Chave} {RegA.Chave == RegB.Chave} {RegA.Chave > RegB.Chave}
{ enquanto RegA.Chave < máximo ou RegB.Chave < máximo }
H
F
C 2
A
B
I
D
G
E
Buffer A
Buffer B
26 / 35
Arrasto: exemplos
• Tem Arrasto == 2Intercalararquivos
Abrirarquivos
Efetuar aintercalação
Fechararquivos
Ler 1o. reg de ALer 1o. reg de B
Intercalar paresregs correntes
Transferir reg de A para S
Transferir regsde A para E
e de B para E
Transferir regde B para S
{RegA.Chave < RegB.Chave} {RegA.Chave == RegB.Chave} {RegA.Chave > RegB.Chave}
{ enquanto RegA.Chave < máximo ou RegB.Chave < máximo }
H
F
C 2
A
B
I
D
G
E
Buffer A
Buffer B
Caso 2
buffers mudam com somente uma
interação
Caso 1
buffers mudam com duas
interações
menores números de iterações
MAIOR DOS...
14
27 / 35
Arrasto: exemplos
• Tem Arrasto == 2
Intercalararquivos
Abrirarquivos
Efetuar aintercalação
Fechararquivos
Ler 1o. reg de ALer 1o. reg de B
Intercalar paresregs correntes
Transferir reg de A para S
Transferir regsde A para E
e de B para E
Transferir regde B para S
{RegA.Chave < RegB.Chave} {RegA.Chave == RegB.Chave} {RegA.Chave > RegB.Chave}
{ enquanto RegA.Chave < máximo ou RegB.Chave < máximo }
H
F
C 2
A
B
I
D
G
E
28 / 35
Critérios de cobertura: repetições
• O arrasto é o número mínimo de iterações a realizar para
que todos os valores que possam ser modificados durante a
repetição tenham sido de fato modificados
– corresponde ao número mínimo de iterações para atingir o
estado “genérico”
– é função do projetista determinar o arrasto
• Os casos de teste a para as repetições são:
– caso 0 iteração (caso especial)
– caso 1 iteração (base da indução)
– caso n >= arrasto + 1 iterações (simula o passo de indução)
– devem sempre ser considerados os casos de término:
• break ou return no corpo da iteração
• atingiu a condição de término
15
29 / 35
Critérios de cobertura: repetições
• A preocupação ao testar programas é obter uma informação
confiável a respeito da qualidade do artefato
– pode requerer o uso de dados pouco plausíveis do ponto de
vista uso produtivo do programa, exemplos:
• intercalar dois arquivos vazios produzindo arquivos vazios
• procurar um símbolo em uma tabela vazia
• calcular o produto de matrizes de tamanho 0 × 0
30 / 35
Critério cobertura de decisões: exemplo
• Esquema do algoritmo para pesquisa em qualquer tabela
tpEstado Corrente ;
Corrente = DefinirPrimeiro( ValorProcurado ) ;
while ( !Terminou( Corrente ))
{
if ( Comparar( ObterValor( Corrente ),
ValorProcurado ) == EH_IGUAL )
{
return Corrente ;
} /* if */
Corrente = DefinirProximo( Corrente , ValorProcurado ) ;
} /* while */
return ESTADO_NIL ;
• arrasto == 1
16
31 / 35
Critério cobertura de decisões: exemplo
• Caso 0 iterações:
– tabela vazia
– tabela com 1 ou mais elementos e acha o primeiro elemento
• Caso 1 iteração:
– tabela com 1 elemento e não acha o elemento
– tabela com 2 ou mais elementos e acha o segundo elemento
• Caso arrasto + 1 iterações:
– tabela com 2 elementos e não acha o elemento
– tabela com 3 ou mais elementos e acha o segundo elemento
32 / 35
FIM