• Nenhum resultado encontrado

Extens˜ao da JaBUTi/AJ para adequa¸c˜ao ao teste estrutural de tratamento

estrutural de tratamento de exce¸c˜oes

Ap´os realizar o estudo da representa¸c˜ao do fluxo de exce¸c˜ao na ferramenta JaBUTi/AJ relatado na se¸c˜ao anterior, decidiu-se que seria importante realizar algumas altera¸c˜oes para aprimorar a ferramenta em rela¸c˜ao a este mecanismo da linguagem Java.

O primeiro ponto a ser atacado foi relativo `a identifica¸c˜ao dos n´os em que ocorre o lan¸camento expl´ıcito de exce¸c˜ao. Na vers˜ao anterior da ferramenta JaBUTi/AJ isso n˜ao era poss´ıvel na maioria dos casos, apenas observando o grafo. Ent˜ao foi alterado o identificador dos n´os throw adicionando-se ao in´ıcio do identificador os caracteres ”E.”para deixar expl´ıcito que aquele n´o lan¸ca uma exce¸c˜ao.

A segunda modifica¸c˜ao foi realizada porque, por ser uma abordagem baseada no by-

tecode, n˜ao era poss´ıvel determinar com certeza qual exce¸c˜ao seria lan¸cada por um n´o

throw. Verificou-se que ´e poss´ıvel fazer uma an´alise para identificar qual ´e o tipo de exce¸c˜ao com mais possibilidade de ser lan¸cada por um n´o. Essa an´alise foi feita e imple- mentada e os n´os passaram a conter essa informa¸c˜ao que foi denominada como ”sugest˜ao de exce¸c˜ao”(exception hint). Tamb´em foi adicionada a todos os n´os uma informa¸c˜ao so-

Figura 4.5: Exemplo 2 - c´odigo e seu grafo de integra¸c˜ao.

Figura 4.6: C´odigo do programa p5 .

bre a ordem de chamada (call order ), que informa de maneira ordenada quais unidades foram chamadas para alcan¸car o n´o analisado. Embora fosse poss´ıvel identificar essa or- dem analisando o grafo nos estudos explorat´orios conduzidos neste trabalho, mesmo os

Figura 4.7: Grafo de integra¸c˜ao do programa p5.

testadores com experiˆencia na JaBUTi/AJ tinham dificuldade de identificar com clareza essa informa¸c˜ao.

A figura 4.8 apresenta uma das informa¸c˜oes `a qual o testador tem acesso por meio da JaBUTi/AJ ao analisar o n´o E.(3).2.6 referente ao grafo 4.9. A primeira informa¸c˜ao ´e o identificador do n´o seguido pelo ponto de in´ıcio e de t´ermino das instru¸c˜oes do bytecode que o n´o representa; em seguida est˜ao as duas novas informa¸c˜oes adicionadas pelas altera¸c˜oes realizadas neste trabalho: a informa¸c˜ao de ordem de chamada e a informa¸c˜ao de ”sugest˜ao de exce¸c˜ao”e por ´ultimo encontra-se a informa¸c˜ao sobre quais n´os podem ser alcan¸cados por meio de arestas de exce¸c˜ao a partir do n´o analisado.

Figura 4.8: Inform¸c˜oes do n´o throw do n´o (3).2.6 do grafo de integra¸c˜ao do programa p5.

A terceira altera¸c˜ao envolveu a parte mais importante das mudan¸cas realizadas: alterar o algoritmo de constru¸c˜ao do grafo integrado para que a(s) aresta(s) de exce¸c˜ao integradas fossem criadas. Isso foi feito adicionando-se um passo no algoritmo que realiza essa fun¸c˜ao. O algoritmo, similarmente ao algoritmo de Cafeo e Masiero (2011), funciona conforme descrito no pr´oximo par´agrafo.

Primeiramente ´e gerado o grafo da unidade-base, de acordo com processo de Lemos et al. (2007), e em seguida s˜ao gerados todos grafos de unidades que se relacionam di- retamente com o grafo da unidade-base; em seguida s˜ao removidas da unidade-base to- das as arestas regulares que conectavam os n´os de integra¸c˜ao com os n´os seguintes da unidade-base; para cada unidade a ser integrada ´e criada uma aresta regular do n´o de integra¸c˜ao para o n´o de entrada da unidade que est´a sendo integrado. Tamb´em s˜ao cria- das arestas regulares de todos os n´os de sa´ıda do grafo integrado para os n´os seguintes ao n´o de itera¸c˜ao da unidade-base. Em seguida s˜ao identificados todos n´os throw e depois verifica-se se existem arestas de exce¸c˜ao que saem do n´o de integra¸c˜ao da unidade-base; caso existam, isso significa que existe um tratamento de exce¸c˜oes previsto no n´ıvel da unidade-base. Ent˜ao s˜ao criadas arestas de exce¸c˜ao com o mesmo destino das que saem do n´o de integra¸c˜ao, mas com a sa´ıda dos n´os throw. Este processo para verificar se existe um tratamento de exce¸c˜oes previsto ´e realizado novamente, mas em um n´ıvel abaixo do qual foi verificado anteriormente, e em seguida este processo se repete at´e que seja veri- ficado o n´ıvel 0; A partir desse ponto todo processo recome¸ca usando uma das unidades que foi integrada no papel de unidade-base at´e que n˜ao existam mais unidades a serem integradas ao grafo.

Para ilustrar a parte do procedimento que cria as arestas de exce¸c˜ao integradas con- sidere o exemplo da figura 4.7 referente ao c´odigo apresentado na figura 4.6. Para essa descri¸c˜ao considere-se que o processo de cria¸c˜ao do grafo integrado est´a no momento em que o m´etodo intMetodo2() est´a sendo integrado, com a primeira invoca¸c˜ao do m´etodo intComChancaDeLancarExce¸c~ao(), que ocorre nele; neste ponto o n´o de integra¸c˜ao ´e o n´o (2).1.21. Identifica-se como n´o throw na unidade integrada o n´o (3).1.6, verifica-se que do n´o de integra¸c˜ao sai a aresta de exce¸c˜ao ((2).1.21, (2).1.29) e ent˜ao ´e criada a aresta de exce¸c˜ao ((3).1.6, (2).1.29); neste ponto o procedimento ´e repetido para um n´ıvel abaixo ao n´ıvel anterior, que era o n´ıvel 2 e agora ´e o n´ıvel 1, em que o n´o de integra¸c˜ao ´e o n´o

(1).2.21; verifica-se que do n´o de integra¸c˜ao sai a aresta de exce¸c˜ao ((1).2.21, (1).2.29) e ent˜ao ´e criada aresta de exce¸c˜ao ((3).1.6, (1).2.29); o procedimento ´e aplicado novamente para o n´ıvel 0 em que o n´o de integra¸c˜ao ´e 14; verifica-se que do n´o de integra¸c˜ao saem as arestas de exce¸c˜ao (14, 29) e (14, 41) e ent˜ao s˜ao criadas as arestas de exce¸c˜ao ((3).1.6, 29) e ((3).1.6, 41); neste momento n˜ao existe um n´ıvel abaixo para ser aplicado o procedi- mento e ent˜ao ele ´e encerrado. Vale ressaltar que quando esse procedimento for aplicado no momento em que o m´etodo intMetodo2() est´a sendo integrado, com a segunda invo- ca¸c˜ao do m´etodo intComChancaDeLancarExce¸c~ao()o n´o de integra¸c˜ao no n´ıvel 2 ser´a o n´o (2).1.34 e o n´o throw ser´a o n´o (3).2.6. Neste caso, como n˜ao existe uma aresta de exce¸c˜ao (2).1.34 saindo deste n´o para o n´o (2).1.29, n˜ao haver´a uma aresta de exce¸c˜ao ((3).2.6, (2).1.29); isso acontece porque a segunda invoca¸c˜ao do m´etodo intComChanca- DeLancarExce¸c~ao()pelo m´etodo intMetodo2() ocorre fora do bloco try, como pode ser observado no c´odigo apresentado em 4.6.

Como resultado dessa nova vers˜ao do algoritmo, o grafo para o programa da figura 4.6 se torna o na figura 4.9. Pode-se notar que ´e mais f´acil identificar os n´os throw, pois agora s˜ao identificadas com o prefixo de exce¸c˜ao E.(3).1.6 e E.(3).2.6 e tamb´em porque esses n´os n˜ao ficam mais isolados, pois foram criadas arestas de exce¸c˜ao para todos os poss´ıveis pontos em que uma exce¸c˜ao poderia ser tratada, desde que fosse lan¸cada em um desses n´os.

O trabalho de Cafeo e Masiero (2011) definiu trˆes crit´erios de teste de integra¸c˜ao e nenhum deles com foco no fluxo de exce¸c˜ao. Os crit´erios de Lemos et al. (2007), mesmo tendo sido criados pensando no teste de unidade, possam ser aplicados no teste de in- tegra¸c˜ao se o grafo integrado fosse considerado como uma unidade, mas assim como no trabalho de Cafeo e Masiero (2011) que decidiu n˜ao utilizar esses crit´erios e sim propor novos crit´erios como foco principal na abordagem proposta este trabalho tamb´em optou por propor novos crit´erios. Neste trabalho optou-se por tomar como base os trabalhos de Cafeo e Masiero (2011); Lemos et al. (2007); Sinha e Harrold (2000) e definir novos crit´erios com foco no fluxo de exce¸c˜ao.

Antes da defini¸c˜ao dos crit´erios considere-se: T um conjunto de casos de teste para um programa P (cujo grafo integrado ´e o grafo de fluxo de controle/dados integrado gerado das unidades de P), e seja II o conjunto de caminhos exercitado por T. Ent˜ao um n´o x est´a inclu´ıdo em II se II cont´em um caminho (y1, ..., yn) tal que x = yj, para algum j, 1 ≤ j ≤ n. Similarmente, uma aresta(x1, x2) est´a inclu´ıda em II se II cont´em uma aresta tal que (x1 = yj e x2 = yj+1, para algum j, 1 ≤ j ≤ n − 1. Considere tamb´em que sempre que um n´o ou aresta ´e mencionado, ´e um n´o ou aresta integrada, ou seja, se trata de um n´o referente a uma unidade que est´a num n´ıvel j, para algum j, j ≥ 1, e no caso da aresta

Figura 4.9: Grafo de integra¸c˜ao do programa p5 gerado pelo algoritmo modificado. se trata de uma aresta que sai de um n´o integrado. Assim, os crit´erios s˜ao definidos como segue:

• todos-n´os-integrados-throw: II satisfaz o crit´erio todos-n´os-integrados-throw se todo n´o throw de um grafo integrado est´a inclu´ıdo em II. Em outras palavras, este crit´erio requer que cada n´o throw seja exercitado ao menos uma vez por algum caso de teste de T

• todas-arestas-integradas-throw: II satisfaz o crit´erio todas-arestas-integradas- throw se toda aresta (x1, x2) em que x1 ´e um n´o throw de um grafo integrado, est´a

inclu´ıda em II. Em outras palavras, este crit´erio requer que cada aresta que sai de um n´o throw seja exercitada ao menos uma vez por algum caso de teste de T • todos-n´os-integrados-dependentes-de-exce¸c˜ao: II satisfaz o crit´erio todos-n´os-

integrados-dependentes-de-exce¸c˜ao se todo n´o de entrada em um bloco catch ou fi- nally de um grafo integrado est´a inclu´ıdo em II. Em outras palavras, este crit´erio requer que cada aresta de exce¸c˜ao seja exercitada ao menos uma vez por algum caso de teste de T.

• todas-arestas-integradas-dependentes-de-exce¸c˜ao:II satisfaz o crit´erio todas- arestas-integradas-dependentes-de-exce¸c˜ao se toda aresta de exce¸c˜ao integrado est´a inclu´ıda em II. Em outras palavras, este crit´erio requer que cada n´o de entrada em um bloco catch ou finally seja exercitado ao menos uma vez por algum caso de teste de T.

• todos-n´os-integrados-de-exce¸c˜ao: II satisfaz o crit´erio todos-n´os-integrados-de- exce¸c˜ao se todo n´o throw e todo n´o de entrada em um bloco catch ou finally de um grafo integrado est´a inclu´ıdo em II. Em outras palavras, este crit´erio requer que cada n´o throw e cada n´o de entrada em um bloco catch ou finally seja exercitado ao menos uma vez por algum caso de teste de T.

A t´ıtulo de ilustra¸c˜ao considere-se o grafo 4.10 referente ao c´odigo 2.7. A partir desse grafo s˜ao derivados os requisitos de teste apresentados na tabela 4.1.

Os crit´erios propostos ser˜ao comparados com os crit´erios propostos por Sinha e Har- rold (2000). Os dois conjuntos de crit´erios tˆem quatro crit´erios semelhantes. Dois deles s˜ao para testar os n´os de lan¸camento expl´ıcito de exce¸c˜ao: todos-n´os-integrados-throw e

all-throw, e os outros dois para os n´os de tratamento de exce¸c˜oes: todos-n´os-integrados-

dependentes-de-exce¸c˜ao e all-catch. O conjunto de crit´erio proposto neste trabalho tam- b´em apresenta um crit´erio que engloba os n´os de lan¸camento e tratamento de exce¸c˜oes, o crit´erio todos-n´os-integrados-de-exce¸c˜ao. A proposta de Sinha e Harrold (2000) tam- b´em apresenta crit´erios para cobertura de triplas ativa¸c˜ao-desativa¸c˜ao, mas os crit´erios propostos nesse trabalho n˜ao usam essa tripla como requisitos e sim arestas de exce¸c˜ao. Essas s˜ao duas perspectivas diferentes de teste, mas apresentam resultados semelhantes. Na maioria dos casos exercitar uma aresta de exce¸c˜ao ´e equivalente a exercitar uma tripla ativa¸c˜ao-desativa¸c˜ao e exercitar uma tripla ativa¸c˜ao-desativa¸c˜ao tamb´em corresponde a exercitar uma aresta de exce¸c˜ao. Por´em existem casos em que n˜ao s˜ao equivalentes, pois ao exercitar uma aresta de exce¸c˜ao se exercita uma vari´avel de exce¸c˜ao v sendo lan¸cada de um n´o i e sendo tratada em um n´o j, mas em alguns casos especiais esse tratamento pode n˜ao fazer a desativa¸c˜ao da exce¸c˜ao como, por exemplo, um bloco referente a um adendo after throwing ou um bloco finaly que n˜ao fa¸cam a desativa¸c˜ao da exce¸c˜ao.

Figura 4.10: Grafo para o cod´ıgo mostrado na figura 2.7 Crit´erio Requisitos todos-n´os-integrados-throw (2).1.79; (2).1.82; (2).1.85 todas-arestas-integradas-throw ((2).1.79,(1).2.35); ((2).1.79,(1).2.7); ((2).1.79,(2).1.85); ((2).1.79,(2).1.98); ((2).1.82,(1).2.35); ((2).1.82,(1).2.7); ((2).1.82,(2).1.85); ((2).1.82,(2).1.98); ((2).1.85,(1).2.35); ((2).1.85,(1).2.7) todos-n´os-integrados-dependentes-de-exce¸c˜ao (1).2.35; (1).2.7; (2).1.85; (2).1.98 todas-arestas-integradas-dependentes-de-exce¸c˜ao ((2).1.79,(1).2.35); ((2).1.79,(1).2.7); ((2).1.79,(2).1.85); ((2).1.79,(2).1.98); ((2).1.82,(1).2.35); ((2).1.82,(1).2.7); ((2).1.82,(2).1.85); ((2).1.82,(2).1.98); ((2).1.85,(1).2.35); ((2).1.85,(1).2.7) todos-n´os-integrados-de-exce¸c˜ao (1).2.35; (1).2.7; (2).1.79; (2).1.82; (2).1.85; (2).1.98

Tabela 4.1: Requisitos de teste para os crit´erios propostos nesta disserta¸c˜ao Sinha e Harrold (2000) tamb´em apresenta crit´erios que tratam do uso de vari´aveis de exce¸c˜ao, mas neste trabalho n˜ao foi criado nenhum crit´erio desse tipo, por considerar que esses crit´erio s˜ao mais relevantes para exercitar o fluxo de dados do programa do que o fluxo de exce¸c˜ao. Outra diferen¸ca ´e que este trabalho tamb´em permite a possibilidade de

lidar com exce¸c˜oes impl´ıcitas, que n˜ao eram consideradas no trabalho de Sinha e Harrold (2000), como por exemplo o crit´erio todas-arestas-integradas-dependentes-de-exce¸c˜ao, que tem como requisito, al´em das arestas de exce¸c˜ao que saem de n´os throw, arestas de exce¸c˜ao que saem de n´os que n˜ao cont´em um lan¸camento expl´ıcito de exce¸c˜ao.

Ao comparar as tabelas 2.1 e 4.1, observa-se que os crit´erios que tˆem como requisitos um conjunto de arestas de exce¸c˜ao, tˆem um n´umero de requisitos significativamente maior do que os crit´erios que tˆem como requisitos um conjunto de triplas ativa¸c˜ao-desativa¸c˜ao. O crit´erio todas-arestas-integradas-throw, que s´o considera exce¸c˜oes expl´ıcitas, tem 10 re- quisitos de testes, enquanto um crit´erio semelhante como o crit´erio all-e-deact tem apenas 3 requisitos de teste. Se o crit´erio all-e-deact for comparado com um crit´erio que tamb´em considera exce¸c˜oes impl´ıcitas, como o crit´erio todas-arestas-integradas-dependentes-de- exce¸c˜ao, a diferen¸ca entre o n´umero de requisitos ainda fica maior. Essa diferen¸ca signifi- cativa entre requisitos de crit´erios semelhantes ocorre n˜ao por uma diferen¸ca dos crit´erios, mas sim pelo tipo de grafo integrado em que cada um deles ´e aplicado. Comparando-se as grafos 2.7 e 4.10 nota-se que no segundo grafo h´a um n´umero maior de arestas de exce¸c˜ao. A abordagem mais conservadora da JaBUTi/AJ pode ser considerada positiva, repre- sentando um maior n´umero de possibilidades para o fluxo de exce¸c˜ao. Mas essa aborda- gem tamb´em leva a um efeito colateral que seria o grande n´umero de arestas de exce¸c˜ao. Grafos integrados com representa¸c˜ao do fluxo de exce¸c˜ao j´a s˜ao complexos naturalmente. Uma representa¸c˜ao como a implementada na JaBUTi/AJ pode gerar um grafo ainda mais complexo. Outro ponto ´e que na maioria dos casos, quando existir um grande n´umero de arestas de exce¸c˜ao que saem do mesmo n´o, a maioria dessas arestas estar´a em caminhos n˜ao execut´aveis.

Conhecendo essa poss´ıvel dificuldade de interpretar o grafo integrado, nesse traba- lho foram implementadas na JaBUTi/AJ algumas op¸c˜oes de visualiza¸c˜ao com o objetivo de facilitar a atividade do testador. A figura 4.11 mostra um exemplo de visualiza¸c˜ao do grafo com a op¸c˜ao de exibir somente as arestas requeridas pelo crit´erio selecionado. Neste caso o crit´erio selecionado ´e todas-arestas-integradas-throw e as arestas de exce- ¸c˜ao referentes a exce¸c˜oes impl´ıcitas, que s˜ao as arestas ((1).2.0,(1).2.7), ((1).2.0,(1).2.35), ((2).1.72,(2).1.85) e ((2).1.72,(2).1.98), ficam invis´ıveis. Caso o crit´erio selecionado fosse todas-arestas-integradas-dependentes-de-exce¸c˜ao, todas as arestas de exce¸c˜ao ficariam vi- s´ıveis e se fosse um crit´erio que s´o tivesse requisitos do fluxo regular, como todas-arestas- integradas-independentes-de-exce¸c˜ao, todas as arestas de exce¸c˜ao ficariam invis´ıveis.

A JaBUTi/AJ permite que o testador indique quais requisitos de teste ele identificou como n˜ao execut´aveis. Foi criada uma op¸c˜ao de visualiza¸c˜ao que usa essa indica¸c˜ao de requisitos n˜ao execut´aveis. Nela, somente os requisitos que foram identificados como tal ficam ocultos no grafo. A figura 4.12 mostra um exemplo do grafo com essa op¸c˜ao

Figura 4.11: Grafo visualizado com op¸c˜ao de exibir somente as arestas requeridas pelo crit´erio todas-arestas-integradas-throw.

de visualiza¸c˜ao e pode-se notar que o n´umero de arestas mostradas ´e bem menor que do grafo original 4.10, passando de 14 para apenas 4 arestas de exce¸c˜ao. Com essa op¸c˜ao, a visualiza¸c˜ao do fluxo de exce¸c˜ao no grafo 4.12 fica bem semelhante ao grafo 2.7, tendo apenas uma aresta de exce¸c˜ao a mais, que ´e a aresta ((1).2.0,(1).2.35) referente ao lan¸camento impl´ıcito de exce¸c˜ao.

A op¸c˜ao de visualiza¸c˜ao que oculta os requisitos n˜ao execut´aveis se mostra uma op¸c˜ao interessante, pois ela permite em muitos casos uma visualiza¸c˜ao mais clara do fluxo de exce¸c˜ao no grafo, o que facilita a sua compreens˜ao. Por´em, ela depende da identifica¸c˜ao dos requisitos n˜ao execut´aveis pelo testador. A atividade de identificar os requisitos n˜ao execut´aveis pode ser complexa e trabalhosa, uma vez que a maioria das arestas de exce¸c˜ao normalmente n˜ao s˜ao execut´aveis. O caso mais comum ´e que de um n´o throw que tem como sa´ıda uma aresta de exce¸c˜ao execut´avel ´e que todas as outras arestas com sa´ıda do mesmo n´o sejam n˜ao execut´aveis. Vale ressaltar que embora esse seja o caso mais comum, ele n˜ao ´e uma regra, pois existem v´arios casos em que um n´o throw pode dar sa´ıda a duas ou mais arestas de exce¸c˜ao que sejam execut´aveis.

Para ajudar o testador, foi implementada uma op¸c˜ao que tenta identificar automa- ticamente parte das arestas de exce¸c˜ao como n˜ao execut´aveis. Essa op¸c˜ao funciona da seguinte maneira: ap´os executar um conjunto de casos de teste, verifica-se se uma ou mais arestas de exce¸c˜ao foram exercitadas; ent˜ao, no caso de uma aresta de exce¸c˜ao ter sido exercitada, todas as arestas de exce¸c˜ao com sa´ıda no mesmo n´o que n˜ao foram exercita-

das s˜ao identificadas como n˜ao execut´aveis. Vale ressaltar que a qualquer momento que um novo caso de teste for adicionado, se ele exercitar um requisito que por engano tenha sido identificado como n˜ao execut´avel, ele deixa automaticamente de ser classificado dessa forma e passar ser considerado um requisito execut´avel e coberto. Embora essa op¸c˜ao de identifica¸c˜ao de arestas de exce¸c˜oes n˜ao execut´aveis esteja sujeita a enganos, levando em considera¸c˜ao os estudos de casos realizados neste trabalho, consideramos que essa op¸c˜ao traz benef´ıcios mesmo quando ocorre algum engano por que ainda assim foi considerado mais simples identificar algum enganos que venham a ocorrer com essa op¸c˜ao do que ter de identificar manualmente todas as arestas de exce¸c˜ao n˜ao execut´aveis. De qualquer forma, trata-se de uma op¸c˜ao que pode ser usada ou n˜ao pelo testador.

Figura 4.12: Grafo visualizado com op¸c˜ao de n˜ao exibir as arestas de exce¸c˜ao n˜ao exe- cut´aveis.