Técnicas de Teste Estrutural
Teste de Fluxo de Controle
Introdução
• Teste funcional vs. Teste Estrutural • Teste funcional▪ Usa como entrada a especificação funcional.
▪ Procura verificar se todas as funcionalidades previstas foram implementadas e se respondem como esperado.
▪ Incapaz de verificar funcionalidades ou comportamentos extras não
especificados.
Introdução
• Teste estrutural▪ Usa como ponto de entrada o código fonte.
▪ Mais propenso a automação.
▪ Procura exercitar o maior número possível de possibilidades de execução do programa, de acordo com algum critério pré-definido
▪ No teste estrutural a especificação funcional é usada apenas como oráculo.
Introdução
• Teste estrutural e teste funcional sãocomplementares:
▪ Teste estrutural ajuda a detectar comportamentos que foram
implementados mas não especificados.
▪ Teste funcional detecta comportamentos que foram
especificados, mas não implementados – e que o teste estrutural jamais testaria.
Introdução
• Análise estática:▪ Oferece parâmetros de qualidade do código fonte.
▪ Será visto mais adiante. • Análise dinâmica:
▪ Exercita o código fonte em busca de erros. ▪ Cada técnica define um critério de
cobertura: fluxo de controle fluxo de dados análise de mutantes
Introdução
• Por serem baseadas na análise docódigo fonte, as técnicas estruturais dependem da linguagem de
programação usada – na verdade, do paradigma de programação utilizado. • Inicialmente serão discutidas as
técnicas de teste estrutural para programas imperativos. Mais adiante comentaremos o que muda quando se consideram outros paradigmas.
Introdução
• Duas categorias principais:▪ Teste de fluxo de controle.
▪ Teste de fluxo de dados.
▪ Compartilham uma característica importante: baseiam-se no conceito de grafo de programa.
Grafo de Fluxo de Controle
• Grafo de Fluxo de Programa:▪ Grafo dirigido onde os nodos representam comandos e os arcos representam o fluxo de execução
▪ Existe um arco de um nodo i para um nodo j se e somente se j pode ser executado imediatamente após i
Grafo de programa
Grafo de Fluxo de Controle
• Quais comandos representar?
▪ Dependente do paradigma e da linguagem
▪ Em C/C++/Java não se representam as declarações de variáveis porque não
correspondem a comandos
executáveis.
• Todo grafo de programa tem um único nodo inicial e um nodo final
Exemplo
1.a = Integer.parseInt(args[0]); 2.b = Integer.parseInt(args[1]); 3.while f1(a){ 4. if (f2(b)){ 5. a = b + 1; 6. }else b = a + 1; 7. } 8. c = a + b; 1 2 3 4 5 6 7 8Grafo de Programa
• Estruturas típicas de um grafo deExercícios
1) Desenhe o grafo de programa correspondenteaos trechos de código a seguir:
1. public void ordena(int *vet, int pos){
2. int i=0;
3. while (i<pos-1) {
4. int j=0;
5. while (j<pos-1) {
6. if (vet[j] > vet[j+1]){
7. int aux = vet[j];
8. vet[j] = vet[j+1]; 9. vet[j+1] = aux; 10. } 11. j = j++; 12. } 13. i = i++; 14. } 15. }
Exercícios
1. String cab=""; int qtd;2. for(int j=0;j<Veiculo.QTDADE_CAMPOS;j++) 3. cab += Veiculo.ROTULOS[j]+"\t"; 4. cab += "Imagem\t"; 5. cab += "LogoRevenda\t"; 6. ps.println(cab); 7. for(int i=0;i<tam;i++){ 8. qtd = dis.readInt(); 9. aux = dis.readUTF()+logoRevenda+"\t"; 10. for(int j=0;j<qtd;j++) 11. ps.println(aux); 12. String ni = dis.readUTF();
13. int nbytes = dis.readInt();
14. FileOutputStream ios= new FileOutputStream(ni);
15. for(int j=0;j<nbytes;j++)
16. ios.write(dis.read());
17. ios.close();
18. }
19. dis.close(); fis.close(); ps.close();fos.close();
Exercícios
1. public static void verificaOuCriaDirVeiculos(){2. File f = new File(Revenda.getDirVeiculos());
3. if (f.exists()){
4. if (f.isDirectory()) return;
5. JOptionPane.showMessageDialog(null,
6. "Nao e possivel criar o diretorio veiculos"+
7. "\nRemova o arquivo com este nome diretório "+
8. "corrente");
9. System.exit(0);
10. } else {
11. f.mkdir();
12. File fImg = new File("NoVehicle.jpg");
13. JTextField cmps[]=new JTextField[Veiculo.QTD];
14. for(int i=0; i<Veiculo.QTD;i++)
15. cmps[i] = new JTextField(20);
16. campos[Veiculo.PLACA].setText("NoVehicle");
17. Veiculo.save(cmps,fImg);
18. }
19. }
Análise dinâmica
• Execução monitorada do programa • Pode exigir instrumentação de código • Abordagens:▪ Análise de cobertura • Teste de fluxo de controle • Teste de fluxo de dados
▪ Análise de mutantes
Análise dinâmica
• Análise de cobertura▪ Dado um conjunto de execuções do programa, quanto do código fonte foi exercitado (coberto)?
• Geração de casos de teste
▪ Cria-se os casos de teste com o objetivo de atingir um determinado valor de cobertura
▪ Métricas: • Fluxo de controle • Fluxo de dados
Análise dinâmica
• Grafo de Fluxo de Controle:▪ Define uma relação entre o caso de teste e a parte do programa exercitada por ele.
▪ Um caso de teste:
• Corresponde a um caminho no grafo. • Corresponde a uma execução completa: do
Teste de Fluxo de Controle
• Cada caso de teste corresponde a umcaminho no grafo. • Etapas:
▪ Construir o grafo de fluxo de programa.
▪ Determinar os caminhos factíveis.
▪ Selecionar um conjunto de caminhos factíveis para teste.
▪ Gerar as entradas e os resultados esperados para os casos de teste correspondentes.
Exemplo
1. public Triangulo(String args[ ]){
2. int a,b,c;
3. String resp = null;
4. a = Integer.parseInt(args[0]); 5. b = integer.parseInt(args[1]); 6. c = integer.parseInt(args[2]); 7. if (a==b)&&(b==c) 8. resp = “equilatero”; 9. if (((a==b)&&(b!=c))||((b==c)&&(a!=b))||((a==c)&&(c!=b)) 10. resp = “isoceles”; 11. if ((a!=b)&&(b!=c)) 12. resp = “escaleno”; 13. system.out.println(“Tipo de triangulo:”+resp); 14. } 4 5 6 7 9 11 13 8 10 11
Caminhos Sobre o Grafo
• Sobre o grafo do problema dotriângulo podemos distinguir os seguintes caminhos: 1. 4-5-6-7-9-11-13 2. 4-5-6-7-8-9-11-13 3. 4-5-6-7-9-10-11-13 4. 4-5-6-7-8-9-10-11-13 5. 4-5-6-7-9-11-12-13 6. 4-5-6-7-8-9-11-12-13 7. 4-5-6-7-9-10-11-12-13 8. 4-5-6-7-8-9-10-11-12-13
Caminhos Sobre o Grafo
• Existem caminhos factíveis. Ex:caminhos 1,2,3 e 5.
• Existem caminhos não factíveis. Ex: caminhos 4,6,7 e 8.
• A existência de caminhos não factíveis indica que talvez a lógica pudesse ser escrita de outra maneira.
Teste de Fluxo de Controle
• Objetivos do teste de fluxo decontrole:
▪ Exercitar um mínimo aceitável de caminhos factíveis.
▪ O que determina o que é um “mínimo aceitável” são as “métricas de cobertura”:
• Cobertura de comando • Cobertura de decisão • Cobertura de condição • Cobertura de condição múltipla • Cobertura de repetição
Cobertura de Comando
• Definir casos de teste que executem todosos comandos pelo menos uma vez (passa por todos os nodos do grafo).
▪ Métrica: número de nodos cobertos.
▪ Fácil de satisfazer:
• Para o problema do triângulo bastam 3 casos de teste (caminhos 2,3 e 5)
▪ Não garante muita coisa:
• Não testa o caso em que a entrada não é um triângulo
• Não detectaria o seguinte bug:
1. a = Integer.parseInt(args[0]); 2. b = Integer.parseInt(args[1]); 3. while (a < 0) { 4. if (b < 0) { 5. b = b + 2; 6. } 7. a = a + 1; 8. } 9. c = a + b; a b c (res. esperado) -1 -1 1 1 2 3 4 5 7 9
Cobertura de comando: exemplo
Cobertura de Decisão
• Os testes devem cobrir cada saída possível de um nodo que tenha uma condição.
• Métrica: número de arestas cobertas. • Cobertura de condição implica em
cobertura de comando, mas o inverso nem sempre é verdade.
1. a = Integer.parseInt(args[0]); 2. b = Integer.parseInt(args[1]); 3. while (a < 0) { 4. if (b < 0) { 5. b = b + 2; 6. } 7. a = a + 1; 8. } 9. c = a + b; a b c (res. esperado) -1 -1 1 -2 -1 1 1 2 3 4 5 7 9
Cobertura de Decisão: Exemplo
Cobertura de Condição
• Para cada condição deve-se cobrir os dois resultados possíveis.
▪ Ex: if ((A>0) or (B<10)) ...
▪ Exemplos de casos de teste: • A = 3 e B = 20 (A verdade e B Falso) • A = 0 e B = 5 (A falso e B verdade)
Cobertura de Condição múltipla
• Necessidade de verificar melhor osnodos que tem condições múltiplas. • Cria-se uma tabela verdade para cada
nodo desses e gera-se um caso de teste para cada entrada da tabela.
▪ Resulta em diferentes entradas para alguns caminhos que vão se repetir.
1. a = Integer.parseInt(args[0]); 2. b = Integer.parseInt(args[1]); 3. while ((a < 0) or (b < -2)) { 4. if (b < 0) { 5. b = b + 2; 6. } 7. a = a + 1; 8. } 9. c = a + b; 1 2 3 4 5 7 9 Cobertura de Condição Múltipla: Exemplo
a b c (res. esp) -1 (V) -1 (F) 1 0 (F) -1 (F) -1 -1(V) -3 (V) -1 0 (F) -3 (V) 0
Cobertura de Repetição
• Gerar casos de teste de maneira quecada repetição seja exercitada pelo menos k vezes.
• Deve ser usada em combinação com a cobertura de condição.
• Pode-se aplicar técnicas de valor limite nos laços.