Este documento fornece uma breve introdução às técnicas de teste de software, descrevendo conceitos como:
- Casos de teste, que especificam entradas e saídas esperadas para testar o programa.
- Critérios de teste, como particionamento de equivalência e análise de valor limite, que guiam a geração sistemática de casos de teste.
- Teste funcional e estrutural, que se baseiam respectivamente na especificação e implementação do software.
1. Técnicas de Teste de
Software
Uma Breve Introdução
Compilado a partir do material original gentilmente cedido pelos professores
Sandra Fabbri (UFSCar) e José Carlos Maldonado (ICMC-USP)
1
2. O Que é Teste de Software
D P
X
? T
ִInexistência de erro:
Software é de alta Qualidade?
T é de baixa Qualidade?
2
3. Caso de Teste
Especificação de uma entrada para o programa
e a correspondente saída esperada
Entrada: conjunto de dados necessários
para uma execução do programa
Saída esperada: resultado de uma
execução do programa (um oráculo é
esperado)
Um bom caso de teste tem alta probabilidade
de revelar um erro ainda não descoberto
3
4. Projeto de Casos de Teste
Projeto de teste pode ser tão difícil quanto o
projeto do próprio produto a ser testado
Poucos programadores/analistas gostam de
teste; menos ainda de projeto de casos de
teste
4
5. Técnicas de Projeto de Casos de Teste
ִ Maneira sistemática e planejada para
conduzir os testes ( Critérios de Teste )
ִ Conjunto de Casos de Teste T
características desejáveis:
i ) deve ser finito
ii) o custo de aplicação deve ser razoável
5
6. Critérios de Teste
Critério de Teste C
ִObjetivo:
... obter, de maneira sistemática um conjunto T de casos de
teste efetivo quanto à meta principal de teste - revelar a
presença de erros no programa
Critério de Seleção de Casos de Teste
Critério de Adequação
ִT é C-adequado ⇔ todo elemento requerido por C é
exercitado por pelo menos um t, t ∈ T
6
7. Técnicas de Teste
Funcional
Estrutural
Baseada em Erros
A diferença está na fonte utilizada para
estabelecer os requisitos de teste
O importante não é definir qual usar, mas
saber usá-las de forma complementar
7
8. Técnicas de Teste
Funcional ou Teste Caixa Preta
ִbaseada na especificação do software
Estrutural ou Teste Caixa Branca
ִbaseada numa implementação em particular
Baseada em Erros
ִbaseada nos erros típicos e comuns
cometidos durante o desenvolvimento
8
9. Teste Funcional
Os requisitos de teste são extraídos da
especificação do software
Aborda o software de um ponto de vista
macroscópico
Problema:
ִDificuldade em quantificar a atividade de teste - não
se pode garantir que partes essenciais ou críticas do
software foram executadas
Critérios:
ִParticionamento de Equivalência
ִAnálise do Valor Limite
ִGrafo Causa-Efeito
9
10. Particionamento de Equivalência
Descrição:
ִdivide o domínio de entrada em classes ou partições de
equivalência que, de acordo com a especificação do
programa, são tratadas da mesma maneira
ִAs classes, que podem ser válidas ou inválidas, são
definidas de acordo com as seguintes diretrizes:
se a condição de entrada especifica um intervalo, são definidas
uma classe válida e duas inválidas
se a condição de entrada especifica um membro de um conjunto,
são definidas uma classe válida e uma inválida
se a condição de entrada for booleana, são definidas uma classe
válida e uma inválida
10
11. Particionamento de Equivalência
Aplicação:
ִde acordo com sua especificação existem, basicamente,
quatro entradas:
um inteiro positivo (entre 1 e 20 ⇒ 3 partições)
uma cadeia de caracteres
um caractere a ser procurado
a opção por procurar por mais caracteres (duas partições: uma
para “s” e outra para “n”)
ִo domínio de saída consiste de duas respostas, que
levam a outra divisão do domínio de entrada:
a posição na qual o caractere foi encontrado na string (caractere
de entrada pertencente à string)
uma mensagem declarando que ele não foi encontrado
(caractere de entrada não pertencente à string)
11
12. Particionamento de Equivalência
Dados de teste para o Teste de Particionamento de Equivalência
entrada saída esperada
x a c resposta
34 entre com um inteiro entre 1 e 20
0 entre com um inteiro entre 1 e 20
3 abc c o caractere c aparece na posição 3
s
k o caractere k não ocorre na string fornecida
n
12
13. Particionamento de Eqüivalência
Observação:
ִreduz o tamanho do domínio de entrada
ִconcentra-se em criar dados de teste baseados
unicamente na especificação
ִé especialmente adequado para aplicações em que as
variáveis de entrada podem ser facilmente identificadas e
podem ter valores distintos
ִproblemas:
embora a especificação possa sugerir que um grupo de dados
seja processado de forma idêntica, isso pode não ocorrer
a técnica não fornece um guia para a determinação dos dados de
teste
13
14. Análise do Valor Limite
Descrição:
ִcomplementa o Particionamento de Equivalência
ִcoloca sua atenção em uma fonte propícia a erros – os
limites de uma classe ou partição de equivalência
Partição de Equivalência
Limites
14
15. Análise do Valor Limite
Aplicação:
ִos valores inteiros 0, 1, 20 e 21
ִencontrar o caractere na primeira e na última posição da
cadeia de caracteres
Dados de teste para o Teste de Análise do Valor Limite
entrada saída esperada
x a c resposta
21 entre com um inteiro entre 1 e 20
0 entre com um inteiro entre 1 e 20
1 a a o caractere a aparece na posição 1
s
x o caractere x não ocorre na string fornecida
n
20 abcdefghijklmnopqrst a o caractere a aparece na posição 1
s
t o caractere t aparece na posição 20
n
15
16. Teste Estrutural
Os requisitos de teste são extraídos de uma
implementação em particular
Teste dos detalhes procedimentais
A maioria dos critérios dessa técnica utiliza
uma representação conhecida do programa
como grafo de programa ou grafo de fluxo de
controle
16
17. Teste Estrutural
Teste Baseado em Teste Baseado em
Fluxo de Controle Fluxo de Dados
Critérios: Critério:
ִ Teste de Comandos ִ Todos-usos
ִ Teste de Ramos
ִ Caminho DD
ִ Teste de Condição
ִ Teste de Decisão/Condição
ִ Teste de Condição Múltipla
ִ Teste do Caminho Básico
ִ Teste de Caminho
17
18. Teste Estrutural
Grafo de Fluxo de Controle ou Grafo de Programa
consiste de nós conectados por arcos com setas que
mostram sua direção
os nós representam blocos de comandos
ִbloco de comando: é um conjunto de comandos tal que se o primeiro
comando for executado, então todos os comandos subseqüentes
também o serão
os arcos indicam precedência, ou transferência de controle
essa representação permite que o programa seja
examinado independentemente de sua função
18
20. Teste Estrutural
Exemplo de Construção do Grafo de Fluxo de Controle
início
leia nro
1
raiz = raiz-quadrada(nro)
escreva raiz
fim
Programa com um caminho
20
21. Teste Estrutural
Exemplo de Construção do Grafo de Fluxo de Controle
início
1
leia nro 1
se nro > 0
raiz = raiz-quadrada(nro) 2
2 3
escreva raiz
senão
escreva mensagem de erro 3 4
fim-se
4
fim
Programa com dois caminhos
21
22. Teste Estrutural
Exemplo de Construção do Grafo de Fluxo de Controle
início 1 1
leia nro
enquanto nro ≠ 0 2 2
se nro > 0 3
raiz = raiz-quadrada(nro) 4 3
escreva raiz
senão 4 5
escreva mensagem de erro 5
fim-se 6 6
leia nro
fim-enqto 7
7
fim
Programa com loop
22
23. Teste Estrutural
1 program exemplo(input, output);
2 var a: array[1..20] of char; Programa com
3 x, i: integer;
4 c, resposta: char; blocos marcados
5 achou: boolean;
6 begin
7 writeln (‘entre com um inteiro entre 1 e 20’); 1
8 readln (x);
2
9 while (x < 1) or (x > 20) do
10 begin
11 writeln (‘entre com um inteiro entre 1 e 20’); 3
12 readln (x)
13 end;
14 writeln (‘digite’, x, ‘caracteres’); 4
15 for i := 1 to x do 5
16 read (a[ i ]); 6
17 readln; 7
18 repeat
19 writeln (‘digite o caracter a ser pesquisado: ‘);
8
20 readln (c);
21 achou := FALSE;
22 i := 1;
23 while (not(achou)) and (i <= x) do 9
24 begin
10
25 if a[ i ] = c then
26 achou := TRUE 11
27 else
12
28 i := i + 1
29 end; 13
30 if achou then 14
31 writeln (‘o caracter ’, c, ‘ aparece na posicao’, i) 15
32 else
33 writeln (‘o caracter ’, c, ‘ não ocorre na string fornecida’); 16
34 writeln;
35 writeln (‘deseja fazer a procura para outro caracter? [s/n]’);
17
36 readln (resposta);
37 until (resposta = ‘n’) or (resposta = ‘N’);
38 end. 18 23
24. Teste Estrutural 1
a
2
1 program exemplo(input, output); b c
d
2 var a: array[1..20] of char; Programa com 3
3 x, i: integer;
4 c, resposta: char; blocos marcados
5 achou: boolean;
4
6 begin
1
Grafo de fluxo e
7 writeln (‘entre com um inteiro entre 1 e 20’);
8 readln (x);
2
de controle 5
9 while (x < 1) or (x > 20) do
10 begin f g
11 writeln (‘entre com um inteiro entre 1 e 20’); 3
12 readln (x) h 6
13 end;
14 writeln (‘digite’, x, ‘caracteres’); 4
15 for i := 1 to x do 5 7
16 read (a[ i ]); 6 i
17 readln; 7
18 repeat 8
19 writeln (‘digite o caracter a ser pesquisado: ‘);
8 j
20 readln (c);
21 achou := FALSE; 9
22 i := 1;
23 while (not(achou)) and (i <= x) do 9 r k
24 begin l 10 m p
10
25 if a[ i ] = c then
26 achou := TRUE 11 11 12
27 else n o
12 13
28 i := i + 1 q
29 end; 13
30 if achou then 14
s 14 t
31 writeln (‘o caracter ’, c, ‘ aparece na posicao’, i) 15
32 else 15 16
33 writeln (‘o caracter ’, c, ‘ não ocorre na string fornecida’); 16
u 17 v
34 writeln;
35 writeln (‘deseja fazer a procura para outro caracter? [s/n]’); w
17
36 readln (resposta);
37 until (resposta = ‘n’) or (resposta = ‘N’); 18
38 end. 18 24
25. Teste de Comandos
Descrição:
ִEstabelece como requisito de teste que sejam
executados todos os comandos do programa ao menos
uma vez
Aplicação:
ִé necessário concentrar-se nos comandos que são
controlados por condições
ִfornecer um valor para x que esteja fora do intervalo para
forçar a execução dos comandos no loop (linhas 11-12)
ִquando x está dentro do intervalo, ele será no mínimo 1 e
o comando dentro do for (linha 16) será executado
25
26. Teste de Comandos
Aplicação (cont.):
ִo comando if (linha 25) precisa ser executado, com as
alternativas then e else (linhas 26 e 28) ⇒ procurar por
um caractere que esteja na cadeia e que force a procura
dentro dela
ִa entrada no while (linha 23) é garantida
ִo comando if (linha 30) precisa ser executado, com as
alternativas then e else (linhas 31 e 33) ⇒ um caractere
que pertença e outro que não pertença à cadeia
(combinando com o if anterior ⇒ uma cadeia de
caracteres a, de um caractere e valores para a variável c
que ocorra e que não ocorra em a)
ִpor fim, é preciso terminar o loop para executar o
comando end
26
27. Teste de Comandos
Dados de teste para o Teste de Comandos (suíte 1)
entrada saída esperada
x a c resposta
25 entre com um inteiro entre 1 e 20
3 abc b o caractere b aparece na posição 2
n
25 entre com um inteiro entre 1 e 20
3 abc d o caractere d não ocorre na string fornecida
n
Observação:
ִé o nível mínimo de cobertura esperado no teste
estrutural
27
28. Teste de Comandos
Dados de teste para o Teste de Comandos (suíte 2)
entrada saída esperada
x a c resposta
25 entre com um inteiro entre 1 e 20
1 x x o caractere x aparece na posição 1
s
a o caractere a não ocorre na string fornecida
n
Observação:
ִA busca de um caractere que não existe pode ser feita
na mesma execução do programa
28
29. Teste de Ramos
Descrição:
ִEstabelece como dados de teste exercitar todas as
saídas verdadeiro e falso de todas as decisões
Aplicação:
ִé conveniente observar o grafo do programa
ִobservando o grafo, é necessário gerar dados de teste
que causem as duas saídas verdadeiro e falso que
ocorrem nos nós 2, 5, 9, 10, 14 e 17
ִpara o nó 2, um valor da variável x menor que 1 ou maior
que 20 causa a saída pelo ramo verdadeiro e um valor de
x dentro desse intervalo causa a saída pelo ramo falso
ִo nó 5, comando for (linha 15), terá as saídas verdadeiro
e falso, desde que o valor de x seja ao menos 1 (e terá
que ser para chegar nesse ponto) 29
30. Teste de Ramos
Aplicação (cont.):
ִpara o nó 9, loop while (linha 23), a saída verdadeiro
(arco k) é garantida devido aos comandos das linhas 21 e
22; a saída falso (arco q) é garantida ou quando o
caractere que está sendo procurado é encontrado ou
quando o final da cadeia é encontrado
ִo nó 10, if (linha 25), requer uma comparação que
encontre o caractere que está sendo procurado (arcos l,
n) e uma outra que cause o incremento de i (arcos m, o)
ִo nó 14 (linha 30) precisa de um caractere que seja
encontrado e um outro que não seja encontrado
ִo nó 17 requer pelo menos mais uma iteração do loop
repeat (arco r) antes que o final do programa seja
encontrado (arco w)
30
31. Teste de Ramos
Dados de teste para o Teste de Ramos
entrada saída esperada
x a c resposta
25 entre com um inteiro entre 1 e 20
1 x x o caractere x aparece na posição 1
s
a o caractere a não ocorre na string fornecida
n
Observação:
ִ O conjunto de dados de testes é o mesmo da Suíte 2 do Teste de
Comandos
ִ Note que suíte 1 do Teste de Comandos não satisfaz o Teste de
Ramos
ִ No Teste de Ramos, a execução do loop repeat é obrigatória !
31
32. Teste de Condição
Descrição:
ִEstabelece os requisitos de teste tal que todas as
condições em uma decisão requeiram as duas saídas,
verdadeiro e falso, se for possível, ao menos uma vez
Aplicação:
ִé necessário considerar todos os nós identificados no
Teste de Ramos, mas neste caso, devem ser
consideradas todas as condições das decisões
ִno loop while (linha 9), tem-se uma decisão com duas
condições: while (x<1) or (x>20) do
valores de x: 0 e 21 obtém-se a cobertura das condições
se x=0 então a primeira condição é verdadeira e a segunda é
falsa; se x=21 então a primeira condição é falsa e a segunda é
verdadeira
32
33. Teste de Condição
Aplicação (cont.):
ִé necessário gerar um outro valor para x que esteja
dentro do intervalo, de forma que seja possível a
execução do resto do programa
ִesse valor pode ser determinado pelo requisito imposto
pela outra condição do programa, que corresponde ao
loop for do comando: for i:=1 to x do
para uma saída verdadeira a variável i deve ser menor ou igual a
x; para uma saída falsa a variável i deve ser maior que x. Como x
é pelo menos 1 para se chegar nessa parte do programa, o for é
executado até que i seja maior que x
33
34. Teste de Condição
Aplicação (cont.):
ִloop while, linha 23 (nó 9): while (not(achou))and(i<=x)
do
as duas condições nessa decisão são verdadeiras quando se
entra nesse loop
Para torná-las com valor falso, é preciso prever as duas
alternativas, ou seja, o caso de um caractere que pertença à
string e o caso de um caractere que não pertença
ִessas duas alternativas geram também os valores
verdadeiro e falso para os comandos if da linha 25 e if
da linha 30
ִa última decisão a ser considerada é o comando until da
linha 37 (nó 17): until (resposta = ‘n’) or (resposta = ‘N’)
quando é fornecido o valor ‘n’, a primeira condição é verdadeira e
a segunda é falsa; quando é fornecido o valor ‘N’, a primeira é
falsa e a segunda é verdadeira (executar o programa duas vezes) 34
35. Teste de Condição
Dados de teste para o Teste de Condição
entrada saída esperada
x a c resposta
21 entre com um inteiro entre 1 e 20
0 entre com um inteiro entre 1 e 20
1 x x o caractere x aparece na posição 1
n
1 x a o caractere a não ocorre na string fornecida
N
Observação:
ִo Teste de Condição pode não satisfazer o Teste de
Ramos
ִneste caso, o loop do repeat não é executado
35
36. Teste do Caminho Base
Descrição:
ִesse critério fornece uma maneira de determinar um conjunto básico
de caminhos linearmente independentes, de modo que executando-
os garante-se a execução de todos os comandos ao menos uma vez
ִEsse número é determinado pela fórmula da Complexidade
Ciclomática de Mc’Cabe
ִ V(G) = a – n + 2 ou
ִ V(G) = P + 1 ou
ִ V(G) = no. de regiões
ִsendo:
G: um grafo direcionado
a: arestas (ramos)
n: nós
P: no. de nós predicativos
ִUm caminho linearmente independente é aquele que contém ao
menos um novo nó
36
37. Teste do Caminho Base
Aplicação:
ִV(G) = 23 - 18 + 2 = 7
ִV(G) = 6 +1 = 7
ִV(G) = no. de regiões = 7
ִa partir desse número deve-se escolher 7 caminhos
linearmente independentes do grafo:
1. 1-2-4-5-7-8-9-14-15-17-18
2. 1-2-4-5-7-8-9-14-16-17-18
3. 2-3-2
4. 5-6-5
5. 9-10-11-13-9
6. 9-10-12-13-9
7. 8-9-14-15-17-8
37
38. Teste do Caminho Base 1
a
Aplicação: 2
b c
d
ִa partir desse número deve-se 3
escolher 7 caminhos linearmente 4
e
independentes do grafo: 5
g
1. 1-2-4-5-7-8-9-14-15-17-18 h
f
6
2. 1-2-4-5-7-8-9-14-16-17-18
7
3. 2-3-2 i
4. 5-6-5 8
j
5. 9-10-11-13-9 9
r k
6. 9-10-12-13-9 l 10 m p
7. 8-9-14-15-17-8 11
n o
12
13
q
s 14 t
15 16
u 17 v
w
18
38
39. Teste do Caminho Base
Observação:
ִesse conjunto é conhecido como conjunto base a partir
do qual qualquer outro caminho pode ser construído
ִPor exemplo, o caminho:
1-2-3-2-4-5-6-5-6-5-7-8-9-10-11-13-9-14-15-17-18
ִé uma combinação dos caminhos 1, 3, 4 (2 vezes) e 5
ִneste caso, o conjunto de dados de teste é o mesmo do
Teste de Ramos
39
40. Teste de Fluxo de Dados
Descrição:
ִestabelece requisitos de teste que seguem o modelo de
dados usados dentro do programa
ִcada ocorrência de uma variável dentro de um programa
pode ser classificada como sendo uma das seguintes:
def: definição
c-use: uso-computacional
p-use: uso-predicativo
40
41. Teste de Fluxo de Dados
ִ definição: quando uma variável é definida através de
uma leitura ou quando ela aparece do lado esquerdo de
um comando de atribuição, isto é, é dado um valor à
variável
ִ uso-computacional: quando a variável é usada na
avaliação de uma expressão ou em um comando de
saída
ִ uso-predicativo: quando a variável ocorre em um
predicado e portanto, afeta o fluxo de controle do
programa
41
42. Teste de Fluxo de Dados
Aplicação:
ִseja a aplicação do critério de fluxo de dados:
todos-usos (uso inclui c-uso e p-uso)
ִa idéia é identificar e classificar todas as ocorrências de
variáveis no programa e então gerar, para cada variável,
dados de teste de modo que todas as definições e usos
(denominado par d-u) sejam exercitados
ִas variáveis que precisam ser consideradas são: x, i, c,
achou, resposta e o vetor a
ִpara cada uma dessas variáveis constrói-se uma tabela
de pares d-u
42
43. Teste de Fluxo de Dados
Pares d-u da variável x
par d-u d u
Requisitos de teste:
1 8 9 1) um valor válido de x é fornecido na
2 8 14 primeira entrada (input), e então é
3 8 15 usado dentro do programa
4 8 23
5 12 9 2) um valor inválido de x seguido por
6 12 14 um valor válido, que é usado
7 12 15 subseqüentemente
8 12 23
43
44. Teste de Fluxo de Dados
Pares d-u da variável i Requisitos de teste:
1) o par d-u 1 é satisfeito lendo-se pelo
par d-u d u
menos um valor no vetor
1 15 16 2) os pares 2 e 3 serão cobertos
2 22 23 automaticamente
3 22 25
4 22 28 3) o par 4 é exercitado quando a procura
5 22 31 do caractere não obtém sucesso no
6 28 23 primeiro elemento do vetor
7 28 25
8 28 28 4) o par 5, por outro lado, é o resultado de
9 28 31 uma procura com sucesso no primeiro
elemento do vetor
5) os pares 6 a 9 são exercitados por uma
futura procura sem sucesso seguida por
uma procura com sucesso
44
45. Teste de Fluxo de Dados
Pares d-u da variável c
Requisitos de teste:
par d-u d u
para a variável c:
1 20 25
2 20 31 1) encontrando-se com sucesso o
3 20 33 caractere c no vetor
2) não encontrando o caractere c no vetor
Pares d-u da variável achou
par d-u d u para a variável achou: similar à c
1 21 23
2 21 30
3 26 23
4 26 30
45
46. Teste de Fluxo de Dados
Pares d-u da variável resposta Requisitos de teste:
par d-u d u
para a variável resposta:
1 36 37
1) fornecendo um valor ‘s’
Pares d-u da variável a
para a variável a:
par d-u d u
o vetor é tratado como uma variável
1 16 25 simples
ele é exercitado pela execução normal do
programa
46
47. Teste de Fluxo de Dados
Dados de teste para o Teste de Fluxo de Dados
entrada saída esperada
x a c resposta
1 D D o caractere D aparece na posição 1
n
21 entre com um inteiro entre 1 e 20
3 XYZ Z o caractere Z aparece na posição 3
y
a o caractere a não ocorre na string fornecida
n
47
48. Teste Baseado em Erros
Os requisitos de teste são estabelecidos com
base nos erros típicos e comuns cometidos
durante o desenvolvimento do software
Critério:
ִAnálise de Mutantes
48
49. Análise de Mutantes
Descrição:
opn
P
op2 Mutantes
op1
operadores Hipóteses:
de mutação
1) programador competente
T 2) efeito de acoplamento
escore de mutação = # mutantes mortos
# mutantes gerados não equivalentes
49
50. Análise de Mutantes
Garantir a ausência de determinados tipos de
defeitos
Considerando todos os programas Q, é possível
provar a correção de P
T
P Q
t∈T
P(t) ≠ Q(t)
50
51. Análise de Mutantes
É impraticável executar e comparar todos os
programas Q
Estabelece-se então uma vizinhança Φ(P)
que contém apenas um conjunto finito de
programas
Esses programas contêm pequenos desvios
sintáticos que representam defeitos simples
51
52. Análise de Mutantes
Q01 Q02 Q... Q... Q... Q... Q...
Q... Q... Q... Q... Q... Q... Q...
Q... Q... Q... Q... Q... Q... Φ(P)
Q... Q... Q... P Q... Q... Q...
Q... Q... Q... Q... Q... Q... Q...
Q... Q... Q... Q... Q... Q... Qn
∃ t ∈ T | ∀ Q, P(t) ≠ Q(t) ⇒ que P não contém os tipos de
defeitos representados pelos programas Q
52
53. Análise de Mutantes
Hipótese do Programador Competente
Programadores experientes escrevem programas corretos ou
muito próximos do correto.
Efeito de Acoplamento
Casos de teste capazes de revelar erros simples são tão
sensíveis que, implicitamente, também são capazes de revelar
erros mais complexos.
53
54. Análise de Mutantes
Os operadores de mutação determinam o
tipo de alteração sintática que deve ser feita
para a criação dos mutantes
ִIntroduzir pequenas alterações semânticas
através de pequenas alterações sintáticas que
representam defeitos típicos
Operadores dependem da linguagem alvo
ִFORTRAN (22 operadores) C (71 operadores)
54
55. Análise de Mutantes
Exemplos de operadores de mutação
ִRetira um comando de cada vez do programa
ִTroca operador relacional por operador relacional
ִTroca o comando while por do-while
ִInterrompe a execução do laço após duas execuções
ִTroca constante por constante
ִRequer valor negativo, positivo e zero para cada
referência escalar
55
56. Análise de Mutantes
Dados P e T
Passos para a Aplicação da Análise de Mutantes
ִP é executado com os casos de teste de T
ִMutantes são gerados
ִMutantes são executados com os casos de teste de T
ִMutantes são analisados
56
57. Análise de Mutantes
Aplicação:
ִConsidere o trecho do programa e o conjunto de teste
obtido para o Teste de Ramos
M
21 achou := FALSE;
22 i := 1;
23 while (not(achou)) and (i <= x) do
24 begin
25 if a[ i ] = c then
26 achou := TRUE
27 else
28 i := i + 1
29 end;
M
entrada saída esperada
x a c resposta
25 entre com um inteiro entre 1 e 20
1 x x o caractere x aparece na posição 1
s
a o caractere a não ocorre na string fornecida
n
57
58. Análise de Mutantes
Aplicação:
ִMutante 1: alteração na linha 21
de: achou := FALSE
para: achou := TRUE
• considere agora que o mutante seja re-executado com os
dados de teste obtidos para o Teste de Ramos
• a saída gerada seria: “o caractere a aparece na posição 1”
em vez de: o caractere a não ocorre na string fornecida
• mutante seria morto por esse conjunto de dados de teste
58
59. Análise de Mutantes
Aplicação:
ִMutante 2: alteração na linha 22
de: i := 1
para: x := 1
• considere agora que o mutante seja re-executado com os
dados de teste obtidos para o Teste de Ramos
• o erro não é revelado; o mutante continua vivo pois a saída
gerada por ele é igual à saída gerada pelo programa original,
uma vez que a string é de tamanho 1 e o loop while da linha
23 executa exatamente uma vez (somente se o for sair com
i=1)
• para matar esse mutante deve-se criar um caso de teste que
possua uma string de tamanho maior que 1 e assim, qualquer
caractere da posição 2 em diante será considerado como não
pertencente à string, mesmo que faça parte dela
59
60. Análise de Mutantes
Aplicação:
ִMutante 2: novos dados de teste para ser morto
Dado de teste que mata o mutante 2
entrada saída fornecida pelo mutante
x a c resposta
3 xCv x o caractere x aparece na posição 1
y
v o caractere v não ocorre na string fornecida
y
C o caractere C não ocorre na string fornecida
n
Obs: se o programa original fosse executado com esses dados, os caracteres v
e C seriam encontrados nas posições 3 e 2 respectivamente.
60
61. Análise de Mutantes
Aplicação:
ִMutante 3: alteração na linha 28
de: i := i + 1
para: i := i + 2
• considere agora que o mutante seja re-executado com os
dados de teste obtidos para o Teste de Ramos
• o erro não é revelado; o mutante continua vivo pois a saída
gerada por ele é igual à saída gerada pelo programa original,
uma vez que a string é de tamanho 1 e o loop while da linha
23 executa exatamente uma vez (o incremento de 2 não será
executado)
• para matar esse mutante deve-se criar um caso de teste que
possua uma string de tamanho maior que 1 e, além disso, é
necessário procurar por um caractere nas posições pares da
string
61
62. Análise de Mutantes
Aplicação:
ִMutante 3: novos dados de teste para ser morto
Dado de teste que mata o mutante 3
entrada saída fornecida pelo mutante
x a c resposta
3 xCv x o caractere x aparece na posição 1
y
v o caractere v aparece na posição 3
y
C o caractere C não ocorre na string fornecida
n
Obs: Se o programa original fosse executado com esse dado de teste, o
caractere C seria encontrado na posição 2
62
63. Análise de Mutantes
Observação:
ִTeste de Mutação consegue mostrar a ausência de erros
particulares, pois ao matar os mutantes está sendo
mostrado que o programa original não possui aquele erro
ִesse critério força o testador a analisar cuidadosamente
o programa, uma vez que ele precisa criar dados de teste
que exponham os erros introduzidos
ִdesvantagem:
ele é computacionalmente caro devido ao grande número de
mutantes gerados e o tempo e recurso usados para compilar e
executar todos eles
63
64. Estratégias de Teste
Aspectos genéricos das Estratégias de Teste
ִa atividade de teste inicia-se no nível de módulos e
caminha na direção da integração de todo o sistema
ִdiferentes técnicas de teste são apropriadas para
diferentes situações
ִa atividade de teste, em geral, é realizada pela equipe de
desenvolvimento e, no caso de grandes projetos, por um
grupo de teste independente
ִas atividades de teste e depuração são atividades
diferentes, mas a depuração é necessária em qualquer
estratégia de teste
64
65. Estratégias de Teste
Relação entre o processo de desenvolvimento e
uma estratégia de teste
Engenharia de Sistema S
Requisitos R
Projeto P
Código C
U Teste de Unidade
I Teste de Integração
V Teste de Validação
TS Teste de Sistema
65