Carregar apresentação
A apresentação está carregando. Por favor, espere
PublicouSonia Moreira Lobo Alterado mais de 8 anos atrás
1
Data Flow Testing
2
Vários critérios de adequação até aqui Baseado em entradas de função (funcional) Baseado na estrutura do programa (estrutural) Baseado em faltas injetadas (mutação)
3
Algumas limitações também... Funcional Inadequado para construir entradas que leva a caminhos específicos do programa Estrutural Pode gerar muitos caminhos desnecessários (e.g., exercitar mesmo loop repetidamente.) Baseado em falhas Modelo de falhas irrealista
4
Critério baseado em fluxo de dados Hipótese Falta modifica estado de um programa de forma incorreta Falha manifesta-se através da leitura deste estado Relação de leitura e escrita entre dados é importante!
5
Critério baseado em fluxo de dados Abordagem Suíte deve incluir testes que executam statements logicamente relacionados E.g., escrita e posterior leitura de um campo de um objeto devem aparecer em um mesmo teste
6
DU Pair Associação de definição e uso de variáveis do programa Neste contexto, uma definição é uma nova atribuição de valor a uma variável
7
Exemplo 01: public static int foo(int a) { 02: if (a > 10) { 03: a++; 04: } 05:... 06: return a; 07: } DU pairs: (01,02), (01,03),... Assuma que parâmetro define um valor
8
Exemplo 01: public static int foo(int a) { 02: if (a > 10) { 03: a++; 04: } 05:...// nova definição de a? 06: return a; 07: } DU pairs: (01,02), (01,03), (03,06)? Linha 05 pode redefinir variável a.
9
DU Path Caminho que associa uma definição ao uso de uma variável Vários DU Paths para um DU Pair E.g. 01: int x = 1; 02: if (...) { 03:... 04: } else { 05:... 07: } 08: System.out.println(“x value”+ x);
10
Cobertura de uma suíte de testes du pairs: fração de todos os pares du que são cobertos por pelo menos um teste du paths: fração de todos os caminhos (desconsiderando loop) du que são cobertos por pelo menos um teste definitions: fração de definições cobertas pelos pares du que são cobertos por pelo menos um teste
11
Desafios gerais de análises estáticas Abrangência: whole-program analysis, main Profundidade: intraprocedural, interprocedural Características de programas: encapsulamento de dados, ponteiros e arrays
12
Interprocedural public class Sample { int x; public static void main(String[] args){ Sample s = new Sample(); s.x = read(System.in); if (s.x > 10) { s.x--; } s.f(); } public void f() { s.x++; } } Definição de s.x se propaga até Sample.f
13
Interprocedural public class Sample { int x; public static void main(String[] args){ Sample s = new Sample(); s.x = read(System.in); if (s.x > 10) { s.x--; } s.f(); } public void f() { s.x++; } } Definição de s.x se propaga até Sample.f Duas definições alcançam a entrada de f
14
Interprocedural public class Sample { int x; public static void main(String[] args){ Sample s = new Sample(); s.x = read(System.in); if (s.x > 10) { s.x--; } s.f(); } public void f() { s.x++; } } Definição de s.x se propaga até Sample.f Duas definições alcançam a entrada de f Análise é feita sobre funções alcançáveis a partir de main
15
Análise a partir de função main Reduz complexidade da análise estática Muitas funções não são alcançáveis (usadas) No contexto de testes é útil para medir cobertura Requisitos de teste (cobertura) são construídos a partir de uma sequência de teste
16
O que fazer quando é preciso analisar dependências sob vários contextos? (sem o main )
17
Construção de contextos Mas que contextos são esses? (além de main) Heurística: assuma ao menos que os métodos de uma classe estão relacionados
18
Várias funções e encapsulamento public class Stack { int num; T[] elems; public void push(T t) { num++; elems[num]=t; } public T pop() { elems[num] = null; num--; } public T peek() { return elem[num]; } }
19
Várias funções e encapsulamento public class Stack { int num; T[] elems; public void push(T t) { num = num + 1; elems[num]=t; } public T pop() { elems[num] = null; num = num - 1; } public T peek() { return elem[num]; } } definições e uso peek pode usar definições de elems e num construídas pelo construtor de Stack, push, e pop.
20
Note que não há função main associando peek, push, e pop.
21
Encapsulamento de dados public class Foo { Stack s; public Stack getStack() { return s; } public void foo() {...getStack().peek();...} public void bar(int k) {...getStack().push(k);...} } public class Stack { int num; T[] elems; public void push(T t) { num++;... } public T pop() { num--;... } public T peek() { return elem[num]; } } Foo.foo usa definições construídas em Foo.bar.
22
Encapsulamento de dados public class Foo { Stack s; public Stack getStack() { return s; } public void foo() {...getStack().peek();...} public void bar(int k) {...getStack().push(k);...} } public class Stack { int num; T[] elems; public void push(T t) { num++;... } public T pop() { num--;... } public T peek() { return elem[num]; } } Campo do tipo Stack é estado encapsulado em Foo. Foo.foo usa definições construídas em Foo.bar.
23
Leituras adicionais Capítulo 13 (Data Flow Testing) do livro “Software Testing and Analysis” “Efficient Computation of Interprocedural Definition-Use Chains”, M. J. Harrold and M. L. Soffa, ACM TOPLAS 1994
Apresentações semelhantes
© 2024 SlidePlayer.com.br Inc.
All rights reserved.