• Nenhum resultado encontrado

Busca meta-heurística para resolução de CSP em teste de software

N/A
N/A
Protected

Academic year: 2021

Share "Busca meta-heurística para resolução de CSP em teste de software"

Copied!
118
0
0

Texto

(1)Universidade Federal de Pernambuco Centro de Ciências Exatas e da Natureza Centro de Informática. Pós-graduação em Ciência da Computação. Busca Meta-Heurística para Resolução de CSP em Teste de Software Mitsuo Takaki. Recife Setembro de 2009.

(2) Universidade Federal de Pernambuco Centro de Ciências Exatas e da Natureza Centro de Informática. Mitsuo Takaki. Busca Meta-Heurística para Resolução de CSP em Teste de Software. Trabalho apresentado ao Programa de Pós-graduação em Ciência da Computação do Centro de Informática da Universidade Federal de Pernambuco como requisito parcial para obtenção do grau de Mestre em Ciência da Computação.. Orientador: Co-orientador:. Prof. Dr. Ricardo Bastos Cavalcante Prudêncio Prof. Dr. Marcelo Bezerra d’Amorim. Recife Setembro de 2009.

(3) Takaki, Mitsuo Busca meta-heurística para resolução de CSP em teste de software / Mitsuo Takaki. - Recife: O autor, 2009. xi, 105 folhas : il., fig., tab.. Dissertação (mestrado) - Universidade Federal de Pernambuco. CIN. Ciência da Computação, 2009. Inclui bibliografia e apêndice. 1.Inteligência artificial. I. Título.. 006.3. CDD (22.ed.). MEI-2009-137.

(4) Dedico esta dissertação à minha mãe, minha fonte de inspiração durante este mestrado..

(5) Agradecimentos. Agradeço à minha mãe, pela constante dedicação e apoio e por ter me mostrado o que é ser pesquisador. Seu esforço para alcançar o que sonhava me serviu de inspiração neste mestrado. À minha noiva Roberta, por estar sempre ao meu lado, me apoiando nos momentos mais difíceis, e por me motivar e ajudar a concluir este trabalho. Aos meu orientadores Ricardo Prudêncio e Marcelo d’Amorim, por terem me orientado e ajudado em diversas situações, além do mestrado. Sou grato pelas orientações durante as dificuldades que surgiram no desenvolvimento deste trabalho. Obrigado por acreditarem na minha capacidade e pelas oportunidades que obtive durante este período que trabalhamos juntos. À professora Flávia Barros, que me orientou inicialmente, e que sem o seu apoio não estaria onde estou agora. Obrigado pela oportunidade e pela confiança no meu trabalho. Ao meu amigo Márcio Ribeiro, que, graças aos conhecimentos que me passou, pude concluir este trabalho. Aos meus amigos Edeilson, Edilson, Eduardo, Leopoldo, Mário, Paulo e Ivan pela convivência e apoio durante este mestrado.. iv.

(6) Resumo. Os algoritmos de busca meta-heurística vêm sendo pesquisados em inúmeros domínios, inclusive na resolução de restrições. Devido à sua capacidade de atuação em problemas que a solução é desconhecida, são utilizados em diversas situações. Os algoritmos evolutivos são uma família dos algoritmos de busca, que simulam o comportamento da natureza. Os problemas de satisfação de restrição (CSP) são compostos por um conjunto de conjunções de variáveis, caracterizando uma restrição. Valores são associados às variáveis, os quais devem satisfazer a restrição, caso contrário, são considerados inválidos. Problemas de resolução de restrição estão associados a diversos contextos, desde problemas de alocação de recursos a design de circuitos integrados. Algoritmos de busca meta-heurística vêm sendo utilizados para a solução de CSP, resolvendo o problema da limitação dos provadores de teoremas, que necessitam modelar uma teoria para serem capazes de encontrar uma solução. Neste trabalho, investigamos o uso do algoritmo de busca meta heurística em um tipo de teste de software (execução concólica) que é tratado como um problema de CSP. A execução concólica se baseia no teste simbólico, o qual extrai as decisões internas de um programa que formam uma restrição, também conhecidas como Path Condition (PC). Estas restrições são formadas a partir das variáveis de entrada, portanto, a solução de uma restrição determina as entradas necessárias para percorrer um determinado caminho no software. As técnicas clássicas utilizam provadores de teoremas, os quais são limitados a teoria suportada, e métodos de randomização, que geram valores aleatórios para as variáveis, reduzindo a complexidade da restrição. A presente dissertação teve como objetivo criar e analisar o desempenho de solucionadores baseados em algoritmos de busca meta-heurística, sendo comparados às técnicas clássicas utilizadas neste contexto. Os resultados mostraram que o uso de heurísticas de busca pode permitir a criação de novas técnicas de resolução de restrição, no contexto de teste simbólico. Palavras-chave: Problema de Satisfação de Restrição, Execução Concólica, Algoritmos de Busca Meta-Heurística. v.

(7) Abstract. The meta-heuristic search algorithms have been researched in several domains, including in constraint satisfaction problem. Due to its good adaptability to be used in problems where the actual solution is unknown, they are applied in innumerous contexts. The evolutive algorithms are a search algorithm family that simulates the nature behavior. The constraint satisfaction problem (CSP) is a set of variables conjunction, compounding a constraint. Values are associated to the variables, which should satisfy the constraint; otherwise, it violates the restriction. CSP are related to innumerous domains, from resource allocation to integrated circuits design. Meta-heuristic search algorithms have been used for solving CSP, surpassing the theorem prover limitation problem that needs a theory modeling in order to be able to find a solution. This work, we investigated the usage of meta-heuristic search algorithms in a kind of software test (concolic execution) that is dealt as a constraint satisfaction problem. The concolic execution is based on the symbolic test, which is a technique used to gather internal decisions of software, which compound a restriction also called as Path Condition (PC). These restrictions are formed by the input variables, thus, the solution of them is used as input data to traverse a specific path in the software. The classical techniques use theorem prover, which are constrained by the theory supported, and randomization methods, that generates random values for the variables, reducing the constraint complexity. The current dissertation had as main objective to create and analyze the performance of meta-heuristic search based solvers, being compared to the classical techniques used in this context. The results have shown that the usage of search heuristics may allow the creation of new constraint satisfaction techniques in the symbolic test domain. Keywords: Constraint Satisfaction Problem, Concolic Execution, Meta-Heuristic Search Algorithms. vi.

(8) Sumário. 1. 2. Introdução. 1. 1.1. Objetivos. 3. 1.2. Organização da Dissertação. 5. Busca Meta-Heurística. 7. 2.1. Algoritmos de Busca e Otimização. 7. 2.2. Busca Local e Global. 10. 2.3. Algoritmos Evolutivos. 11. 2.3.1. Algoritmos Genéticos (AG). 11. 2.3.2. Otimização por Enxame de Partículas (PSO). 11. 2.3.3. Influência da Dimensionalidade e Tamanho da População. 15. 2.4. 2.5 3. Problema de Satisfação de Restrições (CSP). 16. 2.4.1. Algoritmos Completos. 16. 2.4.2. Algoritmos Incompletos. 17. 2.4.3. Algoritmos Evolutivos em CSP. 17. Considerações Finais. 18. Teste de Software. 20. 3.1. Teste de Software. 20. 3.2. Técnicas de Teste. 21. 3.3. Fases de Teste. 23. 3.4. Testes de Caixa Preta. 25. 3.5. Testes de Caixa Branca. 28. 3.6. Critérios de Adequação e Métricas. 29. 3.7. Criação de Casos de Teste. 31. 3.8. Teste Simbólico. 32. 3.8.1. 33. Problema de Resolução de Restrições no Contexto de Teste Simbólico vii.

(9) SUMÁRIO. 3.9. 4. 6. 34. 3.10 Teste Randômico. 35. 3.11 Considerações Finais. 36. Metodologia. 38. 4.1. Framework. 38. 4.1.1. Biblioteca Simbólica e Instrumentador. 40. 4.1.2. Driver. 41. 4.1.3. Solvers. 41. 4.1.4. Solvers Híbridos. 44. 4.2 5. Execução Concólica. viii. Representação do Problema. 45. Experimentos. 49. 5.1. Descrição dos Experimentos. 49. 5.2. Resultados Gerais. 52. 5.2.1. Impacto do timeout. 55. 5.2.2. Impacto dos Parâmetros dos Algoritmos de Busca. 62. 5.3. Discussão dos Resultados. 66. 5.4. Considerações Finais. 70. Conclusões. 71. 6.1. Contribuições. 71. 6.2. Limitações e Trabalhos Futuros. 72. 6.3. Considerações Finais. 74. A Gráficos. 75. B Tabelas. 79. C Códigos Fonte. 89.

(10) Lista de Figuras. 1.1. Conjunto de decisões internas.. 3. 2.1. Mínimo local e global.. 8. 2.2. Exemplo de um vale.. 10. 2.3. Operadores de cross-over e mutação.. 12. 2.4. Algoritmo genético.. 13. 2.5. Algoritmo do PSO.. 14. 2.6. Exemplos de topologias.. 15. 3.1. Processo de Testes.. 21. 3.2. Processo de Testes.. 23. 3.3. Fases de Teste e Seus Requisitos.. 24. 3.4. Teste de Unidade.. 25. 3.5. Exemplo de um grafo de causa e efeito.. 27. 3.6. Exemplo de código fonte com um branch.. 30. 3.7. Exemplo de código fonte com um loop.. 30. 3.8. Gráfico do custo relativo de correção de um defeito.. 33. 3.9. Conjunto de decisões internas (Path Condition).. 34. 3.10 Exemplo de um PC.. 35. 4.1. Arquitetura utilizada.. 39. 4.2. Exemplo de uma árvore semântica.. 40. 4.3. Código fonte de BST original e instrumentado.. 42. 4.4. Driver do programa BST.. 43. 4.5. Arquitetura utilizada pelos solvers.. 44. 4.6. Representação no plano cartesiano dos espaço de busca.. 47. 4.7. Operação de transposição da representação do problema para a árvore semântica. 48. ix.

(11) LISTA DE FIGURAS. x. 5.1. Diagrama de Venn do desempenho dos solvers aleatórios.. 56. 5.2. Diagrama de Venn do desempenho dos solvers híbridos GCF.. 57. 5.3. Diagrama de Venn do desempenho dos solvers híbridos BCF.. 58. 5.4. Diagrama de Venn do desempenho dos solvers híbridos.. 59. 5.5. Comportamento da função MaxSAT.. 60. 5.6. Comportamento da função SAW.. 61. 5.7. Cobertura dos solvers nos programas Switch e Colt. 63. 5.8. Influência dos parâmetros de AG.. 64. 5.9. Influência dos parâmetros de AG.. 65. 5.10 Influência dos parâmetros de PSO.. 67. 5.11 Influência dos parâmetros de PSO.. 68. A.1 Cobertura dos solvers utilizando gráfico de barras empilhadas no experimento BST.. 75. A.2 Cobertura dos solvers utilizando gráfico de barras empilhadas nos experimentos FileSystem e TreeMap.. 76. A.3 Cobertura dos solvers utilizando gráfico de barras empilhadas nos experimentos RatPoly e RationalScalar.. 77. A.4 Cobertura dos solvers utilizando gráfico de barras empilhadas nos experimentos Newton e HashMap.. 78.

(12) Lista de Tabelas. 4.1. Exemplo de uma representação através de um código genético.. 46. 5.1. Comparação dos Experimentos.. 52. 5.2. Tabela da cobertura média dos pares: experimento (linha) e solver (coluna).. 53. 5.3. Desvio padrão da tabela 5.2.. 54. B.1 Comparação dos resultados dos solvers no experimento BST.. 80. B.2 Comparação dos resultados dos solvers no experimento FileSystem.. 81. B.3 Comparação dos resultados dos solvers no experimento TreeMap.. 82. B.4 Comparação dos resultados dos solvers no experimento Switch.. 83. B.5 Comparação dos resultados dos solvers no experimento RatPoly.. 84. B.6 Comparação dos resultados dos solvers no experimento RationalScalar.. 85. B.7 Comparação dos resultados dos solvers no experimento Newton.. 86. B.8 Comparação dos resultados dos solvers no experimento HashMap.. 87. B.9 Comparação dos resultados dos solvers no experimento Colt.. 88. xi.

(13) C APÍTULO 1. Introdução. Os algoritmos de busca meta-heurística constituem uma família de algoritmos utilizados na solução de diversos problemas percorrendo um espaço de busca. O termo meta-heurística foi inicialmente utilizado por Glover (1986), onde é descrito o algoritmo Tabu Search como uma meta-heurística sobreposta em outra heurística. Podem ser aplicados em diversos contextos, desde o design de circuitos integrados à teste de técnicas de criptografia (Silva e Sakallah; 1996). O algoritmo de força bruta, ou busca cega, é o mais simples exemplo de um método de busca, percorrendo todo o espaço de busca até que uma solução seja encontrada. Este método é capaz de garantir que, se existir, uma solução será encontrada, porém o tempo de busca pode se tornar extremamente grande. Neste sentido, métodos que criam uma solução aleatória e, iterativamente, melhoram até encontrar uma solução aceitável tornam possível encontrar soluções em um espaço de tempo mais aceitável. Porém, estes métodos são algoritmos de busca local, ou seja, não são capazes de transpor áreas de mínimos ou máximos locais, portanto nescessitam de diferentes inicializações para buscar a melhor solução (mínimo ou máximo global). Um exemplo de um método iterativo de melhoria de solução é o algoritmo de subida da encosta (hill climbing), que simula a subida de uma colina e pára sua execução quando chega ao topo. Para resolver o problema da transposição de áreas de mínimos ou máximos locais, foram propostos diferentes algoritmos, como exemplo a têmpera simulada (simulated annealing) (Kirkpatrick et al.; 1983). O algoritmo inicia realizando grandes passos e o tamanho dos passos é reduzido gradativamente, permitindo percorrer grandes espaços no inicio e realizar pequenos incrementos no final (Russell e Norvig; 2003, p. 94-131). O algoritmo genético (AG) (Holland; 1975) e a otimização por enxame de partículas (Particle Swarm Optimization – PSO) (Kennedy e Eberhart; 1995) fazem parte dos algoritmos de busca, mais especificamente dos algoritmos evolutivos, e se baseiam em comportamentos observados na natureza. AG foi proposto para introduzir o comportamento de adaptação aos sistemas. PSO foi criado por Kennedy e Eberhart (1995) a partir da observação do comportamento. 1.

(14) CAPÍTULO 1 INTRODUÇÃO. 2. de grupos, o qual mimetiza a criação de estruturas sociais, onde indivíduos podem influenciar o grupo e, ao mesmo tempo, os indivíduos são influenciados pelo grupo. Eles são métodos de busca global, ou seja, são capazes de transpor áreas de mínimos, ou máximos, locais. Os mínimos, ou máximos, locais são soluções do espaço de busca, porém não são as melhores soluções de um problema. Em problemas de otimização, o algoritmo busca pelo mínimo ou máximo global. A função objetivo, ou função de fitness, direciona o algoritmo, avaliando a qualidade das soluções candidatas. O algoritmo de subida da encosta, têmpera simulada, AG e PSO podem ser denominados, de uma forma geral, de métodos de busca meta-heurística. Por outro lado, o algoritmo de força bruta não é considerado uma meta-heurística por não utilizar nenhuma heurística na busca da solução, pois o algoritmo percorre exaustivamente o espaço de busca. Algoritmos de busca meta-heurística têm sido usados com freqüência em problemas de resolução de restrições (ou constraint satisfaction problem, CSP). O problema de resolução de restrições é a determinação de valores para variáveis que compõem uma restrição. Este tipo de problema está relacionado a diversos contextos, desde o problema clássico de coloração de grafos à problemas de alocação. O uso de algoritmos de busca neste contexto é bem conhecido pelo comunidade (Zhou et al.; 2009; Lin; 2005; Rossi et al.; 2000; Marchiori e Rossi; 1999; Folino et al.; 1998). Um exemplo de CSP é atribuir valores às variáveis (x e y) de forma a satisfazer todas as cláusulas da seguinte sentença: (x = y2 ) ∧ (x < 10) ∧ (y ≥ 0), onde uma possível solução para esta restrição é: x = 4 e y = 2. Diversas soluções foram propostas no desenvolvimento de funções de fitness, mais especificamente MaxSAT (Folino et al.; 1998; Rossi et al.; 2000; Marchiori e Rossi; 1999) e Step-Wise Adaptation of Weigths (SAW) (Bäck et al.; 1998; Eiben e van der Hauw; 1997). MaxSAT apenas conta o número de cláusulas satisfeitas, o que permite identificar quando uma solução candidata satisfaz a restrição. Entretanto, MaxSAT não é capaz de direcionar corretamente o algoritmo, pois nem sempre encontrar uma solução candidata que resolve a maior parte das cláusulas significa estar na direção correta. SAW utiliza um método de identificar cláusulas “difíceis” de resolver, atribuindo pesos as mesmas. Desta forma, a solução candidata que resolve uma cláusula difícil, deve ser recompensada por isto – através de um valor de fitness mais alto. O foco da presente dissertação é a resolução de CSP no contexto de teste de software, mais especificamente com teste simbólico. O teste simbólico é uma técnica de extração do conjunto.

(15) 1.1 OBJETIVOS. 3. Figura 1.1: Um exemplo de um conjunto de decisões internas.. de decisões internas de um sistema – também chamado de Path Condition (PC) –, as quais caracterizam uma restrição e o conjunto de dados de entrada são as variáveis destas restrições. Na figura 1.1 está um exemplo de um programa, onde as seguintes restrições são geradas: (x > y)∧(x%2 = 0), (x > y)∧(x%2 6= 0), (x ≤ y)∧(y % 2 = 0) e (x ≤ y)∧(y % 2 6= 0). Existem soluções clássicas para resolver estes restrições, as quais envolvem o uso de provadores de teorema. Os provadores de teorema possuem um poder de atuação limitado à teoria suportada. Facilmente programas simples geram restrições não-lineares, como no exemplo da figura 1.1 que possui operador de resto de divisão (%). Os solvers aleatórios são capazes de resolver restrições, independente do tipo de operador utilizado. Esta característica permite que estes sejam aplicados na resolução de CSP, onde apresentam resultados motivantes (Godefroid et al.; 2005; Majumdar e Sen; 2007).. 1.1 Objetivos As soluções propostas por Godefroid et al. (2005) e Majumdar e Sen (2007) não utilizam nenhum tipo de heurística na geração de valores para a resolução de restrições ou para reduzir a complexidade das restrições. Os resultados obtidos por estas técnicas produziram resultados.

(16) 1.1 OBJETIVOS. 4. motivantes e o uso de meta-heurísticas de busca pode produzir melhores resultados. O principal objetivo deste trabalho é a aplicação de meta-heurísticas de busca em solvers para resolver restrições provenientes de uma execução concólica, além de analisar o desempenho destes solvers em softwares com diferentes características. O trabalho de Lakhotia et al. (2008) utilizou o algoritmo de subida da encosta para resolução de restrições da execução concólica, porém o uso de algoritmos evolutivos, neste contexto, não havia sido proposto anteriormente. O uso destes algoritmos para a resolução de restrições é a principal contribuição deste trabalho. Os solvers baseados em algoritmos de busca foram propostos de duas formas: usados diretamente e combinados ao solver simbólico (symSOL). Os solvers híbridos utilizam três estratégias: restrições “boas” primeiro (Good Constraints First – GCF), restrições “ruins” primeiro (Bad Constraints First – BCF) e variáveis “ruins” primeiro (Bad Variables First – BVF). GCF e BCF separa as restrições em partes “boas” e “ruins”. São chamadas de “boas” as restrições que estão dentro do escopo da teoria suportada por symSOL e, conseqüentemente, “ruins” as que estão fora do escopo. GCF resolve primeiro as restrições “boas” no symSOL e passa o restante para o solver randômico (puramente aleatório, AG ou PSO). Isto permite que a restrição seja simplificada, gerando uma nova restrição reduzida. De forma contrária, BCF resolve as restrições “ruins” primeiro, passando para symSOL uma restrição com complexidade reduzida, permitindo que este a resolva. BVF, se baseia no DART Godefroid et al. (2005), gerando valores aleatórios para as variáveis que compõem as cláusulas não satisfatíveis por symSOL. Nesta dissertação, foram avaliadas quatro abordagens clássicas, um solver simbólico e três híbridos. Três solvers aleatórios foram comparados, utilizando um algoritmo puramente aleatório, AG e PSO. Às estratégias de hibridação, exceto BVF, foram combinados os solvers baseados em AG e PSO, substituindo o solver puramente aleatório mais comumente utilizado. Nesta avaliação foram utilizados nove experimentos, algumas implementações de estruturas conhecidas, como árvore binária de busca e tabela de hash, e bibliotecas de uso matemático. A partir da análise do desempenho dos solvers nos experimentos escolhidos, foi possível observar que o uso de meta-heurísticas de busca produz bons resultados, especialmente em situações que o uso de um solver simbólico não é possível ou sua capacidade de atuação é limitada. Problemas em que o espaço de busca se torna muito grande, os solvers que utilizam geração de valores puramente aleatória não são capazes de resolver a maior parte das restrições geradas. Entretanto, em espaços de busca reduzidos o uso de heurísticas não se justifica devido.

(17) 1.2 ORGANIZAÇÃO DA DISSERTAÇÃO. 5. seu maior custo computacional.. 1.2 Organização da Dissertação Este trabalho está organizado da seguinte forma: Capítulo 2 Introdução aos algoritmos de busca, passando pelo principais métodos de busca iterativa e introdução aos algoritmos evolutivos. O problema de satisfação de restrições (CSP) é apresentado e como estes algoritmos podem ser aplicados neste contexto. Considerando o objetivo deste trabalho ser uma aplicação de algoritmos evolutivos em CSP, é dado uma maior ênfase nestes algoritmos e suas aplicações em CSP, sendo apresentada uma proposta de representação do problema e a determinação o espaço de busca de acordo com esta representação. Capítulo 3 Introdução ao teste de software, separando em dois grupos: funcionais e estruturais. Em cada grupo estão definidos os tipos de testes e seus critérios de adequação. O problema da automação da geração de casos de teste é apresentado com a solução abordada no presente trabalho: teste simbólico. O teste simbólico possui deficiências que são supridas com o advento da execução concólica. Esta solução determina a capacidade de suprir as lacunas deixadas pelo teste simbólico. São apresentados os path conditions (PC) e como estes podem ser vistos como um CSP. O uso de provadores de teoremas (solvers simbólicos – symSOL) para a resolução destes PCs, abordando que esta solução não é aplicável, pois freqüentemente uma aplicação simples pode gerar restrições que estão fora do escopo do provador. No caso em que symSOL é capaz de resolver problemas de aritmética inteira linear, estes PCs podem ser simplificados à uma forma satisfatível. Esta solução é apresentada, contudo, suas deficiências são identificadas. Capítulo 4 A metodologia utilizada é apresentada, com a arquitetura proposta para o desenvolvimento do framework, onde cada componente do framework é apresentado. A representação do problema escolhida é apresentada com suas possíveis implicações na definição do espaço de busca. Capítulo 5 A solução proposta para prover uma heurística aos métodos de randomização de restrições é apresentada. São identificadas deficiências nos algoritmos escolhidos e como seu desempenho é afetado pelo tempo de execução (timeout). Os experimentos escolhidos são.

(18) 1.2 ORGANIZAÇÃO DA DISSERTAÇÃO. 6. detalhados e caracterizados pelo tipo de restrição que sua execução gera. Os resultados obtidos são apresentados, comparando o desempenho de cada solver em nove experimentos. Os efeitos do timeout e variação do seed do número aleatório são analisados. Além disso, uma discussão sobre as características dos algoritmos de busca de acordo com o experimento é realizada e demonstradas as conclusões extraídas dos resultados. Capítulo 6 As conclusões deste trabalho são apresentadas, como também, as contribuições, limitações e perspectivas para os pontos de melhoria que poderão gerar mais investigação..

(19) C APÍTULO 2. Busca Meta-Heurística. Este capítulo apresenta uma introdução aos algoritmos de busca meta-heurística e o problema de satisfação de restrições (Constraint Satisfaction Problem - CSP), dando uma ênfase maior aos algoritmos evolutivos e suas aplicações em CSP. Os solvers de CSP estão sendo apresentados, separados, em dois grupos: completos e incompletos. Os algoritmos incompletos se referem ao tema principal nesta seção, visto que o objetivo deste trabalho é a aplicação de algoritmos de busca meta-heurística na resolução de restrições.. 2.1 Algoritmos de Busca e Otimização A inteligência artificial vem sendo utilizada na resolução de problemas e, mais especificamente, em problemas de otimização. A resolução automática é realizada através de métodos inteligentes, onde a aquisição de conhecimento pode ocorrer durante a execução ou previamente. Existem diversas técnicas, sendo que cada uma possui características que a tornam apta a resolver problemas específicos. Contudo, não existe um método capaz de resolver qualquer problema, este deve ser escolhido de acordo com o contexto. São chamados de problemas de otimização os problemas que requerem que seus dados sejam modificados para que atinjam um certo grau de qualidade. Vão desde problemas de rota (e.g., problema do caixeiro viajante) até problemas complexos de otimização de funções. Os problemas podem ser definidos por quatro componentes, segundo Russell e Norvig (2003, cap. 3): o estado inicial, as ações possíveis, o teste de objetivo e uma função de custo. Para resolver os problemas, os algoritmos de otimização realizam uma busca de soluções em um espaço de estados. Máximo global (ou mínimo global) é a melhor solução em todo espaço de busca, a qual é o objetivo de todos os problemas de otimização. Máximo local (ou mínimo local) é a melhor solução em um subespaço de busca. Um exemplo de uma função e seu mínimo global e local. 7.

(20) 2.1 ALGORITMOS DE BUSCA E OTIMIZAÇÃO. 8. Figura 2.1: Uma função de exemplo com seu mínimo global (círculo vermelho) e seu mínimo local (triângulo azul).. é apresentada na figura 2.1. Algoritmos de busca que melhoram seus resultados sem guardar estados anteriores tendem a ficarem presos em máximos locais. Os algoritmos de busca procuram por soluções para um problema específico, em um grande espaço de possíveis soluções. Uma função de fitness, também chamada de função objetivo, é utilizada para validar estes candidatos e medir a qualidade desta solução. Os algoritmos de busca podem ser utilizados quando não há um conhecimento sobre a solução real para o problema, entretanto, a função de fitness deve ser capaz de identificar quando a solução foi encontrada. Muitas pesquisas vem sendo realizadas nesta área e várias novas técnicas foram propostas, cada uma aplicável a um determinado domínio. Dentre essas técnicas citamos inicialmente: • Busca por força-bruta Também conhecido como busca cega, é o mais simples. Utiliza um método simples, o qual precisa percorrer todo o espaço de busca, que, dependendo do problema, pode demandar um esforço imenso. Toda possível solução deve ser analisada e nenhum conhecimento é adquirido durante este processo. O uso de algoritmos baseados em heurísticas pode reduzir o tempo gasto nesta operação. Entretanto, o algoritmo de força-bruta é ca-.

(21) 2.1 ALGORITMOS DE BUSCA E OTIMIZAÇÃO. 9. paz de garantir a existência, ou a ausência, de soluções para o problema, apesar de o tempo aumentar consideravelmente quando o número de estados aumenta. Mas, eventualmente, a melhor solução será encontrada. Quando não há uma limitação de tempo, esta torna-se a melhor escolha para um problema de otimização. • Subida da encosta (Hill-Climbing) Algoritmo iterativo de melhoria, em outras palavras, ele melhora sua solução inicial passo a passo. A solução inicial é escolhida aleatoriamente e, então, é melhorada até atingir um resultado aceitável. Esta técnica não armazena estados anteriores, move-se no espaço de busca enxergando apenas o estado atual (Russell e Norvig; 2003, p. 94-131). Portanto, não é capaz de atingir resultados ótimos, apesar de eventualmente poder atingir, mas fornece soluções aceitáveis, as quais necessitariam de um longo período de tempo para serem encontradas pelo algoritmo de força bruta. Devido a sua inicialização estocástica, este algoritmo torna-se sensível à sua inicialização, ou seja, depende fortemente de um bom estado inicial para encontrar o máximo global. • Têmpera Simulada (Simulated Annealing) O algoritmo de subida da encosta não é capaz de realizar movimentos de “descida” da encosta para que possa sair de um máximo local. Introduzir uma certa aleatoriedade à subida da encosta, pode trazer melhorias ao seu desempenho, permitindo que este saia de picos e encontre novos máximos locais – podendo eventualmente encontrar o máximo global. Criado por Kirkpatrick et al. (1983), foi inspirado na metalurgia, a têmpera é o processo utilizado para temperar ou endurecer metais e vidros, aquecendo-os a altas temperaturas e depois resfriando-os gradualmente. Um comportamento análogo é reproduzido no algoritmo da têmpera simulada, que inicia sua busca com um grau de exploração do espaço de estados alto e gradativamente reduz essa exploração. • Algoritmos Evolutivos É uma família de algoritmos baseados em comportamentos da natureza. Dentre estes algoritmos, se destacam o algoritmo genético (Holland; 1975) e a otimização por enxame de partículas (Kennedy e Eberhart; 1995). Estes algoritmos serão detalhados na seção 2.3..

(22) 2.2 BUSCA LOCAL E GLOBAL. 10. Figura 2.2: Um função de exemplo onde é possível observar uma área de fitness homogêneo ou um vale.. 2.2 Busca Local e Global Os algoritmos de busca local operam utilizando apenas um estado, o qual é melhorado iterativamente. A busca local é uma meta-heurística (Glover; 1986) de busca por soluções, onde uma solução inicial é aprimorada passo a passo, enxergando apenas estados anteriores. Este comportamento acarreta em uma busca que, apesar de manter um histórico, é incapaz de sair de vales ou transpor áreas de fitness homogêneo. Estas situações podem ser observadas na figura 2.2, onde um exemplo de área com fitness homogêneo é apresentada. Nesta situação, o algoritmo local não é capaz de sair de um vale, pois não ocorre incremento no fitness em nenhuma das direções. Além de vales, há também as situações de máximo (ou mínimo) locais apresentadas na figura 2.1. A busca global é utilizada de forma contrária à busca local. Esta visa encontrar a solução ótima em um grande espaço de busca utilizando-se operações menos refinadas, mas que cobrem uma maior área. Algumas estratégias de busca vêm utilizando algoritmos que combinam buscas globais e locais. Soluções são geradas, a partir da busca global, e estas são refinadas utilizando uma busca local..

(23) 2.3 ALGORITMOS EVOLUTIVOS. 11. 2.3 Algoritmos Evolutivos Os algoritmos evolutivos são algoritmos de busca que utilizam operadores baseados em fenômenos da natureza. São chamados de evolutivos devido a esta característica de mimetizar estes fenômenos naturais. Dentre os algoritmos mais populares, podemos citar os: Algoritmos Genéticos e Otimização por Enxame de Partículas.. 2.3.1. Algoritmos Genéticos (AG). Algoritmos genéticos foram propostos por Holland (1975) para introduzir uma capacidade de adaptação aos programas. Pesquisas na área de reprodução de comportamentos da natureza produziram novas técnicas, como algoritmos baseados em inteligência de grupos (swarm intelligence). Diferentemente de outras estratégias evolutivas, Holland (1975) analisou o fenômeno de adaptação, como acontece na natureza, e como aplicá-lo aos sistemas de computadores. AG é baseado na teoria evolutiva das espécies, que evoluem para melhorar suas capacidades de adaptação, de acordo com o ambiente. Cada solução candidata, chamada de indivíduo, é modelada em uma estrutura de cromossomos e aplicada operações de recombinação a essas estruturas, onde a preservação de informações criticas é o objetivo. Esta operação de recombinação é chamada de cross-over e pode ser observada na figura 2.3a. Operadores de mutação também são utilizados para modificar, levemente, as soluções (Whitley; 2002). A figura 2.3b apresenta um exemplo de operação de mutação. Estas operações são realizadas entre a população de soluções até que um certo grau de qualidade é atingido, de acordo com a função fitness onde cada população de uma iteração é chamada de geração. O algoritmo genético provê soluções viáveis em diversas áreas, onde variações do algoritmo básico são utilizadas. Estas áreas vão desde problemas científicos a problemas de engenharia (Mitchell; 1998). Alguns sistemas devem ser capazes de se adaptar a um ambiente em constante mudança, comportamento análogo ao fenômeno da natureza em que indivíduos devem se adaptar para continuarem sua existência. O algoritmo básico do AG está na figura 2.4.. 2.3.2. Otimização por Enxame de Partículas (PSO). Kennedy e Eberhart (1995) propuseram a otimização por enxame de partículas, inspirado pelo comportamento descentralizado de grupos. Cada partícula é um protótipo de solução e cada.

(24) 2.3 ALGORITMOS EVOLUTIVOS. 12. (a) Cross-Over. (b) Mutação. Figura 2.3: Operadores de cross-over e mutação.. uma possui um grau de confiança em si mesma e um grau de confiança no grupo. As partículas movem-se através do espaço de busca visando um resultado ótimo, enquanto informações são adquiridas do problema para melhorar seu desempenho. O grupo armazena a melhor partícula e cada partícula armazena sua melhor solução, até o momento. Estes dados influenciam a próxima posição de cada partícula. As equações (2.1) e (2.2) mostram como a velocidade e a nova posição são calculadas. r1 e r2 são números aleatórios entre 0 e 1, definidos durante a criação de cada partícula, para criar uma distribuição homogênea de diferentes comportamentos, onde existirão indivíduos com maior confiança em si mesmo, indivíduos com maior confiança no grupo e indivíduos com um comportamento mais balanceado. Se r1 tende a zero, a confiança da partícula em si mesma tende a zero e quando r2 tende a zero, a partícula tende a não confiar no grupo. ω é chamado de inércia e é a proporção da velocidade anterior que será usado na próxima velocidade, proporciona uma mudança gradativa na direção do movimento da partícula. Diferentemente de outros algoritmos evolutivos, PSO não usa operadores de cross-over e mutação. O espaço de busca é percorrido pelo PSO através das mudanças de posição das partículas. O grupo exerce uma influência em cada indivíduo, fazendo com que este siga a direção do grupo. Entretanto, os indivíduos também exercem influência no grupo, pois um indivíduo pode.

(25) 2.3 ALGORITMOS EVOLUTIVOS. Algoritmo Algoritmo Genético Entrada n: Tamanho da população. c: Taxa de cruzamento. m: Taxa de mutação. g: Número de gerações. Saída p: Conjunto de soluções candidatas. 1 init(p) {Inicializando a população.} 2 enquanto iteration < g||solutionFound faça 3. para i ← 0 . . . n faça. 4. f itness(p[i]). 5. order(p) {Ordena a população de acordo com o fitness de cada um.}. 6. para i ← 0 . . . n faça{Sorteia dois indivíduos para o cruzamento.}. 7. indexFather ← random(n). 8. indexMother ← random(n). 9. shouldBreed ← random(). 10. shouldMutate ← random(). 11. se shouldBreed ≥ c então. 12. newSub jects ← breed(p[indexFather], p[indexMother]). 13. add(p, newSub jects). 14. se shouldMutate ≥ m então. 15. mutate(newSub jects). 16 17 18 19. para i ← 0 . . . n faça se eval(p[1]) então solutionFound ← true iteration ← iteration + 1 Figura 2.4: Algoritmo genético.. 13.

(26) 2.3 ALGORITMOS EVOLUTIVOS. vt+1 = ω ∗ vt + r1 ∗ c1 ∗ (bestsolution particle − xi ) + r2 ∗ c2 ∗ (bestsolutiongroup − xi ) xt+1 = xt + vt+1. 14. (2.1) (2.2). Algoritmo PSO Entrada n: Tamanho da população.. ω : Inércia. c1 : Grau de confiança na própria partícula. c2 : Grau de confiança na população. g: Número de gerações. Saída p: Conjunto de soluções candidatas. 1 init(p) {Inicializando a população.} 2 enquanto iteration < g||solutionFound faça 3. para i ← 0 . . . n faça. 4. f itness(p[i]). 5. para i ← 0 . . . n faça{Atualiza velocidade e posição.}. 6. updateVelocity(p[i]). 7. updatePosition(p[i]) Figura 2.5: Algoritmo do PSO.. tornar-se, em um determinado momento, a melhor solução do grupo (Li e Engelbrecht; 2007). PSO é capaz de atingir bons resultados em, relativamente, poucos passos – se comparado ao algoritmo genético. É bastante útil em problemas que utilizam dados de ponto flutuante e alta dimensionalidade. Dimensionalidade é o número de dimensões do espaço de busca. Também possui uma implementação bastante simples, o que o torna um algoritmo eficiente. Na figura 2.5, é possível observar o algoritmo básico do PSO. As partículas podem ser organizadas através de uma topologia que determina como estas irão se comportar e interagir uma com as outras. Partículas são influenciadas pelos vizinhos e estas influenciam sua vizinhança. Na formação destas vizinhanças não se deve levar em conta a.

(27) 15. 2.3 ALGORITMOS EVOLUTIVOS. (a) Anel. (b) Estrela. Figura 2.6: Exemplos de topologias utilizadas para determinar vizinhanças.. distância física, geralmente são utilizados seus rótulos (label) para determinar quais partículas fazem parte do mesmo grupo. As vizinhanças criam estruturas sociais que indicam com quais partículas um indivíduo deve interagir (Lin; 2005). Esta estrutura é determinante no desempenho do algoritmo. Estas estruturas podem utilizar formas já conhecidas, como estrela, anel, entre outros, como pode ser visto na figura 2.6. Como esta determina a interação entre as partículas, vai determinar o comportamento das mesmas no espaço de busca.. 2.3.3. Influência da Dimensionalidade e Tamanho da População. O desempenho de algoritmos de busca é diretamente afetado com o aumento da dimensionalidade. Para problemas com um alto número de dimensões, ou seja, um vasto espaço de busca, um número maior de partículas/indivíduos é necessário. Porém, com o aumento do tamanho da população, o desempenho é degradado. A. Carlisle (2001) realizou diversos experimentos e identificou, empiricamente, que uma população de 30 partículas é suficiente para resolver muitos problemas de baixa dimensionalidade. Parsopoulos (2009) fez uma análise do desempenho do PSO em problemas com uma alta dimensionalidade (n ≥ 100, onde n é o número de dimensões) e percebeu que PSO começa a perder desempenho devido ao tamanho do espaço de busca. Parsopoulos (2009) propõe um novo algoritmo, chamado de (µ PSO), para problemas de alta dimensionalidade. µ PSO mantém um baixo custo computacional, enquanto minimiza o.

(28) 2.4 PROBLEMA DE SATISFAÇÃO DE RESTRIÇÕES (CSP). 16. impacto do aumento do número de dimensões.. 2.4 Problema de Satisfação de Restrições (CSP) O problema de satisfação de restrições (CSP) está relacionado à determinação de valores para variáveis que satisfaçam ou atendam a um dado conjunto de restrições. Segundo Russell e Norvig (2003, cap. 5), CSP é definido por um conjunto de variáveis x1 , x2 , . . . , xn e por um conjunto de cláusulas C1 ,C2 , . . . ,Cn . Cada cláusula Ci envolve um subconjunto de variáveis e valores atribuídos. Cada variável xi possui um domínio Di , não-vazio, de valores possíveis. E um estado do problema é uma atribuição a um conjunto de variáveis {xi = vi , x j = v j }, onde vi ∈ Di . Quando uma atribuição não viola nenhuma restrição, então é chamada de consistente ou válida. CSP vem sendo pesquisado em vários contextos, desde design de circuitos integrados através de computador a testes de criptografia (Eibach et al.; 2008). Um problema clássico de CSP é o problema de coloração mapas, um caso específico do problema de coloração de grafo. Neste caso, a cada região do mapa deve ser atribuída uma cor, sem que haja regiões vizinhas com a mesma cor. A criação de solvers automáticos vem evoluindo devido à crescente necessidade da comunidade. Um dos ramos de pesquisa nesta área utiliza solvers aleatórios, que geram valores para satisfazer a restrição. Alguns resultados foram motivantes e aumentaram a pesquisa no uso de solvers aleatórios e sua aplicação em outras áreas. Existem vários algoritmos propostos para resolver CSP, alguns são completos e outros incompletos.. 2.4.1. Algoritmos Completos. Alguns algoritmos completos foram desenvolvidos para resolver o problema de satisfação de restrições. Estes algoritmos são capazes de garantir que uma restrição é satisfatível ou insatisfatível de acordo com seu suporte de teoremas interno. Provadores de teorema vêm sendo utilizados para este propósito, ou seja, resolver problemas de resolução de restrição. Porém estes apresentam uma desvantagem: possuem uma capacidade de atuação limitada, pois necessitam que um teorema seja modelado e introduzido ao mesmo. Devido esta limitação, não existe um solver completo disponível para todo tipo de teorema. Um exemplo é o CVC3 (CVC3 web page; s.d.). O solucionador CVC3 é um provador.

(29) 2.4 PROBLEMA DE SATISFAÇÃO DE RESTRIÇÕES (CSP). 17. de teorema automático que suporta apenas aritmética linear de número inteiros e alguns casos especiais de aritmética não linear. Para restrições dentro deste escopo, o CVC3 é o solver mais apropriado.. 2.4.2. Algoritmos Incompletos. Algoritmos incompletos são baseados em solução aleatória. Esses algoritmos atribuem valores aleatórios as variáveis do problema e verifica se eventualmente os valores satisfazem as restrições. Esses algoritmos não são capazes de afirmar que uma restrição é insatisfatível, sendo apenas capazes de garantir que é satisfatível, quando a solução é encontrada. É classificado como desconhecido quando não é capaz de encontrar uma solução. Vários algoritmos incompletos foram propostos para CSP e, posteriormente, algoritmos de busca foram utilizados para este propósito.. 2.4.3. Algoritmos Evolutivos em CSP. A utilização de algoritmos evolutivos para resolver problemas de restrição já é bastante conhecida na comunidade (Bäck et al.; 1998; Jong e Kosters; 1998; Li e Engelbrecht; 2007; Zhou et al.; 2009; Eiben e van der Hauw; 1997). Nesse uso, cada solução do espaço de busca é uma atribuição de valores para as variáveis do problema CSP. Os algoritmos evolutivos possuem uma capacidade de percorrer os espaços de busca rapidamente e utilizam uma forma de busca global, isto permite que sejam aplicados a este contexto com sucesso. A aquisição de conhecimento do problema é realizada através de funções de fitness, que avaliam a qualidade da solução candidata e medem a distância da solução final. Duas funções de fitness são bastante usadas neste contexto de resolução de restrição, MaxSAT (Folino et al.; 1998; Rossi et al.; 2000; Marchiori e Rossi; 1999) e Step-wise Adaptation of Weights (SAW) (Bäck et al.; 1998; Eiben e van der Hauw; 1997). MaxSAT é uma função simples que conta o número de cláusulas que são satisfeitas pela solução candidata. Apesar de sua simplicidade, esta função é capaz de fornecer uma forma de avaliar a qualidade da solução, pois a solução final deve satisfazer todas as cláusulas. Quanto mais próximo da solução final, maior a quantidade de cláusulas satisfeitas. Porém, MaxSAT não é capaz de prover um direcionamento adequado ao algoritmo de busca. Este último deve ser capaz de tomar decisões onde uma solução “ruim” pode se tornar uma solução “boa”, posteriormente..

(30) 2.5 CONSIDERAÇÕES FINAIS. 18. Bäck et al. (1998) propuseram o Step-wise Adaptation of Weights (SAW) para reduzir o impacto do problema encontrado pela função MaxSAT durante a busca por uma solução ótima. SAW associa pesos a cada cláusula em uma restrição. Cada peso é atualizado a cada iteração que a sua cláusula não é satisfeita. Através do uso de SAW, é possível identificar cláusulas que são mais difíceis de serem resolvidas, com o passar das iterações. O solvers usa esta informação para favorecer os indivíduos que estão resolvendo as cláusulas mais difíceis. Problemas simples podem possuir vastos espaços de busca, com poucas soluções. Nem sempre resolver uma cláusula significa estar no caminho correto. Este tipo de decisão é realizada pela função SAW. Utilizando a função MaxSAT, o algoritmo poderia ficar preso em uma das linhas azuis, que possuem um valor de fitness relativamente alto. Em um algoritmo completo, de força-bruta, para encontrar uma solução neste espaço de busca, seria necessário um grande esforço computacional, onde todos os estados seriam testados até que uma solução fosse encontrada. Algumas observações devem ser feitas sobre a resolução de CSP com PSO. A representação do problema é realizada de acordo com o domínio do tipo das variáveis. Para restrições com variáveis inteiras, apenas número inteiros serão utilizados na representação. Esta modificação permite que o PSO seja capaz de percorrer o espaço de busca de acordo com o tipo de dados. PSO originalmente utiliza valores ponto-flutuante e esta característica dificulta a busca por soluções em um domínio de valores inteiros. Esta solução foi proposta por Kennedy e Eberhart (1997), chamado de PSO discreto, ou binário. Permite aplicar PSO em outros contextos, além de otimização de funções matemáticas contínuas não-lineares. A adaptação do algoritmo genético à resolução de CSP é realizada de forma simples, pois este não possui a mesma dependência de números ponto-flutuante.. 2.5 Considerações Finais Os algoritmos de busca meta-heurística podem ser aplicados em muitos contextos, incluindo resolução de restrições. Estas pesquisas trouxeram muitas soluções práticas, com resultados motivantes (Folino et al.; 1998; Silva e Sakallah; 1996; Takaki et al.; 2009; ?; Zhou et al.; 2009), apesar de algoritmos incompletos não serem capazes de garantir que uma solução será encontrada. Esta escolha, usar algoritmos incompletos devido a seu ganho de desempenho, é.

(31) 2.5 CONSIDERAÇÕES FINAIS. 19. aceitável quando existe uma limitação de tempo. Essa limitação de tempo é importante em problemas que necessitam obter um resultado em curtos espaços de tempo. O algoritmo utilizado atualmente, CVC3, não é capaz de resolver restrições que estão fora do escopo de sua teoria suportada, o que acontece freqüentemente. Os algoritmos de busca são afetados com o aumento da dimensionalidade. Uma expressão com vários literais acarreta em um vasto espaço de busca, devido à representação do problema escolhida. O tamanho da população influencia diretamente na capacidade de percorrer vastos espaços de buscas, porém o tamanho da população está diretamente relacionado ao custo computacional de cada iteração. A função de fitness deve ser bem escolhida para prover o devido direcionamento ao algoritmo para que este seja capaz de encontrar o máximo global. Atualmente, a função mais apropriada para o CSP é a função SAW, proposta por Bäck et al. (1998). Esta é capaz de favorecer os indivíduos que são capazes de resolver as cláusulas mais difíceis. Isto é feito através de pesos, associados a cada cláusula, que são incrementados a cada iteração que as cláusulas não são resolvidas..

(32) C APÍTULO 3. Teste de Software. Neste capítulo será apresentado o atual estado da arte do teste de software, enfocando em testes de caixa branca, mais especificamente teste simbólico e concólico. As soluções conhecidas e utilizadas são abordadas com suas principais lacunas. Serão apresentadas as diversas técnicas de teste de software, além de métricas e critérios de adequação. A visão dos path condition como problemas de resolução de restrição Constraint Satisfaction Problem (CSP) é apresentada e como isto permitiu automatizar o teste simbólico.. 3.1 Teste de Software Com o aumento da importância dos softwares, testá-los se tornou uma tarefa essencial para a garantia da sua qualidade. Devido a sua alta complexidade e seus grandes times de desenvolvimento, o teste de software vem se tornando uma tarefa árdua. A comunidade de teste de software vem buscando novos métodos que forneçam um alto nível de garantia de qualidade. O teste não é capaz de garantir a ausência de erros, apenas é capaz de garantir a presença de erros. Esta é a causa para que se invista em, cada vez melhores, novos métodos de teste de software. Visando um aumento da qualidade do produto, os testes são executados exaustivamente até que uma quantidade mínima de defeitos seja encontrada. Na figura 3.1 é possível observar que a quantidade de defeitos encontrados é diretamente proporcional a probabilidade de existirem novos defeitos. Ao se utilizar um processo bem definido de desenvolvimento e testes, o controle de qualidade de um produto pode ser automatizado e os erros minimizados. Porém, com o aumento do esforço no controle de qualidade, o custo do produto é aumentado. A decisão da escolha de um processo de testes deve ser feito de acordo com o tipo e necessidades do produto. Um produto amador, que visa prover um serviço de baixa qualidade, não necessita de um processo de testes detalhado e com várias fases. Isto acarretaria em um aumento no custo e no tempo de. 20.

(33) 3.2 TÉCNICAS DE TESTE. 21. Figura 3.1: Quantidade de defeitos encontrados pela probabilidade de existência de novos defeitos (Myers e Sandler; 2004, cap. 2, fig. 2.2).. desenvolvimento, o que poderia fazer com que a empresa perca seu mercado.. 3.2 Técnicas de Teste Existem diversas técnicas de teste; cada uma tem um propósito específico. Para cada fase do desenvolvimento de um software, existem técnicas e métodos que tratam das suas necessidades. Estas podem ser separadas em dois grupos: 1. Teste de Caixa Preta O código-fonte e as estruturas internas não são visíveis ao engenheiro de testes. Apenas é levado em conta o comportamento do software como um todo; o software é visto como uma caixa preta que apenas vemos suas entradas e saídas, mas não podemos ver as operações e estruturas internas. É utilizado na verificação de especificação, suas entradas e saídas são comparadas à sua especificação. O conjunto de dados utilizados como entrada neste tipo de teste é criado a partir de documentos de especificação. Também é conhecido como teste funcional ou teste baseado em especificação..

(34) 3.2 TÉCNICAS DE TESTE. 22. 2. Teste de Caixa Branca As operações e estruturas internas são visíveis e são o principal foco deste tipo de teste. O conjunto de dados de entrada é criado visando testar estruturas específicas do software. Uma das métricas utilizadas é a medição da cobertura do teste. A cobertura mede o quanto do código está sendo coberto por um teste. Esta cobertura pode ser medida utilizando statements, blocos, branches, caminhos, métodos ou classes, em um desenvolvimento orientado a objeto. O termo statement se refere à menor e indivisível instrução utilizada em código fonte (Standard glossary of terms used in Software Testing; 2007). Poderia ser chamado de linha, porém, em algumas linguagens de programação, um comando pode ocupar mais de uma linha. Statement provê o significado necessário neste contexto de teste de software. O teste de caixa branca, a principio, parece ser a melhor opção para realizar testes que garantam a ausência de erros. Porém, para testes de caminhos, um teste minucioso pode ser tornar impraticável. Em um simples programa, a quantidade de caminhos possíveis pode ser extremamente grande. O teste exaustivo não é possível em grandes sistemas (Pressman; 2001). Testes de caixa branca não são impossíveis de serem criados, os principais caminhos podem ser escolhidos e exercitados através de técnicas de geração de dados de entrada, que forçam o fluxo de controle a percorrer o caminho a ser exercitado. Além da forma tradicional, este pode ser combinado ao teste de caixa preta para prover uma abordagem que verifica a interface e o funcionamento interno. Pressman (2001) questiona por que utilizar testes de caixa branca, quando poderíamos apenas verificar se os requisitos estão sendo cumpridos. Entretanto, os testes de caixa preta, por mais minuciosos que sejam, não são capazes de realizar verificações que evitam os seguintes tipos de defeitos: • Os caminhos com as menores probabilidades de serem executados, possuem as maiores chances de conter um erro. Processos mais comuns tendem a serem bem entendidos, por isso possuem menor probabilidade de conterem um erro. • Algumas conclusões sobre o fluxo do programa levam a cometer erros e estes só podem ser descobertos através de testes de caminho. • Erros de digitação podem ser detectados pelo compilador, mas alguns destes erros só podem ser encontrados através de testes..

(35) 3.3 FASES DE TESTE. 23. 3.3 Fases de Teste O desenvolvimento de um software segue uma seqüencia de fases, onde cada uma tem um objetivo e uma abordagem específica. Segundo Pressman (2001), o processo de testes é visto como um espiral como pode ser visto na figura 3.2. Na figura 3.3 podem ser observadas as fases e seus requisitos.. Figura 3.2: Processo de testes, com suas fases, utilizando uma representação de espiral (Pressman; 2001, cap. 18, fig. 18.1). 1. Teste de Unidade Foca na menor unidade do desenvolvimento de software – um componente ou módulo. Os limites do teste são determinados pelo módulo a ser testado, o teste não deve ultrapassar este limite. Utiliza a abordagem de caixa branca. Para cada teste, é desenvolvido um driver e um stub, como pode ser visto na figura 3.4. O driver é basicamente um programa que aceita dados de entrada e repassa para o componente a ser testado. O stub é um subprograma que substitui os componentes necessários para executar o teste e que não estão sendo testados. Este é constituído de uma interface simplificada, construída apenas para permitir a execução do componente, suprindo suas dependências de outros módulos. 2. Teste de Integração Na fase anterior, os módulos são testados individualmente, porém, ao serem integrados, problemas podem ocorrer na interface que os conecta. Módulos, ao serem integrados,.

(36) 3.3 FASES DE TESTE. 24. Figura 3.3: Fases do processo de teste e seus requisitos (Myers e Sandler; 2004, cap. 6, fig. 6.3)..

(37) 3.4 TESTES DE CAIXA PRETA. 25. podem gerar resultados inválidos e não produzir o comportamento esperado. O objetivo é obter os módulos testados, providos da fase anterior, e criar uma estrutura de acordo com a especificação. 3. Teste de Validação Após a correção dos erros de integração, o software passa a ser validado de acordo com as especificações do software. É realizado utilizando a abordagem de caixa preta para garantir a conformidade com os requisitos. 4. Teste de Sistema O software, ao final do desenvolvimento, deve ser testado no ambiente do cliente. Estes testes estão fora do escopo do processo de testes, pois não são realizados apenas por engenheiros de software.. Figura 3.4: Teste de unidade com seus principais componentes: caso de teste, driver e stub. (Pressman; 2001, cap. 18, fig. 18.5).. 3.4 Testes de Caixa Preta Os testes de caixa preta, ou funcionais, visam garantir a conformidade do software com seus requisitos. Os casos de teste são criados de acordo com as especificações, sem se preocupar com as estruturas ou design internos. Nem sempre podem ser automatizados, pois podem exigir.

(38) 3.4 TESTES DE CAIXA PRETA. 26. intervenção humana. A base da criação de testes funcionais é particionar os possíveis comportamentos do programa em um número finito de classes, onde espera-se que cada classe estaja funcionalmente correta. Um erro ocorre quando um programa não funciona como o esperado, ou seja, um defeito não é apenas causado por erros de programação, a não conformidade com requisitos também é caracterizada como um erro. Segundo Myers e Sandler (2004), existem os seguintes tipos de teste que se enquadram nesta abordagem: Particionamento de Equivalência. Um bom caso de teste é aquele que possui uma grande chance de encontrar um defeito. Quando um software está sendo testado através de um teste de caixa preta, este é visto como um módulo que possui entradas e defeito, conforme visto na seção 3.2. Um teste exaustivo com todas as possíveis entradas é impossível de ser realizado. Então o subconjunto de entradas que possua a maior probabilidade de encontrar defeitos deve ser encontrado. Duas propriedades devem ser consideradas neste caso: cada caso de teste deve conter o máximo possível de diferentes entradas para minimizar a quantidade de testes necessárias e o domínio dos dados de entrada devem ser particionados em um número finito de classes de equivalência. Esta segunda propriedade garante que, se um caso de teste de uma determinada classe de equivalência encontra um erro, outro caso de teste, da mesma classe, também deve encontrar o mesmo erro. Estas classes são divididas em dois grupos: dados válidos e inválidos. Em um módulo que possui como entrada apenas valores entre 1 e 999, existe uma classe de equivalência válida: 1 ≤ n ≤ 999 e existem duas classes de valores inválidos: n < 1 e 999 < n. Análise de Valores de Limite (boundary-value analysis). Exercita os limites do tipo de dados de entrada. Difere do particionamento de equivalência em duas propriedades: 1. ao invés de escolher valores qualquer dentro da classe de equivalência como representante, um ou mais valores devem ser selecionados que representam os extremos da classe. 2. ao invés de se preocupar apenas com valores de entrada, os valores de saída também são verificados. É necessário um bom conhecimento do problema para criar testes de boundary. Se o domínio dos valores de entrada de um módulo é [−1.0, +1.0], devem ser criados testes que utilizam valores como −1.0, 1.0, −1.001 e 1.001. Grafo de Causa e Efeito. Explora uma das deficiências da análise de valores de limite e o particionamento de equivalência, que é a combinação de valores de entrada. Uma situação de erro pode ocorrer após uma seqüencia de valores de entrada. Esta situação poderia não.

(39) 3.4 TESTES DE CAIXA PRETA. 27. ser detectada pelas outras técnicas. As possíveis combinações podem tender a infinito e ao se escolher um subconjunto de condições, que podem acarretar em um teste ineficaz. Utiliza uma uma notação similar a lógica Booleana de circuitos digitais para representar o grafo. Este grafo é utilizado para a escolha da seqüencia de valores de entrada. Um exemplo deste grafo pode ser observado na figura 3.5. Métodos de Estimativa de Erro (Error-guessing methods). É um processo ad hoc e intuitivo de escrita de casos de teste, onde a experiência previa do engenheiro de testes é utilizada. A idéia básica é identificar e listar os possíveis erros, ou possíveis situações de erro, e escrever casos de teste baseado nesta lista.. Figura 3.5: Exemplo de um grafo de causa e efeito (Myers e Sandler; 2004, cap. 4, fig. 4.14)..

(40) 3.5 TESTES DE CAIXA BRANCA. 28. 3.5 Testes de Caixa Branca Os testes de caixa branca, ou estruturais, verificam o funcionamento interno de um software. Estes não são capazes de garantir a ausência de defeitos, pois um defeito pode não se manifestar mesmo executando a região de código que contenha o defeito. Para que este se manifeste, pode ser necessário que o software esteja em um estado específico e apenas executar, sem criar este estado, não fará com que o defeito se manifeste. Existem diversas técnicas que seguem a abordagem de caixa branca. As técnicas de teste são complementares, ou seja, não existe uma técnica que consiga encontrar todos os defeitos. Estas devem ser utilizadas em conjunto ou em momentos diferentes, pois uma técnica não substitui a outra. Segue, abaixo, uma lista das principais técnicas de testes de caixa branca, segundo Young e Pezze (2005). • Teste de Statement É a forma mais básica e intuitiva de testar o fluxo de controle de um software. Cada statement deve ser executado pelo menos uma vez, seguindo a idéia de que um defeito é revelado quando a região de código, que contém o defeito, é executada. Como visto anteriormente, não é capaz de revelar todos os defeitos sem criar o estado específico em que manifesta o defeito. • Teste de Branch Teste de statement, mesmo com uma cobertura total, pode não cobrir todos os branches. Cada branch deve ser executado pelo menos uma vez. Os testes cobrem, pelo menos, uma ramificação do grafo de fluxo de controle do software. Em situações que uma ramificação nunca é executada – por realmente ser inalcançável – o teste não satisfaz o critério de adequação deste teste. • Teste de Condição Exercita as condições lógicas contidas em um módulo de um software. Teste de branch enxerga apenas as ramificações, enquanto que teste de condição enxerga as estruturas lógicas que compõem as condições dos branches. Por essa característica, alguns defeitos podem escapar, pois o teste de branch poderá irá exercitar apenas as ramificações, sem levar em conta que a condição pode conter um defeito. Na figura 3.7, existem dois.

(41) 3.6 CRITÉRIOS DE ADEQUAÇÃO E MÉTRICAS. 29. caminhos possíveis – if e else. Entretanto, se a condição contiver um erro como (x == 1 || y == −1), o teste de branch não irá identificar este erro. • Teste de Caminho Visa cobrir os possíveis caminhos de um software. É realizado criando-se entradas que resultem em um determinado caminho. Alguns defeitos podem se manifestar após uma seqüencia de decisões, ou seja, um caminho específico do software. Programas que contenham loops podem gerar um número infinito de caminhos, o que torna este critério difícil de ser totalmente coberto. É importante observar que um aumento na cobertura de caminhos, não necessariamente acarreta em um aumento na cobertura de statements. – Teste de Loop Variação do teste de caminho, onde o principal objetivo é testar os loops. Para que isto seja realizado, é estabelecido um critério de parada para que exista um número finito de possíveis caminhos. O teste de caminho não é capaz de verificar todos os caminhos em situações descritas na figura 3.6, pois poderá gerar infinitos possíveis caminhos. • Teste de Chamada de Procedimento/Método Visa cobrir o fluxo de controle entre procedimentos ou métodos, útil em testes de integração ou testes de sistemas. Se o teste unitário foi bem sucedido, os defeitos que restam serão de interface. Esta é a principal razão para se utilizar esta técnica na fase de integração. Nesta fase de teste, o principal foco deve ser a interface entre módulos, tornando fundamental o uso de testes de chamada de procedimento.. 3.6 Critérios de Adequação e Métricas Critérios de adequação é um conjunto de obrigações que o par [Programa, Suite de Testes] deve satisfazer. Uma suite de testes é dita que satisfaz o critério de adequação quando todas as obrigações do critério são satisfeitas por, pelo menos, um caso de teste, segundo Young e Pezze (2005)..

Referências

Documentos relacionados

Em estudos mais aprofundados, tem-se a análise dinâmica não linear geométrica de estruturas laminadas modeladas com elementos tridimensionais de barra considerando o efeito

Os sais hidratados podem ser considerados ligas de um sal inorgânico e água, formando um sólido crsitalino de fórmula geral

Assim, o método dialético visa a apreensão da totalidade social que é, em si e para si, uma totalidade concreta, modo de ser das múltiplas determinações que imbricam o

Ranque de abundância dos machos de cada uma das oito espécies de Saturniinae (143 exemplares) nos nos 13 meses (março a dezembro de 2012 e janeiro a março de 2013),

For additional support to design options the structural analysis of the Vila Fria bridge was carried out using a 3D structural numerical model using the finite element method by

The strict partition problem is relaxed into a bi-objective set covering problem with k-cliques which allows over-covered and uncovered nodes.. The information extracted

Certain it is, this was not the case with the redoubtable Brom Bones; and from the moment Ichabod Crane made his advances, the interests of the former evidently declined:

Porém, a presença de um item errático, e de efeito teto para os indivíduos com início do arco doloroso acima de 120° de elevação do braço somados ao funcionamento diferencial de