Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos...

115
Teste de programas orientados a aspectos: uma abordagem estrutural para AspectJ Otávio Augusto Lazzarini Lemos

Transcript of Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos...

Page 1: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

Teste de programas orientados a aspectos:uma abordagem estrutural para AspectJ

Otávio Augusto Lazzarini Lemos

Page 2: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

SERVIÇO DE PÓS-GRADUAÇÃO DO ICMC-USP

Data de Depósito: 20 de Janeiro de 2005

Assinatura:

Teste de programas orientados a aspectos:uma abordagem estrutural para AspectJ

Otávio Augusto Lazzarini Lemos

Orientador: Prof. Dr. Paulo Cesar Masiero

Dissertação apresentada ao Instituto de Ciências Matemá-ticas e de Computação – ICMC-USP, como parte dos re-quisitos para obtenção do título de Mestre em Ciências –Ciências de Computação e Matemática Computacional.

USP - São CarlosFevereiro/2005

Page 3: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

Agradecimentos

Agradeço aos meus pais e família pelo carinho, amor e formação que me dedicaram. Aosmeus amigos: Ricardo Menotti, Mario Pazoti, Wilson Batista, Fernando Molento, Gilberto Sté-fan, Régis Frias, Valter Camargo, Fabiano Ferrari, Sandro Bianchini, Miguel Sugai, Bruno Freitas,Luis Stucchi, Adenilso Simão, Luis Sanhermelando, José Cabral, Rogério Colman, Rodrigo Pe-dra, Paula Herculano, Débora Medeiros, Luiz Ywata, Jéssica Zorzatto, André Domingues, MarcoGraciotto, André Rocha, Antonielly Rodrigues, Carolina Ferraz, Juliane Perondi, Débora Paiva,Tatiana Sugeta, Erika Höhn, Maria Istela Cagnin, Auri Vincenzi, Camila Kozlowski, Claudio Ya-mamoto, Luciana e Richard, Simone Domingues, Ubirajara Maltez Jr., Ellen Barbosa, AndreaPadovan, Daniel Cruz, Reginaldo Ré, Vanderlei Bonato, toda a galera do LABES que cheguei aconhecer; galera da PGCOMPUSP04/futebol – amigos recentes mas nem por isso menos parceiros– Zappa, Jão, Damiance, Augusto, Manzato, Jean, Eler, Marleta, Delane, Rafael, Alberto & CIA; ea todos os outros que esqueci no momento mas que são não menos importantes. Agradeço tambémao meu orientador Paulo Cesar Masiero pela dedicada atenção, e também ao professor José CarlosMaldonado pelo grande auxílio neste trabalho.

Agradeço também a todos os funcionários e professores do ICMC, e a todas as pessoas que dealguma maneira contribuíram para a realização deste trabalho.

Agradeço ao CNPq pelo auxílio financeiro.

Page 4: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

The aim of life is appreciation;there is no sense in not appreciating things;

and there is no sense in having more of them if you have less appreciation of them.(G. K. Chesterton)

Page 5: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

Resumo

EM meados dos anos 90, alguns pesquisadores constataram a existên-cia de certos interesses que, independente da técnica de programa-ção utilizada ou da maneira como o sistema venha a ser decomposto,

não se encaixam em módulos individuais, mas ficam espalhados por váriasunidades do software (também chamados de interessestransversais). A pro-gramação orientada a aspectos (POA) foi concebida como uma proposta deresolução desse problema, a partir do uso de mecanismos que permitem oisolamento dos interesses transversais. Entretanto, por ser uma técnica nova,nesses primeiros anos os pesquisadores preocuparam-se em estabelecer osconceitos e técnicas básicos das linguagens orientadas a aspectos, deixandopara uma segunda fase a investigação de outras características do desenvol-vimento de programas orientados a aspectos, como métodos de projeto eabordagens de teste. Nesta dissertação é apresentada uma abordagem deteste estrutural para programas orientados a aspectos baseados na linguagemAspectJ, que pode contribuir para o aumento da confiança no software de-senvolvido utilizando essa técnica e auxiliar o entendimento das novas cons-truções e comportamentos envolvidos nesses programas. Modelos de fluxode controle e de dados baseados no código-objeto resultante da compila-ção/combinação de programas escritos na linguagem AspectJ são propostos,bem como nove critérios de teste baseados nesses modelos. Uma ferramentadesenvolvida para apoiar o teste estrutural de unidade de programas Java foiestendida para dar apoio aos modelos e critérios propostos nesta disserta-ção. Além disso, algumas propriedades do teste de integração de programasorientados a aspectos são discutidas teoricamente.

i

Page 6: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

Abstract

I N the mid 90’s, researchers from the Software Engineering field discove-red the existence of certain concerns that can not be well modularizedusing the decompositions supported by the available programming te-

chniques (also calledcrosscuttingconcerns). The aspect-oriented program-ming (AOP) was conceived as a proposal to solve this problem, offeringmechanisms to support the modularization of crosscutting concerns. Howe-ver, being a novel technology, in the early years the researchers of AOP havefocused in establishing the underlying concepts and techniques, leaving fora future phase the investigation of other properties, such as design metho-dologies and testing approaches. This dissertation presents a structural tes-ting approach for aspect-oriented programs based on the AspectJ language,aiming at enhancing the confidence on software developed using the AOPtechnique and helping in understanding the behavior involved in such pro-grams. Control and data flow models for aspect-oriented programs based onthe bytecode resulted from the compilation of AspectJ programs are propo-sed, together with nine unit testing criteria. A prototype tool to support theapproach proposed was extended from an existing tool, and properties of theintegration testing of aspect-oriented programs are discussed theoretically.

ii

Page 7: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

Sumário

Resumo i

Abstract ii

1 Introdução 11.1 Contextualização. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Motivação. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.3 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.4 Organização. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Revisão Bibliográfica 52.1 Considerações Iniciais. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2 Programação Orientada a Aspectos. . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2.1 Linguagens de Suporte à Programação Orientada a Aspectos. . . . . . . . 82.3 Teste de Software. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14

2.3.1 Técnica Funcional. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .162.3.2 Técnica Estrutural. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .182.3.3 Teste Estrutural de Programas Orientados a Objetos. . . . . . . . . . . . . 242.3.4 Ferramentas de Teste. . . . . . . . . . . . . . . . . . . . . . . . . . . . .302.3.5 Teste de Programas Orientados a Aspectos. . . . . . . . . . . . . . . . . 33

2.4 Considerações Finais. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .40

3 Teste Estrutural de Programas Orientados a Aspectos 413.1 Considerações Iniciais. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .413.2 Fases do Teste Estrutural de Programas OA. . . . . . . . . . . . . . . . . . . . . 413.3 Teste Estrutural de Unidade. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .42

3.3.1 Grafo de Fluxo para Programas Orientados a Aspectos. . . . . . . . . . . 433.3.2 Critérios de Fluxo de Controle. . . . . . . . . . . . . . . . . . . . . . . . 503.3.3 Critérios de Fluxo de Dados. . . . . . . . . . . . . . . . . . . . . . . . . 553.3.4 Exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .583.3.5 Comparação entre os Critérios de Teste de Unidade. . . . . . . . . . . . . 59

3.4 Teste Estrutural de Integração. . . . . . . . . . . . . . . . . . . . . . . . . . . . .603.4.1 Teste Método-adendo. . . . . . . . . . . . . . . . . . . . . . . . . . . . .60

3.5 Comparação e Avaliação da Abordagem Proposta. . . . . . . . . . . . . . . . . . 643.6 Considerações Finais. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .69

iii

Page 8: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

4 Teste de Unidade: Automatização e Exemplos 704.1 Considerações Iniciais. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .704.2 Extensão da Ferramenta JaBUTi para Apoio ao Teste de Unidade de Programas OA714.3 Funcionamento da Ferramenta JaBUTi/AJ e Exemplos de Aplicação. . . . . . . . 72

4.3.1 Aplicação de Figuras 2D. . . . . . . . . . . . . . . . . . . . . . . . . . .724.3.2 Aplicação de Simulação de Telefonia. . . . . . . . . . . . . . . . . . . . 79

4.4 Exemplo de Fluxo de Dados. . . . . . . . . . . . . . . . . . . . . . . . . . . . .874.5 Considerações Finais. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .94

5 Conclusão 955.1 Considerações Finais. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .955.2 Contribuições. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .965.3 Pesquisas Futuras. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .96

Referências 102

iv

Page 9: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

Lista de Figuras

2.1 Interesse transversal de atualização da tela (adaptado do trabalho deElrad et al.(2001a)) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.2 Interesse deloggingno Tomcat (adaptado do trabalho deKersten (2002)) . . . . . 72.3 Processo de combinação. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.4 Exemplo de código em AspectJ. . . . . . . . . . . . . . . . . . . . . . . . . . . .102.5 Exemplo de definição de conjunto de junção nomeado (adaptado do livro deLad-

dad (2003)) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .112.6 Exemplos de declarações inter-tipos (adaptado do livro deLaddad (2003)) . . . . . 132.7 Sintaxe da declaraçãodeclare parents (adaptado do livro deLaddad (2003)) . 132.8 Exemplo do declare error e do declare warning (adaptado do livro deLaddad (2003)) 132.9 Exemplo dobytecodegerado para o adendo posterior que afeta o conjunto de jun-

çãomudancaEstado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .142.10 Método iterativo para o cálculo de fatorial e 3 casos de teste construídos utilizando

o JUnit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .172.11 Casos de teste para o teste dos limites das classes de equivalência construídos

utilizando o JUnit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .182.12 Grafo de fluxo de controle do método para validação de identificadores (adaptado

do trabalho deMaldonado et al. (2003)) . . . . . . . . . . . . . . . . . . . . . . . 192.13 Grafo Def-Uso do método para validação de identificadores (adaptado do trabalho

deMaldonado et al. (2003)) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .212.14 Hierarquia dos critérios deRapps e Weyuker (1982) e Potenciais-Usos (Maldo-

nado, 1991). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .232.15 Implementação parcial da classeSymbolTable . . . . . . . . . . . . . . . . . . . 272.16 Grafo de chamadas de classe para a classe de Tabela de Símbolos (adaptado do

trabalho deHarrold e Rothermel (1994)) . . . . . . . . . . . . . . . . . . . . . . . 272.17 Grafo de chamadas de classe para a classe de Tabela de Símbolos englobado por

frame(adaptado do trabalho deHarrold e Rothermel (1994)) . . . . . . . . . . . . 282.18 Grafo de fluxo de controle de classe para a classe de Tabela de Símbolos (adaptado

do trabalho deHarrold e Rothermel (1994)) . . . . . . . . . . . . . . . . . . . . . 292.19 Principais classes doframeworkJUnit (adaptado do livro deFontoura (2002)) . . . 302.20 Exemplo de caso de teste implementado utilizando o JUnit. . . . . . . . . . . . . 312.21 Tela da ferramenta JaBUTi mostrando um grafo Def-Uso de um dado método, a

partir do critério Todos-Nós-Primários.. . . . . . . . . . . . . . . . . . . . . . . . 332.22 Exemplo de motivação para o teste de programas orientados a aspectos.. . . . . . 36

v

Page 10: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

2.23 Grafo de chamadas para o c-aspectoPointShadowProtocol e para a c-classePonto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36

2.24 FCFG para o c-aspectoPointShadowProtocol e para a c-classePoint . . . . 372.25 Modelo FREE para classe de contas bancárias (Xu et al., 2004a). . . . . . . . . . . 372.26 Modelo ASM para classe de contas bancárias (Xu et al., 2004a). . . . . . . . . . . 382.27 Árvore de transição baseada no modelo ASM para classe de contas bancárias (Xu

et al., 2004a). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .382.28 AFG parcial baseado no modelo ASM para classe de contas bancárias (Xu et al.,

2004a). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .39

3.1 Algoritmo para gerar um grafoAODU a partir de um grafoIG. . . . . . . . . . . 493.2 Exemplo de um programa orientado a aspectos escrito em AspectJ.. . . . . . . . . 503.3 Parte do bytecode do métodoaffectedMethod sem a presença do aspecto

AnAspect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .513.4 Parte do bytecode do métodoaffectedMethod com a presença do aspecto

AnAspect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .513.5 AODUs do métodoaffectedMethod sem e com a presença do aspectoAn-

Aspect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .523.6 Um programa simples escrito em AspectJ e osAODUs dos métodosmethodA e

methodB da classeClassA . . . . . . . . . . . . . . . . . . . . . . . . . . . . .563.7 Hierarquia dos critérios definidos no trabalho deVincenzi (2004) e neste trabalho.. 593.8 GrafosAODU utilizados como contra-exemplos.. . . . . . . . . . . . . . . . . . 603.9 GrafoMADU do métodoaffectedMethod . . . . . . . . . . . . . . . . . . . 623.10 Caminho percorrido no grafoMADU do métodoaffectedMethod , a partir

da entrada ((0, 1), 7, 10).. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .653.11 GrafoAOCFG para um dado método.. . . . . . . . . . . . . . . . . . . . . . . . 673.12 Grafo do c-método baseado no grafo do método apresentado na Figura3.11. . . . . 68

4.1 Diagrama UML da aplicação de figuras 2D orientada a aspectos.. . . . . . . . . . 724.2 Código das classesPoint , LineSegment eMain do pacotecomponent . . . . 734.3 Código dos aspectosFigureLogging ePointBoundsChecking . . . . . . . 744.4 Janela do gerenciador de projetos da JaBUTi/AJ.. . . . . . . . . . . . . . . . . . 754.5 Telas da JaBUTi/AJ. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .764.6 Requisitos de teste do métodoLineSegment.distance gerados pelos crité-

rios Todos-NósC , Todas-ArestasC , e Todos-UsosC . . . . . . . . . . . . . . . . . . 774.7 GrafosAODU gerados pela ferramenta JaBUTi/AJ baseados nos critérios Todos-

NósC e Todas-ArestasC , após a execução do caso de teste.. . . . . . . . . . . . . 784.8 Caso de teste para cobrir os nós transversais do métodoLineSegment.distan-

ce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .784.9 Caso de teste para cobrir a aresta transversal(60, 200) do métodoLineSegment.

distance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .784.10 AODU do adendo anterior do aspectoPointBoundsChecking . . . . . . . . . 794.11 Conjunto de casos de teste Todos-Nós-adequado para o adendo anterior do aspecto

PointBoundsChecking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .804.12 Diagrama UML das classes-base da aplicação de telefonia (adaptado da página

mantida porAspectJ Team (2004)). . . . . . . . . . . . . . . . . . . . . . . . . . . 814.13 Código das classes-base da aplicação de telefonia.. . . . . . . . . . . . . . . . . . 824.14 Código dos aspectos da aplicação de telefonia.. . . . . . . . . . . . . . . . . . . . 83

vi

Page 11: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

4.15 Elementos requeridos para o critério todos-nós-transversais para a aplicação detelefonia. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .84

4.16 Código-fonte da classeCall com os elementos requeridos do critério todos-nós-transversais em destaque.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .85

4.17 GrafosAODU de construtor e método da classeCall . . . . . . . . . . . . . . . . 864.18 Classe contendo um conjunto de casos de teste para o teste da aplicação de telefonia.864.19 Código fonte da aplicação para ilustração do critério de fluxo de dados.. . . . . . 874.20 Bytecode do métodoaMethod da classeAClass . . . . . . . . . . . . . . . . . 884.21 Requisitos de teste dos critérios Todos-NósC , Todos-ArestasC e Todos-UsosC , para

o métodoaMethod da classeAClass . . . . . . . . . . . . . . . . . . . . . . . . 894.22 Código fonte da aplicação exemplo mostrado na ferramenta JaBUTi/AJ, com base

no critério Todos-NósC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .904.23 AODU do métodoaMethod da classeAClass . . . . . . . . . . . . . . . . . . . 914.24 Código fonte da aplicação exemplo mostrado na ferramenta JaBUTi/AJ, com base

no critério Todos-UsosC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .924.25 Código fonte da aplicação exemplo mostrado na ferramenta JaBUTi/AJ, após a

seleção da definição da variávels no início do método. . . . . . . . . . . . . . . . 934.26 Casos de teste para a aplicação exemplo.. . . . . . . . . . . . . . . . . . . . . . . 93

vii

Page 12: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

Lista de Tabelas

2.1 Tipos de conjuntos de junção do AspectJ e suas respectivas sintaxes (adaptado dolivro deLaddad (2003)) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11

2.2 Relação entre as fases de teste e o teste de programas OO (adaptado do trabalho dedos Santos Domingues (2001)) . . . . . . . . . . . . . . . . . . . . . . . . . . . .25

3.1 Diferentes classes de instruções de bytecode (Vincenzi, 2004). . . . . . . . . . . . 463.2 Requisitos de teste para cada critério OA definido, para o métodoaffectedMethod . 583.3 Pares Def-Uso aspectuais coletados a partir do grafoMADU do métodoaffected-

Method e conjuntos de casos de teste adequados para cada critério.. . . . . . . . 643.4 Total de casos de teste e de requisitos não-executáveis para cada critério definido,

para o métodoaffectedMethod . . . . . . . . . . . . . . . . . . . . . . . . . . 653.5 Relação entre as fases de teste no teste de programas OA na abordagem deste

trabalho e na abordagem deZhao (2003). . . . . . . . . . . . . . . . . . . . . . . 66

4.1 Arquivos criados na extensão da JaBUTi para JaBUTi/AJ.. . . . . . . . . . . . . . 71

viii

Page 13: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO

1Introdução

1.1 Contextualização

No fim da década de 60 e início da década de 70, como resultado da crise ocorrida em razão

do aumento da complexidade dos programas, emergiram alguns princípios de projeto e de progra-

mação, com o objetivo de organizar e apoiar o processo de desenvolvimento de software. Nessa

época o paradigma procedimental tornou-se dominante e, devido à utilização desses princípios de

projeto e programação, possibilitou-se o desenvolvimento de código mais legível, fácil de manter

e mais flexível. Adicionalmente, boas práticas de projeto foram estabelecidas ao longo dos anos

para o paradigma procedimental.

Com a evolução desses princípios e o avanço das técnicas de programação, foi concebida a

programação orientada a objetos (POO), que tornou possível o desenvolvimento de sistemas par-

ticionados em módulos (classes) capazes de encapsular abstrações de dados juntamente com ope-

rações sobre esses dados. Esse paradigma de programação possibilitou uma melhor separação dos

diversos interesses de um sistema, com a estruturação de projetos e códigos mais próxima da ma-

neira como os desenvolvedores naturalmente idealizam os sistemas (Elrad et al., 2001b). Além

disso, entre outros benefícios, essa técnica de programação facilitou a reutilização de código de-

senvolvido em diferentes projetos, auxiliando também a modelagem de aplicações do mundo real

(Capretz, 2003).

Apesar da POO ter revolucionado as técnicas de programação, alguns problemas não foram

completamente resolvidos por suas construções e, especificamente, essa técnica não permite a

clara separação de alguns interesses, geralmente não funcionais (também chamados de interesses

transversais). Como uma proposta de resolução desse problema, em 1997 (Kiczales et al., 1997)

1

Page 14: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 1. INTRODUÇÃO 2

surgiu a programação orientada a aspectos (POA), que oferece mecanismos para a construção de

programas em que os interesses transversais ficam isolados e separados dos interesses funcionais,

em vez de espalhados pelo sistema. A POA não tem o intuito de ser um novo paradigma de progra-

mação, mas uma técnica para ser utilizada em conjunto com as atuais linguagens de programação

(Elrad et al., 2001b), possibilitando a construção de sistemas com maior qualidade.

O teste de software sempre foi uma atividade de grande importância no processo de desen-

volvimento de software, por fornecer evidências da conformidade dos sistemas com os requisitos

especificados, aumentar o entendimento dos programas, diminuir a possibilidade da existência de

erros e, dessa forma, aumentar a confiança no software. Desde o paradigma procedimental, muitas

técnicas têm sido propostas para auxiliar a descoberta de erros nos diversos artefatos produzidos

em um projeto de software. Estudos têm confirmado cada vez mais a importância da utilização des-

sas técnicas para assegurar a qualidade do produto final e alguns pesquisadores chegam a calcular

o custo do teste – para alguns tipos de sistema – como sendo metade de todo o custo de desenvol-

vimento de software (Harrold, 2000). Além disso, a atividade de teste se torna ainda mais crítica

na medida em que programas são utilizados para realizar atividades complexas como controle de

satélites e artefatos bélicos.

As três técnicas de teste mais conhecidas são: a funcional, a estrutural e a baseada em erros.

Elas diferem pela origem da informação utilizada para gerar e avaliar os casos de teste (Adrion

et al., 1982; Zhu et al., 1997). A técnica estrutural tem sido uma das mais utilizadas e concentra-

se na cobertura de partes do código fonte a partir dos casos de teste, sendo portanto baseada em

uma implementação específica. Para a programação procedimental e orientada a objetos, foram

propostas várias abordagens de teste estrutural, utilizando-se como base tanto o fluxo de controle

quanto o fluxo de dados da aplicação (Harrold e Soffa, 1989; Harrold e Rothermel, 1994; Frankl e

Weyuker, 1988).

A POA tem sido reconhecida como uma técnica que permite a construção de sistemas com

melhor arquitetura, facilitando a manutenção dos diferentes interesses e a legibilidade do código.

Entretanto, a sua simples utilização não evita que erros sejam introduzidos ao longo do desenvol-

vimento do software, sendo necessária a utilização de técnicas de teste para aumentar a qualidade

dos programas.

1.2 Motivação

Pelo fato de ser um tema de pesquisa muito recente, os pesquisadores da área de POA preocupa-

ram-se nestes primeiros anos em estabelecer os conceitos e técnicas básicos das linguagens orien-

tadas a aspectos (Kiczales et al., 1997; Elrad et al., 2001a,b). Numa segunda fase, que ocorre

atualmente, as pesquisas se voltam para o uso da POA em situações reais, o que sugere, por exem-

plo, a necessidade de métodos de projeto, análise de requisitos e abordagens de teste específicas

para esse contexto.

Page 15: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 1. INTRODUÇÃO 3

A POA acrescenta novos construtores e conceitos aos já conhecidos das linguagens de progra-

mação e que, portanto, devem ser explorados na proposta de uma abordagem de teste estrutural

adequada, já que, de modo geral, as abordagens atuais não podem ser utilizadas diretamente .Ale-

xander (2003) enfatiza que o entendimento e teste adequado de programas orientados a aspectos é

um dos principais meios para tornar essa técnica menos custosa na prática. Outros pesquisadores

têm chamado a atenção para a dificuldade de entendimento e subseqüente teste de programas orien-

tados a aspectos, e que tal problema deve ser explorado antes que a técnica possa ser efetivamente

adotada na prática (Bodkin, 2003; Huang, 2000). Além disso, percebe-se o crescente interesse

nesse assunto, com trabalhos publicados recentemente (Xu et al., 2004b,a; Xie et al., 2004; Ale-

xander et al., 2004; Zhou et al., 2004), e também com a realização do primeiro workshop sobre

o tema – o WTAOP 2005 (Workshop on Testing Aspect Oriented Programs) – que será realizado

em conjunto com a conferência mais importante da área de programação orientada a aspectos – a

AOSD (Aspect Oriented Software Development Conference).

Com isso, e levando em conta também o fato de poucos trabalhos terem sido publicados sobre

esse tema, abre-se um nicho de pesquisa interessante e importante a ser explorado, para a adoção

efetiva da POA. Além de possibilitar o aumento da confiança nos programas orientados a aspectos,

uma proposta de teste estrutural para esses programas também auxilia o entendimento das novas

construções e do comportamento envolvidos quando se utiliza essa nova técnica de programação.

1.3 Objetivo

O objetivo deste trabalho é propor uma abordagem de teste estrutural para programas orienta-

dos a aspectos, que visa a adaptar os modelos e critérios estruturais propostos para os paradigmas

procedimental e orientado a objetos para esse novo contexto, tanto para o teste baseado no fluxo de

controle quanto para o teste baseado no fluxo de dados dos programas. Dessa forma, permitir-se-á

a utilização dos critérios estruturais no teste de programas OA, explorando-se também as peculia-

ridades dessa técnica.

A abordagem abrange o teste de unidade e também algumas características do teste de integra-

ção. Adicionalmente, é tratada a implementação da abordagem de teste de unidade de programas

OA baseados na linguagem AspectJ em uma ferramenta chamada JaBUTi/AJ, estendida a partir da

ferramenta JaBUTi, resultado do trabalho deVincenzi (2004).

1.4 Organização

No Capítulo2 é apresentada uma revisão bibliográfica sobre os temas abordados no trabalho:

a programação orientada a aspectos e linguagens orientadas a aspectos, com ênfase na linguagem

AspectJ; o teste de software, com ênfase no teste estrutural; e, por fim, o teste de programas orien-

tados a aspectos. No Capítulo3 é apresentada a abordagem de teste estrutural para programas OA

Page 16: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 1. INTRODUÇÃO 4

baseados na linguagem AspectJ proposta, tanto para o teste de unidade quanto para o teste de inte-

gração. No Capítulo4 é discutida a automação da abordagem de teste estrutural de unidade, com

o auxílio de alguns exemplos e a apresentação da ferramenta JaBUTi/AJ – extensão da ferramenta

JaBUTi (Java Bytecode Understanding and TestIng) (Vincenzi, 2004). Finalmente, no Capítulo5

são discutidas as conclusões finais, as contribuições do trabalho e os trabalhos futuros.

Page 17: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO

2Revisão Bibliográfica

2.1 Considerações Iniciais

Neste capítulo é apresentada uma revisão bibliográfica dos temas relevantes para a proposta

deste trabalho. Os principais conceitos da programação orientada a aspectos e das linguagens que

a apóiam são definidos, com ênfase na linguagem AspectJ. O teste de software também é abordado

genericamente, porém o teste estrutural é estudado com mais profundidade. Por fim, é feita uma

revisão bibliográfica dos trabalhos relacionados com o teste de programas OA.

2.2 Programação Orientada a Aspectos

Em Ciência da Computação, as técnicas de programação têm experimentado inúmeras trans-

formações, evoluindo desde construções de baixo nível – como as linguagens de montagem – até

abordagens de alto nível – como a programação orientada a objetos (POO) (Elrad et al., 2001a,b).

Ao elevarem-se os níveis de abstração, as diferentes técnicas têm permitido a idealização de pro-

jetos e programas mais próximos da maneira como os desenvolvedores naturalmente raciocinam.

Nesse contexto, é importante citar a influência significativa das pesquisas na área de Engenharia

de Software para o projeto de linguagens de programação. Essas pesquisas têm sido uma fonte

valiosa para a implementação de propriedades importantes que hoje são comuns nas técnicas de

programação1. Um exemplo é a maneira como as linguagens de vanguarda têm implementado o

1O projeto IMPACT do SIGSOFT da ACM explora de forma detalhada os relacionamentos entre esses dois campos.

5

Page 18: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 6

tratamento de exceções que, segundoRyder e Soffa (2003), é altamente influenciada pela ênfase

dada pela Engenharia de Software à confiabilidade dos sistemas.

O conceito deinteresse(concern) foi introduzido porDijkstra (1976) há quase trinta anos, e

tem sido utilizado em Engenharia de Software para se referir tanto a atributos de alto nível de um

determinado software quanto a funcionalidades de baixo nível (Elrad et al., 2001a). De maneira

geral, um interesse pode indicar tanto um requisito funcional, quanto não funcional de um sistema.

Em um projeto de software – para fins de simplicidade, legibilidade, e conseqüente facilidade

na manutenção e maior potencial para reutilização – é importante que os vários interesses relevan-

tes para um sistema estejam localizados em módulos separados. De forma geral, todas as técnicas

de programação oferecem suporte a esse tipo deseparação de interesses2 (Dijkstra, 1976), porém

cada uma à sua maneira (utilizando sub-rotinas, procedimentos, funções, classes, APIs) e em graus

diferentes.

Em meados dos anos 90, alguns pesquisadores constataram a existência de certos interesses

que, independentemente da técnica de programação utilizada ou da maneira como o sistema ve-

nha a ser decomposto, não se encaixam em módulos individuais, mas ficam espalhados por várias

unidades do software. A partir daí, dois fenômenos interessantes foram percebidos: oespalha-

mento, que acontece quando um interesse encontra-se em diversos módulos do sistema; e oema-

ranhamento, que acontece quando há a implementação de diversos interesses dentro de um único

módulo3.

Esses tipos de interesse são geralmente não funcionais, e também são chamados de interesses

transversais, pois podem ser visualizados como integrantes de uma segunda dimensão, transversal

àquela dos módulos que normalmente implementam requisitos funcionais. Exemplos de possí-

veis interesses transversais são: políticas de sincronização, mecanismos de tolerância a falhas,

funcionalidades de qualidade de serviços (QoS), controle de acesso, rastreamento da execução de

programas e persistência (Elrad et al., 2001a).

Um exemplo de interesse transversal é apresentado na Figura2.1. O diagrama de classes re-

presenta um sistema para a edição de figuras, no qual existem duas classes concretas de elementos

de figura: Ponto e Linha. Quando as coordenadas de um ponto ou os pontos de uma linha são

alterados, é necessário que a tela seja atualizada. Dessa forma, o interesse de atualização da tela

não pertence a nenhuma das duas classes, masentrecortaambas e, por isso, pode ser entendido

como transversal a essas classes.

Para se ter uma idéia do espalhamento de um interesse transversal, na Figura2.2são mostradas

as classes do Tomcat, um servidorwebbaseado em Java. As colunas representam cada classe do

sistema, enquanto que os detalhes mostram as partes relacionadas à funcionalidade delogging.

2Na verdade, como idealizado por Dijkstra, o princípio daseparação de interessestem como objetivo dividirum domínio de conhecimento em partes menores, para poder entender objetivamente cada uma delas. Portanto, aimplementação de um sistema particionado em módulos que contêm cada um dos interesses é uma conseqüência dautilização desse princípio.

3Nesse caso,módulopode se referir a um método, classe, procedimento, ou qualquer unidade de uma determinadatécnica de programação.

Page 19: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 7

*

Tela

Figura ElementoDeFigura

setY()setX()getY()getX()

AtualizaçãoDaTela

getP1()getP2()setP1()setP2()

Ponto Linha2

Figura 2.1: Interesse transversal de atualização da tela (adaptado do trabalho deElrad et al.(2001a))

Figura 2.2: Interesse deloggingno Tomcat (adaptado do trabalho deKersten (2002))

Com o intuito de resolver esse problema, foi proposta a programação orientada a aspectos (POA),

uma tecnologia de suporte para a implementação dos interesses transversais de maneira localizada.

A POA é resultado de vários estudos em metaprogramação, programação orientada a assuntos,

filtros de composição, programação adaptativa e outros. O termoaspectorefere-se aos interesses

transversais que podem ser implementados em módulos separados (Kiczales et al., 1997, 2001).

A POA oferece mecanismos para que os aspectos possam ser construídos em módulos sepa-

rados e provê meios para a definição de pontos do programa onde esses aspectos possam definir

comportamento. A partir daí, um programa executável pode ser gerado, combinando os módulos

básicos com os aspectos. Dessa forma, a POA pretende dar suporte aos interesses transversais

assim como a POO tem dado suporte aos objetos (Kiczales et al., 2001).

Desde a primeira proposta de POA (Kiczales et al., 1997), muitas pesquisas têm sido feitas

nesse tema, principalmente no que diz respeito a linguagens de suporte e a aplicações. Como essa

técnica é relativamente nova, ainda existem muitos campos pouco explorados, e alguns deles estão

começando a ser abordados. Exemplos desses assuntos são: uma teoria para a POA, abordando

essa técnica a partir de perspectivas formais (Walker et al., 2003); estudos empíricos para a ava-

Page 20: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 8

liação da efetividade da técnica (Murphy et al., 2001; Walker et al., 1999); projeto de programas

orientados a aspectos (Stein et al., 2002; Baniassad e Clarke, 2004; Clarke e Walker, 2002); e ve-

rificação, validação e teste de programas orientados a aspectos (Zhao, 2003; Störzer et al., 2003;

Alexander et al., 2004; Alexander, 2003; Zhou et al., 2004; Xu et al., 2004b,a; Xie et al., 2004).

2.2.1 Linguagens de Suporte à Programação Orientada a Aspectos

As linguagens orientadas a aspectos podem ser classificadas em: linguagens de domínio espe-

cífico e linguagens de propósito geral. As de domínio específico tratam somente de determinados

tipos de aspectos, ligados a apenas um domínio. Alguns exemplos são:

• COOL (Lopes, 1997): interesse delocking/exclusão mútua;

• RIDL (Lopes, 1997): interesse de invocação remota;

• D2AL (Becker, 1998): computação distribuída;

• QuO (Karr et al., 2001): política para o transporte em rede.

As linguagens de propósito geral oferecem mecanismos linguísticos que permitem codificar

qualquer tipo de aspecto em unidades separadas, e capturar locais onde esses aspectos afetam os

módulos básicos do programa (Kiczales et al., 2001). A partir daí, qualquer desenvolvedor pode

conceber um programa orientado a aspectos, utilizando as facilidades da linguagem. Para que os

aspectos possam interagir com os módulos básicos do programa (também chamados de compo-

nentes), em uma linguagem de propósito geral, é necessário que o programador possa determinar

em quais pontos da execução dos módulos básicos serão definidos comportamentos. Esses pontos

são chamados depontos de junção, e são definidos de acordo com determinadas regras (que de-

pendem da linguagem). Após a codificação dos componentes e dos aspectos com pontos de junção

determinados, é necessário um processo que os una em um programa executável, e esse processo

é chamado decombinação(weaving) (Kiczales et al., 2001). Esse processo pode ser realizado

tanto em tempo de compilação – também chamada de combinação estática – quanto em tempo de

execução – também chamada de combinação dinâmica – de acordo com a abordagem adotada pela

linguagem. Na Figura2.3são mostradas representações para os dois tipos de combinação.

De acordo com Karl Lieberherr (Elrad et al., 2001b), uma linguagem orientada a aspectos deve

determinar:

• Um modelo de pontos de junção que descrevam osganchosem que comportamentos possam

ser definidos;

• Um mecanismo de identificação dos pontos de junção;

• Unidades que encapsulem tanto especificações de pontos de junção quanto definições de

comportamento desejadas;

Page 21: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 9

C − Componente

A

C

A

C

Compilação eCombinação Executável

Programa

A − Aspecto

(a) Combinação estática

Execução

C

C

ExecutávelPrograma

AA

Compilação

Combinação

(b) Combinação dinâmica

Figura 2.3: Processo de combinação

• Um processo para combinar as unidades em um programa (com o combinador).

Existem inúmeras maneiras de implementar uma linguagem orientada a aspectos. Algumas

linguagens utilizam os mecanismos de empacotamento de métodos (wrapping), outras criam novas

construções para alguma linguagem existente e outras, ainda, fornecemframeworksque permitem

a criação dos aspectos.

AspectJ

A linguagem AspectJ é uma extensão de Java criada para permitir a programação orientada a

aspectos de maneira genérica, no contexto dessa linguagem. Foi desenvolvida noXerox Palo Alto

Research Centere posteriormente foi agregada ao projetoEclipseda IBM. Basicamente, as novas

construções do AspectJ consistem em: conjuntos de junção (pointcut ) que identificam conjun-

tos de pontos de junção; adendos (advice) que definem o comportamento em um dado conjunto de

junção; construções para afetar estaticamente a estrutura dos módulos básicos do programa (decla-

Page 22: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 10

rações inter-tipos e que alteram a hierarquia de classes); e os aspectos (aspect ) que encapsulam

as construções novas e as tradicionais de uma classe Java4.

Na Figura2.4 é mostrada uma implementação em AspectJ para o exemplo de interesse trans-

versal apresentado anteriormente. Essa implementação será utilizada ao longo da seção. O aspecto

AtualizacaoDaTelase encarrega de atualizar a visualização todas as vezes que alguma figura é

alterada. Como as figuras são alteradas a partir dos métodos que alteram suas coordenadas, os

adendos são definidos nas chamadas a esses métodos.

public class Ponto implements ElementoDeFigura {private int x = 0, y = 0;int getX() { return x; }int getY() { return y; }void setX( int x) { this .x = x; }void setY( int y) { this .y = y; }public void move( int dx, int dy) { x += dx; y += dy; }

}

public class Linha implements ElementoDeFigura {private Ponto p1, p2;Ponto getP1() { return p1; }Ponto getP2() { return p2; }void setP1(Ponto p1) { this .p1 = p1; }void setP2(Ponto p2) { this .p2 = p2; }public void move( int dx, int dy) { p1.move(dx,dy); p2.move(dx,dy); }

}

public aspect AtualizacaoDaTela {public pointcut mudancaEstado() :

call ( void ElementoDeFigura.move( int , int )) ||call (* Ponto. set *(*)) || call (* Linha. set *(*));

before (): mudancaEstado() {System.out.println("O estado vai mudar...");

}

after () returning : mudancaEstado() {Tela.atualiza();

}}

Figura 2.4: Exemplo de código em AspectJ

Conjuntos de Junção são utilizados para identificar pontos de junção no fluxo do programa.

A partir da especificação desses pontos, regras de combinação podem ser definidas – tal como re-

alizar uma certa ação antes ou depois da execução dos pontos de junção. Além disso, os conjuntos

de junção podem expor as informações de contexto dos pontos de junção alcançados, podendo

ser utilizadas pelas ações que afetam esses pontos. No AspectJ, os conjuntos de junção podem

conter nomes ou serem anônimos. Na Figura2.5 é mostrado um exemplo de conjunto de jun-

ção nomeado. Um conjunto de junção pode ser definido como uma combinação de conjuntos de

junção, utilizando operadores lógicos binários ‘e’ (&&) e ‘ou’ (|| – como no exemplo). Além

disso, o operador unário de negação (!) também pode ser usado quando não se quer capturar pon-

tos de junção definidos por um conjunto de junção específico. O primeiro conjunto de junção que

4A maior parte desta seção foi baseada no livro deLaddad (2003).

Page 23: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 11

compõemudancaEstado , por exemplo, captura todas as chamadas ao métodomove da classe

ElementoDeFigura , que recebe dois inteiros como parâmetros e não retorna nenhum valor.

public pointcut mudancaEstado : call( void ElementoDeFigura.move(call( *call( * *

*)

Palavra−chaveTipo do

de acessoEspecificador Nome do

conjunto de juncao

conjunto de juncao

Ponto.set (..)) || Linha.set (..));

||)int,int

Figura 2.5: Exemplo de definição de conjunto de junção nomeado (adaptado do livro deLaddad(2003))

As notações coringa ‘*’, ‘..’ e ‘+’, denotam respectivamente: qualquer número de caracteres

com exceção do ‘.’, qualquer número de caracteres incluindo o ‘.’, e qualquer subclasse ou sub-

interface de um dado tipo5.

Em Java, as classes, interfaces, métodos e atributos contêm assinaturas. No AspectJ, quando se

quer especificar padrões que designam várias assinaturas contidas em um programa, são utilizados

ospadrões de assinatura. No exemplo da Figura2.5, no segundo conjunto de junção que compõe

mudancaEstado , é utilizado um padrão de assinatura que captura as chamadas aos métodos que

iniciam com a cadeiaset , pertencem à classePonto , recebem quaisquer tipos de parâmetros e

retornam quaisquer valores.

Na tabela2.1são relacionados os tipos de conjuntos de junção implementados no AspectJ, com

as respectivas sintaxes.

Tabela 2.1:Tipos de conjuntos de junção do AspectJ e suas respectivas sintaxes (adaptado dolivro deLaddad (2003))

Tipo Sintaxe

Execução de método execution(AssinaturaDeMétodo)Chamada a método call(AssinaturaDeMétodo)

Execução de construtor execution(AssinaturaDeConstrutor)Chamada a construtor call(AssinaturaDeConstrutor)

Iniciação de classe staticinicialization(AssinaturaDeTipo)Acesso de leitura de atributo get(AssinaturaDeAtributo)

Acesso de modificação de atributo set(AssinaturaDeAtributo)Execução de tratador de exceção handler(AssinaturaDeTipo)

Iniciação de objeto initialization(AssinaturaDeConstrutor)Pré-iniciação de objeto preinitialization(AssinaturaDeConstrutor)Execução de advices adviceexecution()

5tipo no AspectJ refere-se a uma classe, interface, tipo primitivo ou aspecto.

Page 24: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 12

Adendos são construções similares a métodos e definem ações que acontecem em um dado

ponto de junção. Existem três tipos de adendos no AspectJ:

• Anteriores (before() ), que executam antes do ponto de junção;

• Posteriores (after() ), que executam depois do ponto de junção;

• De contorno (around() ), que têm a habilidade de executar em substituição ao ponto de

junção, podendo também continuar com a execução normal ou causar a execução com o

contexto alterado, por meio do método especialproceed() .

Um adendo pode ser visto como uma sobrecarga de um ponto de junção. No exemplo da

Figura2.4são mostrados dois adendos, um anterior e outro posterior, que executam antes e depois

dos pontos de junção capturados pelo conjunto de junçãomudancaEstado , respectivamente.

O primeiro apenas imprime uma mensagem avisando que o estado está para mudar e o segundo

atualiza a tela de fato, depois dos elementos de figura terem sido alterados.

As diferenças entre métodos e adendos no AspectJ são:

• adendos não têm nome;

• adendos não podem ser chamados diretamente (é trabalho do sistema executá-los nos mo-

mentos apropriados);

• adendos não têm especificadores de acesso;

• adendos têm acesso a outras variáveis especiais além dothis :

thisJoinPoint , thisJoinPointStaticPart ethisEnclosingJoinPoint-

StaticPart . Essas variáveis possuem informações reflexivas6 referentes ao ponto de jun-

ção alcançado, como valores de parâmetros, assinatura do método em execução e dados do

objeto que chamou o método. A diferença entre elas é que athisJoinPoint encapsula

informações estáticas e dinâmicas enquanto quethisJoinPointStaticPart guarda

somente informações de contexto estático. A variávelthisEnclosingJoinPoint-

StaticPart guarda informações estáticas do ponto de junção mais próximo acima do

interceptado.

Modificações estáticas permitem afetar o programa estaticamente com declarações inter-

tipos, modificações da hierarquia de classes, e introdução de avisos e erros de compilação. As

declarações inter-tipos permitem a introdução de novos atributos e métodos nas classes básicas do

programa.

Na Figura2.6é mostrado um exemplo de aspecto que utiliza os dois tipos de declarações inter-

tipos. O aspecto implementa uma regra de negócios de saldo mínimo para contas em um sistema

6Informações reflexivas referem-se ao próprio programa sendo executado, como, por exemplo, assinaturas de mé-todos e tipos de parâmetros.

Page 25: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 13

de contas. A primeira declaração inter-tipos introduz um atributo na classe de contasConta , que

representa o valor mínimo do saldo. A segunda declaração introduz um método na mesma classe

Conta para obter o saldo disponível, subtraindo o mínimo do atual. O adendo posterior executa

quando alguma instância deContaPoupanca é criada, atribuindo o saldo mínimo de 25.

public aspect RegraSaldoMinimo {private float Conta.saldominimo; \\Introduz atributo

public float Conta.obtemSaldoDisponivel() { \\Introduz metodoreturn getSaldo() - saldominimo;

}

after (Conta conta) : execution (ContaPoupanca. new(..)) &&this (conta) {

conta.saldominimo = 25;}

}

Figura 2.6: Exemplos de declarações inter-tipos (adaptado do livro deLaddad (2003))

A modificação na hierarquia das classes é feita por meio da declaração inter-tiposdeclare

parents . Essa declaração permite alterar a hierarquia e indicar que alguma classe herda de

outra classe ou implementa certas interfaces. Na Figura2.7 é mostrada a sintaxe da declaração

declare parents , para os dois casos (herança e implementação de interface).

declare parents : [PadraoDeTipo] implements [ListaDeInterfaces];declare parents : [PadraoDeTipo] extends [Classe/ListaDeInterfaces];

Figura 2.7: Sintaxe da declaraçãodeclare parents (adaptado do livro deLaddad (2003))

Com a introdução dos avisos e erros de compilação, o usuário pode implementar comporta-

mentos similares às diretivas#error e #warning de alguns pré-processadores C/C++. Além

disso podem ser construídas diretivas mais complexas e poderosas.

A declaraçãodeclare error permite ao desenvolvedor declarar um erro que interrompe

a compilação e mostra uma mensagem toda a vez que o compilador encontra um dado ponto de

junção (capturado por um conjunto de junção). A construçãodeclare warning funciona de

maneira similar, porém a compilação não pára, somente a mensagem é mostrada. Na Figura2.8são

exemplificados os dois comandos. O primeiro é utilizado para interromper a compilação toda vez

que um código de terceiro considerado perigoso é chamado, e o outro para emitir uma mensagem

de aviso quando operações bloqueantes são chamadas, aconselhando o usuário a se assegurar de

que não estão sendo feitas a partir dethreadsAWT.

Implementação dos Adendos: para ser compatível com qualquer máquina virtual Java, o

compilador do AspectJ gera, a partir do código-fonte oubytecodedos componentes e código-fonte

dos aspectos,bytecodeJava comum, obtido por meio da combinação de componentes e aspectos.

Page 26: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 14

declare error : chamadaCodigoPerigoso(): "Este codigo de terceiro tem apresentado muitos problemas.";

declare warning : chamadaOperacoesBloqueantes(): "Por favor certifique-se que estas operacoes n\~{a}o sejamchamadas a partir de uma thread AWT.";

Figura 2.8: Exemplo do declare error e do declare warning (adaptado do livro deLaddad (2003))

Para que isso seja possível, os aspectos são transformados em classes e os adendos são transforma-

dos em métodos comuns. Os parâmetros passados para esses métodos são os mesmos parâmetros

dos adendos, possivelmente acrescentados das variáveis que contêm informações reflexivas (por

exemplo, othisJoinPoint ). O corpo do método é o mesmo do adendo, com exceção do trata-

mento especial que é dado para os adendos de contorno, quando o métodoproceed() é invocado

(Hilsdale e Hugunin, 2004). Na Figura2.9é mostrado o exemplo de adendo posterior que atualiza

a tela, apresentado no início da seção, e sua respectiva transformação embytecode.

after () returning : mudancaEstado() {Tela.atualiza();

}

public void ajc$afterReturning$AtualizacaoDaTela$1af()0: invokestatic #38 <Method void Tela.atualiza()>3: return

Figura 2.9: Exemplo dobytecodegerado para o adendo posterior que afeta o conjunto de junçãomudancaEstado

A implementação da execução dos adendos é feita da seguinte maneira: primeiramente o com-

pilador identifica os possíveis pontos de junção no programa e, de maneira geral, coloca uma

chamada ao método correspondente ao adendo antes, depois ou ao invés do ponto de junção, de

acordo com o tipo do adendo, se é anterior, posterior ou de contorno. Além disso, como alguns

pontos de junção só podem ser resolvidos em tempo de execução, para estes casos são adiciona-

dos alguns resíduos nobytecodepara realizar as checagens dinâmicas necessárias. Um exemplo

de resíduo pode ser uma instrução condicionalif que checa o tipo de um determinado parâmetro,

colocada antes da chamada ao método correspondente a um adendo, quando a execução do adendo

depende do tipo do parâmetro (Hilsdale e Hugunin, 2004).

2.3 Teste de Software

Muitas propostas de técnicas e ferramentas para a verificação, validação e teste de software

têm sido apresentadas no contexto da grande área agregada sob o nome de Garantia de Qualidade

de Software (GQS). Dentre elas, o teste é uma das mais utilizadas e consiste na execução de um

Page 27: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 15

produto com a intenção de revelar erros7. Sua importância se deve ao fato das outras atividades de

GQS serem insuficientes para a descoberta dos erros introduzidos ao longo do desenvolvimento do

software (Pressman, 2002; Myers, 1979).

Em um projeto de software, os objetos submetidos ao teste podem incluir programas, especifi-

cação de requisitos e de projeto, estruturas de dados e quaisquer outros artefatos conceitualmente

executáveis utilizados na implementação da aplicação. Esses objetos representam uma função que,

por sua vez, descreve a relação entre um elemento de entrada (chamado deelemento do domínio)

e um elemento de saída. A atividade de teste, por conseguinte, verifica se uma dada função está

corretamente representada por um programa (ou qualquer outro objeto conceitualmente executável

que esteja em teste) (Adrion et al., 1982).

Para se testar o software, são necessários cinco elementos: um programa executável, a descri-

ção do comportamento esperado (obtida por meio de umoráculo), a observação da execução do

programa, a descrição do domínio funcional e um método para determinar se o comportamento

observado corresponde ao esperado (Adrion et al., 1982). Dessa forma, podem ser definidas qua-

tro etapas nessa atividade: planejamento da atividade de teste, projeto dos casos de teste, execução

dos casos de teste e avaliação dos resultados (Pressman, 2002).

Geralmente, a atividade de teste é realizada em três fases:

• Teste de unidade: Nessa fase procura-se identificar erros na lógica e na implementação de

cada módulo do software, isoladamente. No paradigma procedimental, o teste de unidade

consiste em testar um procedimento separadamente do sistema e também pode ser chamado

de teste intraprocedimental. Equivalentemente, no desenvolvimento orientado a objetos, o

teste de unidade é chamado intra-método8 e consiste no teste individual de cada método.

Para se testar as unidades de um sistema, tem-se a necessidade da implementação de uni-

dades pseudo-controladoras e pseudo-controladas (drivers e stubs). As unidades pseudo-

controladoras são responsáveis por coordenar e ativar a unidade que está sendo testada,

passando os dados de teste fornecidos pelo testador, e as pseudo-controladas, por sua vez,

consistem em implementações que substituem unidades que são chamadas pela unidade em

teste.

• Teste de integração: Nessa fase procura-se descobrir erros nas interfaces dos módulos, du-

rante a integração da estrutura do programa. No caso de um programa orientado a objetos,

por exemplo, um tipo de teste de integração consiste em testar cada método juntamente com

os métodos chamados direta ou indiretamente por ele dentro da mesma classe, e também é

chamado de teste inter-método.7Neste texto, é utilizado o termoerro como sinônimo dos termosdefeito, enganoe erro do padrão IEEE 610.12-

1990, e o termofalhapara indicar um comportamento incorreto do programa (Standards Coordinating Comittee of theComputer Society of the IEEE, 1990). De maneira geralerro se refere à causa efalhaà conseqüência.

8Neste texto, ométodoé considerado como a menor unidade de um programa orientado a objetos.

Page 28: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 16

• Teste de sistema: Nessa fase procura-se identificar erros nas funções e características de

desempenho do sistema como um todo e, para isso, geralmente é utilizada a especificação.

Um caso de teste é um par ordenado(d, S(d)) tal qued é um elemento de um determinado

domínioD (d ∈ D) e S(d) é a saída esperada para uma dada função da especificação, quando

d é utilizado como entrada. Uma verificação completa de um determinado programaP poderia

ser obtida testandoP com um conjunto de casos de testeT que inclui todos os elementos do

domínio. Entretanto, como geralmente o conjunto de elementos do domínio é infinito ou muito

grande, torna-se necessária a obtenção de subconjuntos desses casos de teste.

Para isso, podem ser utilizados critérios de teste que auxiliam o testador fornecendo: 1) um

método para a avaliação de conjuntos de casos de teste e 2) uma base para a seleção de casos de

teste. No primeiro caso os critérios de adequação servem para evidenciar a suficiência da atividade

de teste e, no segundo caso, para ajudar na construção de casos de teste (Frankl e Weyuker, 2000).

Os critérios de teste são geralmente derivados a partir de três técnicas conhecidas: funcional,

estrutural e baseada em erros, que diferem pela abordagem de teste subjacente utilizada para gerar

e avaliar os casos de teste (Zhu et al., 1997).

A técnica funcional, também chamada de teste “caixa-preta”, tem o objetivo de determinar se

o programa satisfaz aos requisitos funcionais e não-funcionais encontrados na especificação. A

técnica estrutural, por sua vez, concentra-se na cobertura de partes do código fonte a partir dos

casos de teste, sendo portanto baseada em uma implementação específica (e por esse fato é conhe-

cida também por teste “caixa-branca”). Por fim, a técnica baseada em erros utiliza informações

sobre os erros mais freqüentemente encontrados no desenvolvimento de software para derivar os

requisitos de teste. Essas técnicas são consideradas complementares, sendo que uma estratégia de

utilização se torna interessante para explorar as vantagens de cada critério. Nesse contexto, têm

sido realizados vários estudos teóricos e empíricos envolvendo a aplicação das diferentes técnicas

de teste (Zhu et al., 1997).

Apesar de ser impossível provar que um programa está absolutamente correto por meio de tes-

tes – para praticamente qualquer programa (Myers, 1979) –, a sua utilização fornece evidências da

conformidade com as funcionalidades especificadas e, dessa forma, uma atividade de teste bem re-

alizada aumenta a confiança no produto, além de auxiliar no entendimento dos artefatos testados.

Evidências da importância do teste de software são os investimentos em pesquisas não somente

acadêmicas mas também por empresas como aTelcordia Technologiese Siemens Corporate Re-

search(EUA) (Agrawal et al., 1998; Hutchins et al., 1994), e organizações como a NASA (EUA)

(Waligora e Coon, 1995).

2.3.1 Técnica Funcional

O principal objetivo da utilização da técnica funcional é encontrar discrepâncias entre o pro-

grama e sua especificação externa (Myers, 1979) e, para isso, procura-se derivar requisitos de teste

Page 29: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 17

que exercitem completamente as funções especificadas (Pressman, 2002). É chamada também de

teste caixa-preta, pelo fato de tratar o software como uma caixa com conteúdo desconhecido e do

qual só se visualiza o lado externo (dados de entrada e saída). Alguns exemplos de critérios da

técnica funcional são:

• Teste exaustivo: O critério mais óbvio para a técnica funcional é o teste exaustivo que con-

siste no uso de cada condição de entrada como um caso de teste (Adrion et al., 1982; Myers,

1979) e, conforme observado, geralmente é impraticável (considere por exemplo, o teste de

um compilador para o qual o conjunto de entradas é infinito).

• Particionamento em classes de equivalência: O critério particionamento em classes de equi-

valência consiste em particionar o conjunto de elementos do domínio em um número finito

de classes de equivalência de maneira que o teste de um elemento representativo de uma

classe seria equivalente ao teste de qualquer outro elemento da mesma classe. A idéia é que

se um caso de teste para um dado elemento de uma classe revela um erro, todos os outros

casos de teste para os outros elementos da mesma classe revelariam o mesmo erro. Equi-

valentemente, se um caso de teste não revela nenhum erro, espera-se também que nenhum

outro caso de teste na mesma classe o revelaria (Myers, 1979).

...public long factorial( int num){

if (num < 0)return -1;

long temp_fact0 = 1;long temp_fact1 = 1;boolean out_of_bounds = false ;while (num > 0 && !out_of_bounds) {

temp_fact1 = temp_fact0;temp_fact0 = temp_fact0 * num;if (temp_fact1 > temp_fact0)

out_of_bounds = true ;num--;

}if (out_of_bounds)

return -2;return temp_fact0;

}...

...public void testNegativeNumber() {

long f = fi.factorial(-34);assertEquals(-1, f);

}

public void testValidNumber() {long f = fi.factorial(10);assertEquals(3628800, f);

}

public void testOutOfBoundsNumber() {long f = fi.factorial(212);assertEquals(-2, f);

}...

Figura 2.10: Método iterativo para o cálculo de fatorial e 3 casos de teste construídos utilizandoo JUnit

Na Figura2.10é mostrado um pequeno método iterativo escrito em Java para o cálculo do

fatorial de um número (factorial ). Para esse método, poderia ser realizado um teste

funcional utilizando o critério particionamento em classes de equivalência, particionando-se

o domínio em 3 classes de equivalência: uma classe inválida correspondente aos núme-

ros negativos (x < 0), uma classe válida correspondente aos números dentro dos limites

(0 ≤ x ≤ 20) e uma classe inválida correspondente aos números cujos fatoriais excedam os

Page 30: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 18

limites de uma variável do tipolong (x > 20). Para essas 3 classes poderiam ser criados

3 casos de teste (como os criados utilizando o framework JUnit (Beck e Gamma, 2002),

e exemplificados na Figura2.10), testando um elemento representativo de cada classe de

equivalência (no exemplo foram escolhidos os elementos−34, 10 e212).

...public void testOutOfBoundsLimitNumber() {

long f = fi.factorial(21);assertEquals(-2, f);

}

public void testValidLimitNumber() {long f = fi.factorial(20);String s = "2432902008176640000";long l = Long.valueOf(s).longValue();assertEquals(l, f);

}

public void testValidLimitNumber2() {long f = fi.factorial(0);assertEquals(1, f);

}

public void testNegativeLimitNumber() {long f = fi.factorial(-1);assertEquals(-1, f);

}...

Figura 2.11: Casos de teste para o teste dos limites das classes de equivalência construídosutilizando o JUnit

• Análise de valor limite: Análise de valor limite é um critério funcional que complementa o

particionamento em classes de equivalência, exigindo que existam casos de teste para testar

os limites de cada classe de equivalência. Esse critério é interessante pois geralmente os erros

ocorrem nos limites dos domínios de entrada (Pressman, 2002). Para o exemplo apresentado

anteriormente, poder-se-ia acrescentar casos de teste para testar os elementos−1, 0, 20 e

21, testando assim os limites das classes de equivalência (como pode ser visualizado na

Figura2.11).

• Grafo causa-efeito: O critério grafo de causa-efeito explora a fraqueza dos outros critérios

funcionais que não combinam as circunstâncias de entrada, mas apenas exigem o teste de um

subconjunto delas (Myers, 1979). Para isso verifica o efeito combinado de dados de entrada,

identificando as causas (condições de entrada) e os efeitos (ações), e juntando-os em um

grafo. A partir desse grafo é montada uma tabela de decisão que é utilizada na geração dos

casos de teste (Maldonado e Fabbri, 2001).

2.3.2 Técnica Estrutural

A técnica estrutural é vista como complementar à técnica funcional e baseia-se na estrutura de

um programa para derivar seus casos de teste. Em geral, os critérios dessa técnica utilizam ografo

de fluxo de controleou grafo de programa. Esse grafo ilustra o fluxo de controle lógico de um

programa utilizando uma notação padrão (Pressman, 2002).

Considerando um programaP , constituído de vários comandos, um bloco consiste em um con-

junto de comandos no qual a execução do primeiro comando do bloco acarreta a execução de todos

os outros comandos do mesmo bloco, na seqüência determinada. Sendo assim, cada comando de

Page 31: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 19

um bloco, possivelmente com exceção do primeiro, tem um único predecessor e exatamente um

sucessor, exceto possivelmente o último comando. Um grafo de fluxo de controle consiste em uma

correspondência entre nós e blocos de um programa, que indica possíveis fluxos de controle entre

esses blocos através de arcos (Zhu et al., 1997).

No que diz respeito ao grafo de fluxo de controle, alguns conceitos são importantes para o seu

uso na técnica estrutural. Dado um grafo de programaG = (N, E, s) em queN é o conjunto de

nós,E o conjunto de arestas es o nó de entrada, umcaminhocorresponde a uma seqüência finita

de nós(n1, n2, ..., nk), parak ≥ 2, tal que existam arcos deni parani+1 parai = 1, 2, ..., k − 1.

Um caminho é ditosimplesse todos os nós que compõem esse caminho, exceto possivelmente o

primeiro e o último, forem distintos. Se todos forem distintos, incluindo o primeiro e o último, o

caminho é ditolivre de laço. Osnós de entradaenós de saídacorrespondem, respectivamente, aos

nós que não possuem nenhum antecessor e aos nós que não possuem nenhum sucessor, em outras

palavras, os nós de entrada não possuem nenhum arco de entrada e os nós de saída não possuem

nenhum arco de saída (Zhu et al., 1997). Um caminhocompletoé um caminho que vai do nó de

entrada a um nó de saída do grafo de programa.

Outro termo importante no teste estrutural é o de caminhosnão executáveis. Um caminho não

executável é um caminho do grafo de programa impossível de ser coberto para qualquer elemento

do domínio de entrada. Isso acontece quando as condições lógicas que deveriam ser satisfeitas

para que a seqüência de nós do caminho fosse executada são contraditórias (Howden, 1987).

A partir do grafo de programa, podem ser escolhidos os caminhos a serem executados, com o

apoio dos diferentes critérios da técnica estrutural. Considerando um método para a validação de

identificadores, na Figura2.12é mostrado o código e o grafo de fluxo de controle referente a ele.

Os critérios de teste estruturais são baseados na idéia de que não se pode confiar em uma

atividade de testes se existem certos caminhos que ainda não foram executados no programaP

sendo testado. Esses critérios geralmente associam um conjuntoT de casos de teste (que contém

um subconjunto das entradas do programa) com um conjuntoΠ de caminhos no grafo de fluxo

de controle deP , que são percorridos quando esses casos de teste são executados. O conjunto de

casos de testeT satisfaz o critérioC paraP (“T é C-adequado para o teste deP ”) se, e somente

se, todo caminho requerido porC é um sub-caminho de um dos caminhos deΠ (Frankl e Weyuker,

1988).

Os primeiros critérios estruturais propostos são baseados apenas no fluxo de controle da apli-

cação. Por outro lado, existem também critérios baseados na análise de fluxo de dados dos progra-

mas.

Critérios Baseados em Fluxo de Controle

Entre os critérios baseados em fluxo de controle, os mais conhecidos são:

• Todos-Nós: Este critério exige que cada comando do programa seja executado ao menos uma

vez, ou seja, que cada nó do grafo de programa seja coberto. Logicamente, a cobertura de

Page 32: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 20

public static boolean verify(String s) {/* 01 */ if (s == null || s.length() == 0)/* 02 */ return false ;/* 03 */ char achar;/* 03 */ boolean valid_id;/* 03 */ valid_id = true ;/* 03 */ achar = s.charAt(0);/* 03 */ valid_id = valid_s(achar);/* 03 */ if (s.length() == 1 && valid_id)/* 04 */ return true ;/* 05 */ int i = 1;/* 06 */ while (i < s.length()) {/* 07 */ achar = s.charAt(i);/* 07 */ if (!valid_f(achar))/* 08 */ valid_id = false ;/* 09 */ i++;/* 09 */ }/* 10 */ if (valid_id && (s.length() <= 6))/* 11 */ return true ;/* 12 */ return false ;/* 12 */ }

1

2 3

4 5

6

7 10

8

9

11 12

13

Figura 2.12: Grafo de fluxo de controle do método para validação de identificadores (adaptadodo trabalho deMaldonado et al. (2003))

cada sentença é uma necessidade no teste de qualquer tipo de programa, mas geralmente este

é um critério fraco pois na prática não revela mesmo os erros mais simples (Myers, 1979).

• Todos-Arcos: Todos-Arcos requer que cada desvio do fluxo de controle do programa seja

exercitado pelo menos uma vez, ou seja, que cada arco do grafo seja coberto. No grafo de

programa para o método de validação de identificadores apresentado na Figura2.12, é fácil

ver que, para este caso, a cobertura de todos os nós do grafo não implica na cobertura de

todos os arcos. Por exemplo, pode-se ter casos de teste que passem pelos caminhos(1, 2),

(1, 3, 4), (1, 3, 5, 6, 7, 8, 9, 6, 10, 11) e (1, 3, 5, 6, 10, 12) e que cobrem todos os nós, porém

não exercitam o arco7− 9.

• Todos-Caminhos: O critério Todos-Caminhos requer que todos os caminhos possíveis do

grafo de fluxo de controle sejam executados. Esse critério é o mais exigente do teste caixa-

branca e o número de requisitos de teste gerados para ele, mesmo em um programa simples,

pode ser astronomicamente grande (possivelmente infinito) (Myers, 1979). Na Figura2.12,

por exemplo, em decorrência do laço(6, 7, 8, 9, 6), tem-se inúmeros caminhos no grafo.

Critérios Baseados em Fluxo de Dados

Para os critérios baseados no fluxo de dados de uma aplicação é utilizado o grafo Def-Uso,

que é construído a partir do grafo de programa com informações adicionais sobre as definições e

Page 33: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 21

public static boolean verify(String s) {/* 01 */ if (s == null || s.length() == 0)/* 02 */ return false ;/* 03 */ char achar;/* 03 */ boolean valid_id;/* 03 */ valid_id = true ;/* 03 */ achar = s.charAt(0);/* 03 */ valid_id = valid_s(achar);/* 03 */ if (s.length() == 1 && valid_id)/* 04 */ return true ;/* 05 */ int i = 1;/* 06 */ while (i < s.length()) {/* 07 */ achar = s.charAt(i);/* 07 */ if (!valid_f(achar))/* 08 */ valid_id = false ;/* 09 */ i++;/* 09 */ }/* 10 */ if (valid_id && (s.length() <= 6))/* 11 */ return true ;/* 12 */ return false ;/* 12 */ }

up={s}

1

2 3

4 5

6

7 10

8

9

11 12

13

up={s}up={s}

d={achar, valid_id}

up={s,valid_id}up={s,valid_id}

d={i}

up={i,s}

d={achar}uc={achar, s}

d={i}uc={i}

d={valid_id}

up={i,s}

d ={s}

d=definiçãouc=c−usoup=p−uso

uc={achar, s}

up={s}

Figura 2.13: Grafo Def-Uso do método para validação de identificadores (adaptado do trabalhodeMaldonado et al. (2003))

subseqüentes usos das variáveis contidas em um programa. Uma definição de variável ocorre toda

vez que um valor é atribuído a uma variável. O uso de variáveis, por sua vez, pode ser de dois tipos:

uso computacional(c-uso) euso predicativo(p-uso). O primeiro refere-se a sentenças do tipo

y = f(x1, ..., xn), em que variáveis são utilizadas em uma computação. O uso predicativo acontece

em sentenças do tipoif p(x1, ..., xn), em que o valor das variáveis é utilizado como condição de

desvios (não somente em sentençasIF-THEN-ELSE mas também em laços). A partir daí, se

existe alguma sentença em um bloco contendo um c-uso ou definição de uma variável, adiciona-se

essa informação ao nó referente no grafo. Já os p-usos são associados aos arcos do grafo, posto que

o valor das variáveis afeta a seqüência de execução do programa. Umcaminho livre de definição

para uma variávelx é um caminho(n1, ..., nm), m ≥ 0, no qual não há definições dex nos nós

n2, ..., nm (Rapps e Weyuker, 1982). Outro conceito importante é o depar Def-Uso, que se refere

a um par de definição e subseqüente c-uso ou p-uso de uma variável. Na Figura2.13é mostrado o

grafo Def-Uso do método que valida identificadores.

Para que as informações de definição e uso das variáveis sejam adicionadas ao grafo Def-uso,

cada nó do grafo é associado aos conjuntosc-usoe def, e cada aresta ao conjuntop-uso. def(i) é

o conjunto de variáveis definidas no nói; c-uso(i) é o conjunto de variáveis para as quais existem

c-usos emi; e p-uso(i, j) é o conjunto de variáveis para as quais existem p-usos na aresta(i, j)

(Rapps e Weyuker, 1982). Definem-se ainda os seguintes conjuntos:

• dcu(x, i) é o conjunto de todos os nósj tais quex ∈ c-uso(j) e para os quais existe um

caminho livre de definição parax dei a j (Rapps e Weyuker, 1982).

Page 34: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 22

• dpu(x, i) é o conjunto de arestas(j, k) tais quex ∈ p-uso(j, k) e para as quais existe um

caminho livre de definição parax dei a (j, k) (Rapps e Weyuker, 1982).

SejaΠ o conjunto de caminhos completos para um grafo Def-Uso de um dado programa. Diz-

se que um nói está incluído emΠ seΠ contém um caminho(n1, . . . , nm) tal quei = nj para

algumj, 1 ≤ j ≤ m. Similarmente, uma aresta(i1, i2) é incluída emΠ seΠ contém um caminho

(n1, . . . , nm) tal quei1 = nj e i2 = nj+1 para algumj, 1 ≤ j ≤ m− 1. Um caminho(i1, . . . , ik) é

incluído emΠ seΠ contém um caminho(n1, . . . , nm) tal quei1 = nj, i2 = nj+1, . . . , ik = nj+k−1

para algumj, 1 ≤ j ≤ m− k + 1.

Para o propósito deste trabalho, dentre os critérios baseados em fluxo de dados são definidos

os seguintes:

• Todas-Definições: Um conjuntoΠ de caminhos completos executados por um conjunto de

casos de teste satisfaz o critério Todas-Definições se para cada nói do grafo Def-Uso e para

cadax ∈ def(i), Π inclui um caminho livre de definição parax de i a algum elemento de

dcu(x, i) oudpu(x, i) (Rapps e Weyuker, 1982).

• Todos-C-Usos: Um conjuntoΠ de caminhos completos executados por um conjunto de casos

de teste satisfaz o critério Todos-C-Usos se para cada nói do grafo Def-Uso e para cada

x ∈ def(i), Π inclui um caminho livre de definição parax dei a cada elemento dedcu(x, i)

(Rapps e Weyuker, 1982).

• Todos-P-Usos: Um conjuntoΠ de caminhos completos executados por um conjunto de casos

de teste satisfaz o critério Todos-P-Usos se para cada nói do grafo Def-Uso e para cada

x ∈ def(i), Π inclui um caminho livre de definição parax dei a cada elemento dedpu(x, i)

(Rapps e Weyuker, 1982).

• Todos-Usos: Um conjuntoΠ de caminhos completos executados por um conjunto de casos

de teste satisfaz o critério Todos-Usos se para cada nói do grafo Def-Uso e para cadax ∈def(i), Π inclui um caminho livre de definição parax de i a cada elemento dedcu(x, i) e a

cada elemento dedpu(x, i) (Rapps e Weyuker, 1982).

• Todos-Potenciais-Usos: Um conjuntoΠ de caminhos executados por um conjunto de casos

de teste satisfaz o critério Todos-Potenciais-Usos se para cada nói do grafo Def-Uso e para

cadax ∈ def(i), Π inclui um caminho livre de definição parax de i a cada nój do grafo

Def-Uso (pois emj pode haver um uso dex).

Comparação entre Critérios de Teste Estruturais

Apesar da dificuldade existente na comparação entre os diferentes critérios de teste, esse tipo de

estudo é muito desejável, pois permite o estabelecimento de estratégias na aplicação das diversas

técnicas de teste. Nesse tipo de teorização é sempre importante ter em mente em que sentido um

Page 35: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 23

critério pode ser consideradomelhorque outro. Os três tipos de medida encontrados na literatura

são: habilidade na detecção de erros, confiabilidade do software e custo de aplicação (Zhu et al.,

1997).

No que diz respeito à habilidade na detecção de erros, os métodos para comparação de cri-

térios de adequação podem ser classificados em três tipos: experimentação estatística, simulação

e análise formal. Em análises formais geralmente se define alguma relação entre os critérios de

adequação, provando para cada par de critérios se a relação é verdadeira ou não.

A relação deinclusãoevidencia o poder relativo entre os diferentes critérios de teste (Ntafos,

1988). Um critério C1 inclui um critérioC2 se para qualquer programaP , qualquer conjunto

de casos de testeC1-adequado for tambémC2-adequado. Um critérioC1 inclui estritamenteum

critério C2, denotado porC1 ⇒ C2, seC1 inclui C2 e existe um programaP e um conjunto de

casos de testeC2-adequado que não éC1-adequado. Além disso, seC1 não incluiC2 e C2 não

inclui C1, C1 eC2 são ditosincomparáveis.

Rapps e Weyuker (1982) mostraram que seus critérios de fluxo de dados formam uma hierar-

quia de acordo com a relação de inclusão, por essa relação estabelecer uma ordem parcial9. O

mesmo foi feito porMaldonado (1991), incluindo nessa hierarquia a família de critérios Potenci-

ais Usos. Na Figura2.14(a)é mostrada a hierarquia formada pelos critérios deRapps e Weyuker

(1982) e deMaldonado (1991).

Geralmente, algumas restrições precisam ser impostas aos programas para que se possa de-

monstrar a hierarquia de inclusão dos critérios. No caso da família de critérios deRapps e Weyuker

(1982), a análise de inclusão se aplica para programasP que satisfaçam as seguintes propriedades:

• NSUP –No-Syntactic-Undefined-P-Use Property: Para cada p-uso de uma variável x em

uma aresta(i, j), emP , existe algum caminho do nó de entrada para a aresta(i, j), o qual

contém uma definição global10 de x.

• NSL – No-Straight-Line Property: P contém ao menos um comando condicional ou de

repetição:

– Pelo menos um nó do grafo de fluxo de controle deP tem mais de um sucessor;

– Pelo menos uma variável tem um p-uso emP .

Frankl e Weyuker (1988) observaram que, na realidade, na presença de caminhos não-executá-

veis, nenhum dos critérios de fluxo de dados deRapps e Weyuker (1982) inclui o critério todas-

arestas. Já os critérios Potenciais Usos exigem menos restrições aos programas para que a análise

9Uma relação de ordem parcial é uma relação que possui as propriedades da reflexividade, antissimetria e transiti-vidade.

10Um nói possui uma definição global de uma variávelx se ocorre uma definição dex no nói e existe um caminholivre de definição dei para algum nój 6= i ou alguma aresta que contém um c-uso ou um p-uso, respectivamente, davariável x.

Page 36: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 24

Todos-Ca m in h os

Todos-Pot-D U -Ca m in h os

Todos-Pot-U sos/ D U

Todos-D U -Ca m in h os

Todos-Pot-U sos

Todos-U sos

Todos-C-U sos-A lg u m -P-U so

Todos-P-U sos-A lg u m -C-U so

Toda s-D e fs

Todos-P-U sos

Toda s-A re sta s

Todos-N os

(a) Caminhos executáveis

Todos-Ca m in h os

Todos-Pot-D U -Ca m in h os

Todos-Pot-U sos/ D U

Todos-D U -Ca m in h os

Todos-Pot-U sos

Todos-U sos

Toda s-A re sta s

Todos-C-U sos-A lg u m -P-U so

Todos-P-U sos-A lg u m -C-U so

Todos-N os

Toda s-D e fs

Todos-P-U sos

(b) Caminhos não executáveis

Figura 2.14: Hierarquia dos critérios deRapps e Weyuker (1982) e Potenciais-Usos (Maldonado,1991).

de inclusão se aplique. Na verdade, tais critérios exigem apenas que a propriedadeLDEN – at-

Least-oneDefinition-in-the-Entry-Node(ao menos uma definição de variável no nó de entrada)

– seja satisfeita. Na Figura2.14(b)é mostrada a hierarquia de inclusão dos critérios deRapps e

Weyuker (1982) e deMaldonado (1991) na presença de caminhos não-executáveis.

2.3.3 Teste Estrutural de Programas Orientados a Objetos

Basicamente, as técnicas apresentadas neste texto foram primeiramente propostas para o para-

digma procedimental mas, apesar disso, também podem ser aplicadas ao teste de programas OO.

A técnica estrutural tem sido utilizada principalmente no teste de unidade, já que os requisitos de

teste exigidos geralmente limitam-se ao escopo da unidade. Entretanto, podem ser identificados

esforços de pesquisa para a utilização dos critérios estruturais no teste de integração (Harrold e

Soffa, 1989; Harrold e Rothermel, 1994).

No teste de unidadede programas OO, o método pode ser considerado como a menor uni-

dade (também chamado de módulo) e a classe como sendo o pseudo-controlador do método (dos

Page 37: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 25

Santos Domingues, 2001). Como comentado anteriormente, o teste de unidade de programas OO

também pode ser chamado de intra-método (Harrold e Rothermel, 1994).

Em programas OO, um método pode interagir com outros métodos, chamando-os direta ou

indiretamente, dentro de uma mesma classe. O teste que envolve esse tipo de interação pode ser

considerado como um tipo deteste de integração, e é chamado inter-método (Harrold e Rothermel,

1994).

Outro tipo de interação que acontece entre métodos em classes são as chamadas a métodos

públicos feitas em seqüências arbitrárias, por usuários de uma classe. Para aumentar a confiança

de que as seqüências de chamadas interagem apropriadamente, é utilizado o teste intra-classe, que

também pode ser considerado como um tipo deteste de integração. Ainda na fase de integração,

também é definido o teste inter-classe que utiliza o mesmo conceito do teste intra-classe, porém

considera também as interações entre métodos de classes distintas (Harrold e Rothermel, 1994).

Após os testes de unidade e integração serem feitos, o sistema todo pode ser integrado, e

testes de sistemapodem ser realizados. Para esse tipo de teste geralmente utilizam-se critérios

funcionais que não apresentam diferenças fundamentais em relação ao paradigma procedimental,

quando aplicados no paradigma OO (dos Santos Domingues, 2001).

Tabela 2.2:Relação entre as fases de teste e o teste de programas OO (adaptado do trabalho dedos Santos Domingues (2001))

Menor Unidade: Método

Fase Teste de Software Orientado a ObjetosUnidade Intra-método

Integração Inter-método, Intra-classe e Inter-classeSistema Toda a aplicação

Menor Unidade: Classe

Fase Teste de Software Orientado a ObjetosUnidade Intra-método, Inter-método e Intra-classe

Integração Inter-classeSistema Toda a aplicação

Alguns autores consideram a classe como menor unidade de um programa OO, o que implica

em uma abordagem de teste diversa, em que os testes de unidade e de integração devem ser vistos

de uma perspectiva diferente. Na Tabela2.2 são sintetizados os tipos de teste OO aplicados em

cada fase, de acordo com a abordagem adotada.

Teste de Fluxo de Dados em Classes

As abordagens existentes para o teste baseado em fluxo de dados de programas procedimentais,

podem ser aplicadas para o teste de programas OO. Assim como são testados os procedimentos

Page 38: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 26

de forma isolada (teste intraprocedimental) e a interação entre eles (teste interprocedimental), a

mesma idéia pode ser aplicada aos métodos isolados de uma classe (teste intra-método), e aos

métodos de uma classe que interagem entre si (teste inter-método). Porém, no paradigma OO

devem ser consideradas também as interações de fluxo de dados que acontecem quando usuários

de uma classe invocam seqüências de métodos de maneira arbitrária (Harrold e Rothermel, 1994).

Por exemplo, em uma classeC, com atributoa e métodosm1, m2, m3, deve ser analisado se as

diferentes seqüências de chamadas (por exemplo:m2, m1, m3, m2) não provocam nenhum estado

inconsistente na classeC com relação ao atributoa.

A partir desse problema,Harrold e Rothermel (1994) propuseram o teste de fluxo de dados

de classe, que considera não somente os testes intra e inter-método, mas também o teste intra-

classe que leva em conta a interação entre métodos públicos de uma classe quando chamados em

diferentes seqüências. Esses autores consideram a classe como a menor unidade de um programa

OO e, sendo assim, consideram três níveis para o teste de unidade:

• Intra-Método, que testa os métodos individualmente (equivalente ao teste de unidade de

programas procedimentais);

• Inter-Método, que testa os métodos em conjunto com outros métodos da mesma classe (equi-

valente ao teste de integração de programas procedimentias);

• Intra-Classe, que testa a interação entre métodos públicos quando chamados em diferentes

seqüências.

Com isso, devem ser considerados três tipos de pares Def-Uso, correspondentes a cada nível

de teste. Considerando uma classeC em teste,d uma sentença definindo uma variável eu uma

sentença contendo um uso de uma variável, definem-se:

• Pares Def-Uso Intra-Método: SejaM um método deC. Sed e u estão emM e existe um

programaP que chamaM , tal que(d, u) é um par Def-Uso exercitado durante uma simples

invocação deM , então(d, u) é um par Def-Uso intra-método.

• Pares Def-Uso Inter-Método: SejaM0 um método público deC e seja{M1, M2, ...,Mn} o

conjunto de métodos chamados direta ou indiretamente quandoM0 é invocado. Suponha que

d está emMi e queu está emMj, sendo que tantoMi quantoMj estão em{M1, M2, ...,Mn}.Se existe um programaP que chamaM0 tal que, em P,(d, u) é um par Def-Uso exercitado

durante uma simples invocação deM0 por P , e Mi 6= Mj ou Mi e Mj são invocações

separadas do mesmo método, então(d, u) é um par Def-Uso inter-método.

• Pares Def-Uso Intra-Classe: SejaM0 um método público deC e seja{M1, M2, ...,Mn} o

conjunto de métodos chamados direta ou indiretamente quandoM0 é invocado. SejaN0

um método público de C e seja{N1, N2, ..., Nn} o conjunto de métodos chamados direta

Page 39: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 27

ou indiretamente quandoN0 é invocado. Suponha qued está em algum dos métodos em

{M1, M2, ...,Mn} e u em algum dos métodos em{N1, N2, ..., Nn}. Se existe um programa

P que chamaM0 eN0, tal que em P(d, u) é um par Def-Uso e que a chamada aM0 é feita

apósd ter sido executado eM0 encerra sua execução antes queu seja executado, então(d, u)

é uma par Def-Uso intra-classe.

01 // symboltable.h: definition02 #include "symbol.h"0304 class SymbolTable {05 private :06 TableEntry *table;07 int numentries, tablemax;08 int *Lookup( char *);09 public :10 SymbolTable( int n) {11 tablemax = n;12 numentries = 0;13 table = new TableEntry[tablemax]; };14 SymbolTable() { delete table; };15 int AddtoTable( char *symbol, char *syminfo);16 int GetfromTable( char *symbol, char *syminfo);17 };1819 // symboltable.c: implementation20 #include "symboltable.h"2122 int SymbolTable::Lookup( char *key, int index) {23 int saveindex;24 int Hash( char *);25 saveindex = index = Hash(key);26 while (strcmp(GetSymbol(index),key) != 0) {27 index++;28 if (index == tablemax) /* wrap around */29 index = 0;30 if (GetSymbol(index)==0 || index==saveindex)31 return NOTFOUND;32 }33 return FOUND;34 }35

36 int SymbolTable::AddtoTable( char *symbol,char *syminfo) {

37 int index;38 if (numentries < tablemax) {39 if (Lookup(symbol,index) == FOUND)40 return NOTOK;41 AddSymbol(symbol,index);42 AddInfo(syminfo,index);43 numentries++;44 return OX;45 }46 return NOTOK;47 }4849 int SymbolTable::GetfromTable( char *symbol,

char **syminfo) {50 int index;51 if (Lookup(symbol,index) == NOTFOUND)52 return NOTOK;53 *syminfo = GetInfo(index);54 return OK;55 }5669 void SymbolTable::AddInfo(syminfo,index)70 ...73 strcpy(table[index].syminfo,syminfo);75 }7677 char *SymbolTable::GetInfo(index)78 ...82 return table[index].syminfo;83 }

Figura 2.15: Implementação parcial da classeSymbolTable .

Os autores argumentam que para os testes inter e intra-método pode ser utilizado o algoritmo

de Pande, Landi e Ryder (PLR) (Pande et al., 1994), concebido para computar os pares Def-Uso

intra e interprocedimentais para a linguagem C. Porém, para a computação dos pares Def-Uso

intra-classe, o algoritmo não pode ser utilizado diretamente e, para isso, é gerado ografo de fluxo

de controle de classe(CCFG -Class Control Flow Graph), queconectatodos os métodos de uma

classe (Harrold e Rothermel, 1994). Na Figura2.15é mostrada uma implementação parcial em

C++ de uma classe de tabela de símbolos (SymbolTable) que será utilizada para exemplificar essa

abordagem de teste (Harrold e Rothermel, 1994).

Para construir o CCFG, primeiramente é necessário gerar ografo de chamadas de classe, que

representa as chamadas entre métodos e também as chamadas que podem ser feitas de fora da

classe – os nós representam cada método e as arestas representam as chamadas. Na Figura2.16

é mostrado o grafo de chamadas para a classe de tabela de símbolos, as arestas pontilhadas re-

presentam as chamadas aos métodos públicos da classe. A partir daí, para poder ser utilizado o

algoritmo PLR, é necessário englobar o grafo de chamadas com umframepara permitir que sejam

feitas as chamadas aos métodos em quaisquer seqüências para a computação dos pares Def-Uso

Page 40: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 28

SymbolTable AddtoTable GetfromTable ~SymbolTable

AddtoSymbol

Hash

GetSymbolAddInfo

Class SymbolTable

Lookup GetInfo

Figura 2.16: Grafo de chamadas de classe para a classe de Tabela de Símbolos (adaptado dotrabalho deHarrold e Rothermel (1994))

SymbolTable

frame entry

frame loop

frame exit

frame return

frame call

AddtoTable GetfromTable ~SymbolTable

AddtoSymbol

Hash

GetSymbolAddInfo

Lookup GetInfo

Figura 2.17: Grafo de chamadas de classe para a classe de Tabela de Símbolos englobado porframe(adaptado do trabalho deHarrold e Rothermel (1994))

Page 41: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 29

AddInfo

AddSymbol

~SymbolTable

GetInfo

CR

T

F

T F

frame exit

frame return

frame callframe loop

frame entry

index = hash(key);

Hash

|| index = saveindex)

T

F

TT F

F

SymbolTable

index),key)!=0)

T F

C R

GetSymbol

36. enter AddtoTable

38. if (numentries <= tablemax)

46. return NOTOK

40. return NOTOK41. AddSymbol(symbol,index)

42. AddInfo(syminfo),index

43. numentries++

44. return OK

47. exit AddtoTable

49. enter GetfromTable

52. return NOTOK 53. *syminfo=GetInfo(index)

54. return OK

55. exit GetFromTable

22: enter Lookup

25. saveindex =

26. while (strcmp(GetSymbol(

27. index++

28. if (index==TableMax)

33. return FOUND

31. return NOTFOUND

30. if (GetSymbol(index)==0

34. exit Lookup

29. index=0

Figura 2.18: Grafo de fluxo de controle de classe para a classe de Tabela de Símbolos (adaptadodo trabalho deHarrold e Rothermel (1994))

intra-classe. Oframe funciona como uma espécie de unidade pseudo-controladora da classe11 e

possui cinco nós:frame entry, frame exit, que representam a entrada e saída doframe; frame loop,

que facilita o seqüenciamento dos métodos;frame calle frame return, que representam a chamada

e o retorno a qualquer método público que possa ser invocado. Oframeainda possui quatro ares-

tas: (frame entry, frame loop), (frame loop, frame call), (frame loop, frame exit) e (frame return,

frame loop). A partir daí, cada nó que representa um método no grafo de chamadas é substituído

pelo seu grafo de fluxo de controle.

11Harrold e Rothermel (1994) definem oframecomo uma abstração de um método principal (main) P, no qualchamadas aos métodos públicos são selecionadas arbitrariamente por um comando de escolha (switch) S, ondeS éenglobado por um laçoL.

Page 42: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 30

Na Figura2.17 é mostrado o grafo de chamadas da classe de tabela de símbolos englobado

pelo frame, e na Figura2.18o CCFG parcial da classe. Na última figura apenas são expandidos

os nós correspondentes aos métodosAddtoTable , GetFromTable e Lookup com os grafos

de fluxo de controle de cada um deles, adicionando também arcos referentes às chamadas de um

método a outros da mesma classe. OsCs eRs contidos na figura correspondem às chamadas e

retornos de métodos, respectivamente.

Os três tipos de teste são úteis para o teste de classes. Por exemplo, se utilizarmos o critério

baseado em fluxo de dados Todos-Usos, então o par Def-Uso Intra-Método nas linhas 27–28 testa

se o métodoLookup volta ao começo da tabela quando chega ao final do vetor. O par Def-Uso

Inter-Método nas linhas 29–41 testa se o usuário pode inserir um símbolo na posição 0 da tabela,

enquanto que o par Def-Uso Intra-Classe nas linhas 43–38 testa se o métodoAddtoTable age

corretamente quando a tabela está cheia. Finalmente o par Def-Uso Intra-Classe nas linhas 73–82

testa se a informação adicionada à tabela anteriormente pode ser encontrada (Harrold e Rothermel,

1994). Para exercitar esse último par Def-Uso, por exemplo, poderia-se utilizar um caso de teste

que executasse o seguinte caminho do grafo da Figura2.18: (frame entry, frame loop, frame call,

36, 38, C, 22, 25, 26, 27, 28, 30, 31, 34, R, 41, 42, 43, 44, 47,frame return, frame loop, frame

call, 49, C, 22, 25, 26, 33, 34, R, 52, 55,frame return, frame loop, frame exit). A seqüência de

chamadas poderia ser: <AddtoTable ("B" , "bbbbb" ), GetFromTable ("B" , &info )>, em

queinfo é um ponteiro de caracter.

Uma outra vantagem apontada porHarrold e Rothermel (1994) em seu artigo é que os pa-

res Def-Uso Intra-Classe também auxiliam na seleção de seqüências de métodos que devem ser

testadas. Por exemplo, para exercitar o par Def-Uso Intra-Classe das linhas 73–82, é necessário

chamar a seqüência de métodos <AddtoTable , GetFromTable >, como comentado anterior-

mente. Entretanto, como não existe par Def-Uso Intra-Classe cuja definição se encontra no método

GetFromTable e uso no métodoAddtoTable , tem-se a evidência de que a execução do pri-

meiro método não afeta o segundo e, sendo assim, a seqüência não precisa ser exercitada.

Harrold e Rothermel (1994) consideram ainda o teste de fluxo de dados na integração das

classes, que corresponde a um quarto nível de teste, o inter-classe. Esse tipo de teste envolve os

pares Def-Uso em que a definiçãod de uma variável se encontra em uma classe e o usou em outra.

Para isso deve ser feita a interação entre os diversos CCFG’s de cada classe (Harrold e Rothermel,

1994).

2.3.4 Ferramentas de Teste

A atividade de teste, se realizada manualmente, geralmente é propensa a erros e limitada a

aplicações de pequeno porte (dos Santos Domingues, 2001). Nesse contexto, ferramentas de teste

podem auxiliar na automatização dessa tarefa, permitindo a aplicação prática de critérios de teste,

o teste de programas maiores, o apoio a estudos empíricos e a transferência das tecnologias de teste

para a indústria. Além disso as ferramentas de teste possibilitam a realização detestes de regres-

Page 43: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 31

são, quando manutenções são feitas no programa e os casos de teste armazenados são executados

novamente para a validação da aplicação modificada (dos Santos Domingues, 2001).

Para o teste de programas OO em C++ e Java, existem várias ferramentas e, entre elas, podem

ser citadas:C++ Test, JProbe Suite, JTest, Panorama C/C++, Panorama for Javae xSuds Tool-

suite. A maioria delas apóia o teste estrutural e algumas delas apóiam o teste funcional, além de

apresentarem algumas outras funcionalidades de análise do programa em teste (dos Santos Domin-

gues, 2001).

*

TestSuite

<<C−Component>><<interface>>

Test

+run() <<C−operation>>

+run() <<C−operation>>

<<C−Composite>>TestCase

#tearDown()#setup()+addTest() <<C−add>>+run() <<C−operation>>

...

... ...

<<fixed>>©

<<C−Composite>>

Figura 2.19: Principais classes doframeworkJUnit (adaptado do livro deFontoura (2002))

O JUnit é um pequenoframeworkde teste de regressão para programas escritos em Java que

fornece suporte à criação, execução e avaliação de casos de teste (Beck e Gamma, 2002). Apesar

de testar se, para uma dada função e elemento do domínio, a saída é correta, não avalia a cobertura

do programa segundo critérios de teste. Na Figura2.19 são mostradas as classes principais do

JUnit – TestCase e TestSuite – que são utilizadas para desenvolver casos de teste e conjuntos de

casos de teste, respectivamente (utilizando a notação UML-F (Fontoura, 2002)). Para gerar um

caso de teste, cria-se uma classe de teste derivada de TestCase e projetam-se os métodos para fazer

os testes. Na Figura2.20é mostrado um exemplo de caso de teste utilizando o JUnit, para o teste

do método de verificação de identificadores. O métodoassertEquals faz parte do JUnit e

serve para realizar asserções.

A Ferramenta JaBUTi – Teste de Fluxo de Dados OO

O Grupo de Pesquisa em Engenharia de Software do ICMC, em colaboração com outros gru-

pos de pesquisa, vem propondo algumas ferramentas para apoiar a atividade de teste. Uma delas é

a JaBUTi (Java Bytecode Understanding and Testing), que tem o intuito de ser um ambiente com-

pleto para o entendimento e teste de programas e componentes Java. A ferramenta JaBUTi fornece

diferentes critérios de teste estruturais para a análise de cobertura, um conjunto de métricas estáti-

cas para avaliar a complexidade das classes que compõem o programa/componente, e implementa

Page 44: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 32

import junit.framework.*;public class FunctionalTC extends TestCase {

boolean b;...public void testBeginsWithLetter() {

b = Identifier.verify("abcde");assertEquals( true , b);

}public void testDoesntBeginWithLetter() {

b = Identifier.verify("1abc");assertEquals( false , b);

}public void testContainsOnlyLettersDigits() {

b = Identifier.verify("a12n3");assertEquals( true , b);

}public void testDoesntContainOnlyLettersDigits() {

b = Identifier.verify("a1n3_");assertEquals( false , b);

}...

}

Figura 2.20: Exemplo de caso de teste implementado utilizando o JUnit

ainda algumas heurísticas de particionamento de programas que visam a auxiliar a localização de

erros12.

Para permitir a análise de cobertura de um programa Java, a ferramenta JaBUTi implementa

quatro critérios de teste baseados no fluxo de controle –Todos-Nós-Primários, Todos-Nós-Secun-

dários, Todos-Arcos-Primários, Todos-Arcos-Secundários– e dois critérios de teste baseados no

fluxo de dados da aplicação –Todos-Usos-Primáriose Todos-Usos-Secundários. Os pares Todos-

Nós-Primários – Todos-Nós-Secundários e Todos-Arcos-Primários – Todos-Arcos-Secundários,

compõem os critérios tradicionais Todos-Nós e Todos-Arcos. A composição do par Todos-Usos-

Primários – Todos-Usos-Secundários, resulta no critério Todos-Usos. A decisão por dividir esses

critérios foi tomada em virtude da distinção entre partes de código relacionadas com a execução

’normal´ do programa daquelas relacionadas com o tratamento de exceções. Essa distinção permite

ao testador se concentrar em perspectivas diferentes do programas, uma de cada vez, realizando

a atividade de teste de modo incremental e respeitando as restrições de tempo e custo que lhe

forem impostas (Vincenzi et al., 2003). Mais recentemente foram implementados na ferramenta

os critériosTodos-Potenciais-Usos-Primáriose Todos-Potenciais-Usos-Secundários, a partir do

critério Todos-Potenciais-Usos deMaldonado (1991).

Para realizar a análise de cobertura, as principais atividades executadas pela ferramenta são:

instrumentar arquivos .class, coletar informação de cobertura durante a execução do programa

(execution trace information), e determinar a suficiência do teste de cada um dos métodos de

acordo com os critérios de teste disponíveis.

Para facilitar a geração de casos de teste de modo a aumentar a cobertura em relação aos cri-

térios, utilizando o conceito de dominadores e super-bloco (Agrawal, 1994), a ferramenta atribui

diferentes pesos aos requisitos de teste indicando qual o requisito de teste que, se coberto, au-

12A maior parte desta seção foi retirada da tese deVincenzi (2004).

Page 45: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 33

mentaria ao máximo a cobertura em relação ao critério considerado. Para avaliar o andamento

da atividade de teste, relatórios de teste com diferentes níveis de granularidade (por projeto, por

classe, por método, por caso de teste) podem ser gerados para auxiliar o testador a decidir quando

parar os testes ou quais partes ainda não foram suficientemente testadas.

As classes que implementam a ferramenta estão agrupadas em 11 pacotes. Seis deles (criteria,

graph, lookup, metrics, project and verifier) são responsáveis pela realização da análise estática,

implementação dos critérios de teste e avaliação da cobertura. Os demais estão relacionados com a

implementação da interface gráfica e com a coleta e armazenamento das informações de execução.

O primeiro passo para se conduzir uma sessão de teste na JaBUTi é a criação de um projeto de

teste (um arquivo .jbt), o qual identifica o conjunto de classes em teste (CUTs). O módulo Lookup

é utilizado para identificar a hierarquia completa das classes que compõem a aplicação. Esse mó-

dulo recebe como entrada um determinado arquivo .class (CF), o qual corresponde à classe base

da aplicação, e produz como saída toda a hierarquia de classes (CH) necessária para se executar

a classe base, incluindo tanto classes do sistema quanto classes definidas pelo usuário. A partir

das classes definidas pelo usuário qualquer subconjunto de classes pode ser selecionado, caracte-

rizando as classes a serem testadas CUTs. CH e CUT são armazenadas em uma base de dados do

projeto. Selecionadas as CUTs, a ferramenta utiliza o módulo Graph para a construção dos grafos

Def-Uso (DUG) de cada método. A partir do DUG, os requisitos de teste (TRs) referentes aos oito

critérios estruturais implementados pela JaBUTi são derivados e armazenados na base de dados do

projeto para serem utilizados posteriormente para a análise de cobertura. O módulo Loader é o car-

regador de classes (class loader) da JaBUTi. Esse módulo instrumenta as CUTs, carrega as classes

instrumentadas para serem executadas, e armazena as informações de execução em um arquivo de

trace com extensão .trc (TF). Cada execução do carregador de classes da JaBUTi corresponde a

um novo caso de teste sendo adicionado. Observa-se que o carregador de classes sempre realiza a

instrumentação das classes no ato, acarretando um atraso na execução das classes que estão sendo

testadas. Opcionalmente, o testador pode criar um arquivo .jar contendo as classes já instrumenta-

das evitando o atraso no processo de instrumentação. O módulo Coverage utiliza as informações

produzidas pelos outros módulos, incluindo o conjunto de requisitos de teste (TR) e o arquivo de

trace (TF), para identificar o conjunto de requisitos que foram cobertos considerando a execução

dos casos de teste armazenados em TF. Ele também é responsável pela geração dos diferentes re-

latórios de teste, os quais são utilizados pelo testador para avaliar a qualidade do conjunto de teste

e decidir quando parar os testes.

Na Figura2.21é mostrada uma tela da ferramenta JaBUTi, com o grafo Def-Uso de um dado

método.

2.3.5 Teste de Programas Orientados a Aspectos

As pesquisas na área da programação orientada a aspectos têm focado basicamente as fases

de análise, projeto e codificação dos modelos de processos da Engenharia de Software. Poucos

Page 46: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 34

Figura 2.21: Tela da ferramenta JaBUTi mostrando um grafo Def-Uso de um dado método, apartir do critério Todos-Nós-Primários.

trabalhos até o momento abordam os tópicos de verificação, validação e teste de software, no

contexto da POA. Apesar disso, recentemente foram publicados alguns trabalhos sobre o tema, e

que serão discutidos nesta seção.

Teste Estrutural de Programas OA

O primeiro pesquisador a propor uma abordagem de teste estrutural para programas orientados

a aspectos foiZhao (2002, 2003). Em seus artigos, esse pesquisador apresenta uma abordagem

baseada em fluxo de dados para o teste de unidade de programas orientados a aspectos e propõe a

construção de uma ferramenta que implementa a abordagem. Zhao argumenta, a partir da imple-

mentação da linguagem AspectJ, ser impraticável o teste separado de classes e aspectos, pelo fato

de não haver referências explícitas aos aspectos nas classes afetadas, após a compilação e combina-

ção (o que não se aplica às versões mais recentes do AspectJ, no que diz respeito aobytecode). Por

conseguinte, propõe que para testar corretamente aspectos e classes, deve-se (1) testar os aspectos

juntamente com os métodos cujos comportamentos podem ser afetados pelos adendos (perspectiva

dos aspectos), e (2) testar as classes juntamente com os adendos que podem afetar o seu compor-

Page 47: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 35

tamento (perspectiva das classes). A partir daí são definidos os conceitos de aspecto combinado

e classe combinada (c-aspecto e c-classe), para indicar um aspecto juntamente com as partes das

classes que ele afeta e, inversamente, a classe com os adendos que a afetam. Conseqüentemente,

para os métodos que são afetados por adendos, são definidos os c-métodos (que compreendem os

métodos juntamente com os adendos que os afetam), e para os adendos que afetam um conjunto de

métodos, os c-adendos (que compreendem os adendos juntamente com os métodos que afetam).

As c-classes e os c-aspectos são considerados as menores unidades do programa, na proposta de

Zhao. A partir daí, baseado no trabalho deHarrold e Rothermel (1994), são definidos três níveis de

teste de unidade: intra-módulo, inter-módulo e intra-aspecto ou intra-classe. Um módulo, para esse

pesquisador, pode ser um c-adendo, c-método, c-construtor, método simples, construtor simples ou

método introduzido13.

De acordo com a abordagem baseada em fluxo de dados de Zhao, o teste intra-módulo de um

programa orientado a aspectos deve selecionar casos de teste para executar caminhos no grafo

Def-Uso que exercitem pares Def-Uso internos de um módulo (equivalente ao teste inter-método

proposto porHarrold e Rothermel (1994)). Da perspectiva inter-módulo, casos de teste são selecio-

nados para exercitar pares Def-Uso que extrapolam o módulo. O teste intra-aspecto ou intra-classe

deve exercitar os pares Def-Uso obtidos a partir de chamadas em seqüências arbitrárias aos méto-

dos públicos de um dado c-aspecto ou c-classe.

Para possibilitar a utilização dessa abordagem, é proposto um modelo estrutural baseado nas

abordagens tradicionais. Para cada um dos módulos (c-método, c-adendo, etc) é construído um

grafo de programa com as informações de definições e usos de variáveis (o que foi chamado de

grafo Def-Uso na Seção2.3.2deste capítulo). Para cada um dos c-aspectos e c-classes também é

construído umgrafo interprocedimental, que é formado por um grafo de chamadas que representa

as possíveis chamadas de cada módulo mais o grafo de programa de cada um dos módulos. Além

disso é proposta a utilização dografo de fluxo de controle com frame(FCFG –Framed Control

Flow Graph) baseado no CCFG proposto porHarrold e Rothermel (1994), porém considerando

as unidades como sendo os c-aspectos ou c-classes. A partir desse grafo pode ser feito o teste

intra-classe ou intra-aspecto proposto por Zhao.

Na abordagem de Zhao um problema que pode ser encontrado é que não se pode testar aspec-

tos e classes separadamente. No primeiro nível de teste – o intra-módulo – os adendos já estão

combinados com os componentes que afetam, sem que tenham sido testados isoladamente. Essa

falha é decorrente do fato da abordagem ser baseada em uma estratégia de implementação anterior

do AspectJ, na qual os aspectos não eram compilados em unidades separadas. Na mais recente

implementação do compilador/combinador do AspectJ, os aspectos e classes são compilados em

unidades separadas, de maneira que as classes ficam mais limpas e tem-se a possibilidade de iden-

13Note-se que Zhao utiliza o termomódulodiferentemente deste texto, pois na sua concepção unidade e módulonão se referem à mesma idéia. O que esse pesquisador chama de módulo é apenas uma parte da unidade em teste, enão a unidade em si.

Page 48: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 36

tificar os pontos onde os aspectos afetam, sem que eles fiquem inteiramente misturados com as

classes.

Na Figura2.22 é mostrado o exemplo que o pesquisador utilizou para ilustrar a abordagem

proposta. A classePoint representa pontos e possui atributosx ey referentes às coordenadas do

ponto. A classeShadow, por sua vez, representa sombras de pontos, e também possui atributosx

e y para as suas coordenadas. O aspectoPointShadowProtocol implementa a relação entre

pontos e sombras e introduz um atributoshadow na classePoint para representar a sombra

de um dado ponto. Para relacionar os objetos, o aspecto associa uma sombra a cada ponto que

é criado, por meio do adendo posterior que executa quando o construtor dePoint é chamado.

O adendo faz uso do métodoassociate para associar a sombra criada ao ponto, atribuindo-

a àshadow (o atributo introduzido). Para manter a relação consistente, sempre que um objeto

ponto se move como conseqüência da execução de um dos métodos que alteram suas coordenadas

(setX e setY ), a sua sombra é atualizada pelos adendos posteriores que executam sempre que

esses métodos são chamados. O métodogetShadow é utilizado pelos adendos posteriores para

obter a sombra do objeto ponto interceptado.

ce0 public class Point {s1 protected int x, y;

me2 public Point( int _x, int _y) {s3 x = _x;s4 y = _y;

}me5 public int getX() {

s6 return x;}

me7 public int getY() {s8 return y;

}me9 public void setX( int _x) {s10 x = _x;

}me13 public void printPosition() {

s14 System.out.println("Point at("+x+", "+y+")");}

me15 public static void main(String[] args) {s16 Point p = new Point(1,1);s17 p.setX(2);s18 p.setY(2);

}}

ce19 class Shadow {s20 public static final int offset = 10;s21 public int x, y;

me22 Shadow( int _x, int _y) {s23 x = _x;s24 y = _y;

}me25 public void printPosition() {

s26 System.out.println("Shadow at ("+x+","+y+")");}

}

ase27 aspect PointShadowProtocol {s28 private int shadowCount = 0;

me29 public static int getShadowCount() {s30 return PointShadowProtocol. aspectOf ().shadowCount;

}s31 private Shadow Point.shadow;

me32 public static void associate(Point p, Shadow s) {s33 p.shadow = s;

me34 public static Shadow getShadow(Point p) {s35 return p.shadow;

}pe36 pointcut setting( int x, int y, Point p):

args (x, y) && call (Point. new( int , int );pe37 pointcut settingX(Point p):

target (p) && call (Point.setX( int ));pe38 pointcut settingY(Point p):

target (p) && call (Point.setY( int ));

ae39 after ( int x, int y, Point p) returning :setting(x, y, p) {

s40 Shadow s = new Shadow(x + Shadow.offset,y + Shadow.offset);

s41 associate(p, s);s42 shadowCount++;

}ae43 after (Point p): settingX(p) {

s44 Shadow s = getShadow(p);s45 s.x = p.getX() + Shadow.offset;s46 p.printPosition();s47 s.printPosition();

}ae48 after (Point p): settingY(p) {

s49 Shadow s = getShadow(p);s50 s.y = p.getY() + Shadow.offset;s51 p.printPosition();s52 s.printPosition();

}}

Figura 2.22: Exemplo de motivação para o teste de programas orientados a aspectos.

A partir do código são gerados então os grafos necessários. Na Figura2.23 são mostrados

os grafos de chamadas para a c-classePoint e para o c-aspectoPointShadowProtocol .

Na Figura2.24é mostrado o FCFG para as duas unidades. Esses dois últimos são utilizados na

computação dos pares Def-Uso no teste intra-classe ou intra-aspecto.

Page 49: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 37

me32 ae43ae39me34me29 ae48

me2 me9 me11

ae43ae39

ae48

me5 me9 me11me2

me7 me13 me15

Figura 2.23: Grafo de chamadas para o c-aspectoPointShadowProtocol e para a c-classePonto .

s45

me32

framecall

ae43

s33

s44

s46

ae39

s41

me34

s35

me29

s30

s47

s50

ae48

s49

s51

s52

s40

s42

framereturn

frameexit

frameloop

frameentry

me2me9 me11

s3

s4

s10s12

s45

me5

framecall

ae43

s6

s44

s46

ae39

s41

me7

s8

s47

s50

ae48

s49

s51

s52

s40

s42

framereturn

frameexit

frameloop

frameentry

me2me9 me11

s3

s4

s10 s12

me13

s14

me15

s16

s17

s18

Figura 2.24: FCFG para o c-aspectoPointShadowProtocol e para a c-classePoint .

Teste Baseado em Estados de Programas OA

Xu et al. (2004b) e Xu et al. (2004a) propuseram uma abordagem mista de teste baseada em

estados e estrutural para programas orientados a aspectos (porém com ênfase na técnica baseada

em estados). A idéia principal é estender o modelo baseado em estados FREE (Flattened Regular

Expression) proposto porBinder (1999), para um modelo de estados aspectual (Aspectual State

Model – ASM). O modelo FREE representa os estados e comportamentos dinâmicos de objetos

e oferece diretrizes para implementação. Na Figura2.25é mostrado um modelo FREE para uma

classeAccount de contas bancárias e na Figura2.26é mostrado o modelo ASM para representar

a classe juntamente com os aspectos que interagem com ela. As transições e estados tracejados

correspondem respectivamente à execução de adendos e aos estados novos adicionados pelos as-

pectos. A execução dos adendos anteriores e posteriores iniciam em um losango preenchido perto

do início ou do final da transição, respectivamente. A execução de adendos de contorno inicia com

Page 50: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 38

um círculo preenchido no ponto de junção referente. A partir desse modelo é derivada uma árvore

de transições da qual são criados casos de teste que definem seqüências de chamadas a métodos.

Na Figura2.27é mostrada a árvore de transições baseada no modelo ASM da Figura2.26.

balance

close

settle

currentY-lastY>5

balance

freeze

unfreeze

debit

open

credit

balance

Frozen

closed

Open

inactive

Figura 2.25: Modelo FREE para classe de contas bancárias (Xu et al., 2004a).

balance

close

[currentY-lastY>5&&

b<MAX_INA_BALANCE]

proceed

[currentY-lastY>5]

[b<0]

balance

freeze

unfreeze

debit

open

credit

balance

Frozen

Closed

Open

[b<0]

Overdrawn

settle

Inactive

credit[b<0]

credit

[b>=0]

Figura 2.26: Modelo ASM para classe de contas bancárias (Xu et al., 2004a).

A segunda parte da abordagem mistura a técnica estrutural à técnica baseada em estados. A

idéia é substituir as transições e interações de aspectos por grafos de fluxo de controle referentes

aos métodos e adendos. Por exemplo, as transições realizadas a partir dos métodoscredit e debit,

do estadoOpen paraOverdrawn, são substituídas pelos grafos de fluxo de controle dos métodos

credit e debite do adendo posterior que interage com esses métodos. O modelo é chamado grafo

de fluxo de aspectos (Aspect Flow Graph– AFG). Uma parte do AFG construído a partir do ASM

representado na Figura2.26é mostrado na Figura2.28. Com esse modelo podem ser realizadas

Page 51: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 39

balance

freeze

debit

credit

[(currentY-lastY)>5]&&

B<MAX_INA_BALANCE balance

settle

balance

close

[(currentY-lastY)>5]

Open

Closed

Inactive

Inactive

Closed

Settle Inactive

Inactive

Closed

[b<0]

[b>=0]

[amt>MAX_AMT] freeze

[b<=0]

[b>0]

Open

Frozen

unfreeze

balance

Frozen

Overdrawn

Frozen unfreeze

Frozen

Open

credit

[b<=0]

[b>0]

Open

Overdrawn

Overdrawn

credit

[b<=0]

[b>0]

Open

Overdrawn Open

Open

Open

Figura 2.27: Árvore de transição baseada no modelo ASM para classe de contas bancárias (Xu etal., 2004a).

análises de cobertura a partir da execução dos casos de teste gerados com auxílio da árvore de

transição, para auxiliar na geração de novos casos de teste e para se ter idéia da suficiência da

atividade de teste.

Outros Esforços

Recentemente foram propostos também outros trabalhos relacionados com o teste de progra-

mas OA, porém explorando outras propriedades sem relações com uma técnica de teste específica.

Em alguns artigos,Alexander (2003) e Bieman ((Alexander e Bieman, 2002a; Alexander et

al., 2004)) discutem a problemática do teste de programas orientados a aspectos. É apontado, por

exemplo, que os testes feitos para os componentes podem não se aplicar aos artefatos combinados,

por causa de mudanças nas dependências de dados e controle que podem surgir a partir da combi-

nação. Pode ocorrer que um defeito em um programa OA não se localize nem nos componentes,

nem nos aspectos, mas sim em um efeito da combinação de uns com os outros.

Mais recentementeAlexander et al. (2004) propuseram um modelo de defeitos para programas

OA. O modelo explora as defeitos que podem ocorrer devido às peculiaridades de um programa

OA. O modelo de defeitos é baseado nas seguintes classes: 1) restrição incorreta em padrões

de conjuntos de junção; 2) incorreta precedência de aspectos; 3) defeito na preservação de pós-

condições impostas; 4) defeito na preservação de invariantes de estado; 5) foco incorreto no fluxo

de controle; e 6) mudanças incorretas em dependências de controle.

Page 52: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 40

c2c1

c3

c0

Open

a1

a0

Overdrawn

d1

d0

d2

Inactive

r2r1

r3

r0

Frozen

b2b1

b3

b0

f2f1

f3

f0

c2c1

c3

c0

Overdrawn Open

a2

Figura 2.28: AFG parcial baseado no modelo ASM para classe de contas bancárias (Xu et al.,2004a).

A primeira classe de defeitos explora erros que podem acontecer na definição de conjuntos de

junção, pois o desenvolvedor pode criar conjuntos de junção que são muito restritivos, ou seja,

capturam menos pontos de junção do que deviam, ou pouco restritivos. Já a segunda explora erros

que o desenvolvedor pode cometer na definição da precedência entre aspectos que afetam pontos

de junção coincidentes. A terceira e quarta classe de defeitos exploram os erros cometidos nos

aspectos que alteram dados dos componentes que afetam, ferindo pós-condições e invariantes de

estado previamente definidas. A quinta classe de defeitos explora erros cometidos em conjuntos

de junção que utilizam o designador de pontos de junção do tipocflow . Por fim, a sexta classe

de defeitos explora mudanças errôneas nas dependências de fluxo de controle que podem ser feitas

a partir do mau uso de aspectos. No próprio trabalho deAlexander et al. (2004) é citado que a

abordagem proposta não é um método completo, mas apenas um passo inicial para auxiliar no

teste de programas OA.

Xie et al. (2004) propuseram uma abordagem para seleção de casos de teste para programas

escritos em AspectJ que detecta casos de teste redundantes para programas desse tipo. Outra

abordagem para seleção de casos de teste é deZhou et al. (2004), entretanto, esse trabalho procura

propor um método prático completo para testar programas OA a partir da seleção de casos de teste

que são relevantes para aspectos. Além disso é proposto um novo critério de cobertura, baseado

no algoritmo de seleção de casos de teste relevantes para aspectos.

O algoritmo proposto porXie et al. (2004) identifica os casos de teste relevantes da seguinte

forma: analisa-se cada método para saber se algum aspecto o afeta em algum ponto; depois para

Page 53: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 2. REVISÃO BIBLIOGRÁFICA 41

cada caso de teste, analisa-se se os métodos chamados são afetados por algum aspecto, sendo que

o caso de teste é considerado relevante para o teste de sum dado aspecto se ele chama um método

que é afetado pelo aspecto.

2.4 Considerações Finais

Neste capítulo foram abordados os principais conceitos relacionados com a programação ori-

entada a aspectos e teste de software. Um fato importante a ser notado é a pequena quantidade de

trabalhos publicados relacionados com o teste de programas OA. Apesar disso, nota-se um cres-

cente interesse por esse tema, já que a maioria das publicações referenciadas são do ano de 2004.

Especificamente sobre teste estrutural de programas OA, até o momento, podem ser destacados

apenas os trabalhos deZhao (2003) e deXu et al. (2004a). Nota-se também que nenhuma das

abordagens explora a fundo as características da POA no que diz respeito aos critérios de fluxo de

controle e de dados, além da falta de implementações ou mesmo subsídios para implementações

de critérios de teste para programas OA. Além do mais, ainda não foram propostos critérios de

teste especificamente orientados a aspectos.

Com isso, abre-se um nicho interessante para ser explorado: o teste estrutural de programas

OA, focando as peculiaridades de programas desse tipo e critérios que explorem esses pontos. No

próximo capítulo é proposta uma abordagem de teste estrutural para programas OA.

Page 54: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO

3Teste Estrutural de Programas

Orientados a Aspectos

3.1 Considerações Iniciais

Considerando a pequena quantidade de trabalhos publicados sobre o tema e o crescente inte-

resse pelo assunto, este capítulo apresenta uma abordagem de teste estrutural para programas OA,

adaptando o modelo de fluxo de controle e de dados e os critérios estruturais. É apresentada uma

análise de inclusão dos critérios estruturais de unidade e também uma comparação da abordagem

com outras propostas.

Na Seção3.2as fases do teste estrutural de programas OA são definidas. Na Seção3.3é apre-

sentada a abordagem de teste de unidade e na Seção3.4 é apresentada a abordagem de teste de

integração, focando na fase de teste Método-adendo. Na Seção3.5é feita uma avaliação da abor-

dagem, comparando com os outros trabalhos relacionados e, por fim, na Seção3.6são apresentadas

algumas considerações finais do capítulo.

3.2 Fases do Teste Estrutural de Programas OA

Considerando o teste de programas OA, baseando-se no livro deSommerville (2000) e na

abordagem deHarrold e Rothermel (1994), essa atividade poderia ser particionada nas seguintes

fases (Lemos et al., 2004b,a):

42

Page 55: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 43

1. Teste de Unidade: O teste de cada método e adendo isoladamente, também chamado de

teste intra-método ou intra-adendo.

2. Teste de Módulo: O teste de uma coleção de unidades dependentes – unidades que inte-

ragem por meio de chamadas ou interações com adendos. Essa fase pode ser dividida nos

seguintes tipos de teste (considerando classes e aspectos como entidades diferentes):

• Inter-método: Consiste em testar cada método público juntamente com outros métodos

da mesma classe chamados direta ou indiretamente (chamadas indiretas são aquelas

que ocorrem fora do escopo do próprio método, dentro de um método chamado em

qualquer profundidade) (Harrold e Rothermel, 1994).

• Adendo-método: Consiste em testar cada adendo juntamente com outros métodos cha-

mados por ele direta ou indiretamente.

• Método-adendo: Consiste em testar cada método público juntamente com os adendos

que o afetam direta ou indiretamente (considerando que um adendo pode afetar outro

adendo). Nesse tipo de teste não é considerada a integração dos métodos afetados com

os outros métodos chamados por eles, nem com método chamados pelos adendos.

• Adendo-adendo: Consiste em testar cada adendo juntamente com outros adendos que

o afetam direta ou indiretamente.

• Inter-método-adendo: Consiste em testar cada método público juntamente com os

adendos que o afetam direta e indiretamente, e com métodos chamados direta ou indi-

retamente. Esse tipo de teste inclui os quatro primeiros tipos de teste descritos acima.

• Intra-classe: Consiste em testar as interações entre os métodos públicos de uma classe

quando chamados em diferentes seqüências (Harrold e Rothermel, 1994), considerando

ou não a interação com os aspectos.

• Inter-classe: Consiste em testar as interações entre classes diferentes, considerando ou

não a interação dos aspectos.

3. Teste de Sistema: A integração de todos os módulos forma um subsistem ou um sistema

completo. Para essa fase geralmente é utilizado o teste funcional.

A próxima seção trata o teste de unidade, que consiste em exercitar cada unidade de um pro-

grama como uma entidade independente, procurando identificar erros em sua lógica e implemen-

tação. O teste de integração é tratado na Seção3.4.

3.3 Teste Estrutural de Unidade

Para o teste de unidade é necessária a definição da menor unidade de um programa que será

testada nessa fase, de acordo com a técnica de programação utilizada. No caso de programas OO,

por exemplo, pode-se considerar cada método como a menor unidade a ser testada (Seção2.3.3).

Page 56: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 44

Para os programas orientados a aspectos, seguindo a mesma linha do trabalho deVincenzi

(2004), que considera o método como a menor unidade de um programa OO, neste trabalho

considera-se cada método, adendo e método inter-tipo declarado como as menores unidades do

programa. A partir daí, o teste de unidade para uma dada classe deve ser feito para cada método

e método inter-tipo declarado (caso exista); e para um dado aspecto deve-se testar cada adendo e

cada método. O teste de unidade de um método é chamado intra-método e, similarmente, o teste

de um adendo isoladamente pode ser chamado de testeintra-adendo.

No teste estrutural, para que os critérios possam ser aplicados, é necessário que sejam definidos

os grafos de fluxo de controle e de dados adequados (Seção2.3). Na próxima seção são defini-

dos genericamente os grafos de fluxo para programas orientados a aspectos e sua versão para a

linguagem AspectJ.

3.3.1 Grafo de Fluxo para Programas Orientados a Aspectos

No fluxo de controle de programas orientados a aspectos, quando os aspectos definem compor-

tamento em algum ponto do sistema por meio dos adendos, pode ser detectado um novo tipo de

interação. Quando o ponto de junção é alcançado, o fluxo de controle é passado para o adendo do

aspecto que afeta o ponto, retornando ao final da execução. Esse tipo de interação pode ser compa-

rada com uma chamada a método, na qual o fluxo de controle é passado para o método chamado,

retornando ao final de sua execução. Porém, é necessário que se faça uma correta distinção entre os

pontos de chamada e os pontos onde os aspectos definem comportamento por meio dos adendos,

pois no primeiro caso o desenvolvedor do método inseriu explicitamente a chamada ao método

para atender os propósitos do método em programação, enquanto que no segundo caso são os

aspectos os responsáveis por definir o comportamento desejado em pontos de junção específicos.

Dessa forma, no fluxo de controle de um programa orientado a aspectos tem-se um novo tipo

de interação que torna necessária a adaptação do grafo para uma representação adequada do fluxo

de controle das unidades que são afetadas por adendos de aspectos. Para esse fim é definido um

novo tipo de nó – o nó transversal (crosscutting node) – para representar os pontos das unidades

onde os aspectos definem comportamentos transversais, tomando o fluxo de controle para si.

O Grafo de Fluxo de Controle Orientado a Aspectos (AOCFG) é um grafo definido com o

objetivo de apoiar o teste de unidade de um programa orientado a aspectos. Como é possível que

em uma linguagem orientada a aspectos os adendos sejam afetados por outros adendos – como, por

exemplo, no AspectJ – oAOCFG pode ser usado para representar tanto métodos quanto adendos.

Um grafoAOCFG de uma dada unidadeu é definido como um grafo dirigidoAOCFG(u) =

(N, E, s, C, T ), tal que:

• N representa o conjunto de nós de um grafoAOCFG : N = {n|n corresponde a uma

seqüência linear de computações deu};

Page 57: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 45

• E ⊆ N ×N é o conjunto completo de arestas doAOCFG. Cada arestae ∈ E representa a

transferência de controle que pode ocorrer entre dois nós;

• s ∈ N é o nó de entrada deu. s é o único nó do grafo que não possui nenhuma aresta de

entrada;

• C ⊆ N é o conjunto (possivelmente vazio) de nós transversais que representam um nó no

qual ocorre uma interação com um adendo de um dado aspecto;

• T ⊆ N é o conjunto (possivelmente vazio) de nós de saída. Ou seja, cadat ∈ T não possui

nenhuma aresta de saída.

O Grafo Def-Uso Orientado a Aspectos (AODU ) é oAOCFG com informações de definições

e usos de variáveis, para a aplicação de critérios baseados em fluxo de dados. Como o grafoAODUé umAOCFG estendido, é necessária apenas a construção doAODU para se derivar requisitos

de teste tanto para o fluxo de controle quanto para o fluxo de dados do programa.

Para uma dada linguagem orientada a aspectos, o grafoAODU deve ser instanciado de maneira

a representar as unidades de programas escritos nessa linguagem e para que possa ser definido um

modelo de dados a partir do qual identificam-se as definições/usos de variáveis e quais tipos de

variáveis são tratadas. No caso do AspectJ – linguagem na qual este trabalho é baseado – decidiu-

se por estender o trabalho deVincenzi (2004), que definiu modelos e critérios de teste para o

bytecode Java. Essa decisão é baseada no fato de que o compilador/combinador do AspectJ produz

bytecode Java comum como resultado da compilação/combinação (Seção2.2).

Antes de construir o grafoAODU para as unidades de um programa escrito em AspectJ, é

construído o grafo de instruções de fluxo de dados (IG) (Vincenzi, 2004). Informalmente oIG é

um grafo no qual cada nó contém uma única instrução de bytecode e as arestas conectam instruções

que podem ser executadas seqüencialmente. A partir daí o grafoIG é acrescido de informações

de acesso a dados (definição ou uso) para cada instrução de bytecode (Lemos et al., 2004c,d).

A idéia do grafoIG é abstrair o fluxo de controle e de dados envolvidos em cada instrução

de bytecode individual. Porém, algumas características do bytecode precisam ser tratadas com

cuidado durante a análise do fluxo de controle. Em particular, é necessário tratar cuidadosamente

as instruções de chamadas a sub-rotinas implementadas pela Máquina Virtual Java (JVM) (jsr e

jsr_w ) e o mecanismo de tratamento de exceção de Java. No último caso o problema é que os

tratadores de exceção de Java não são executados a partir de um fluxo de controle normal de um

dado programa, mas apenas quando exceções são lançadas. A solução adotada porVincenzi (2004)

foi utilizar dois tipos de arestas: arestas regulares, que representam o fluxo de controle normal e

arestas de exceção, que representam o fluxo de controle quando exceções ocorrem (uma aborda-

gem similar foi proposta porSinha e Harrold (1998), entretanto somente considerando exceções

explicitamente geradas). A extensão feita para o grafoIG neste trabalho diz respeito à adição do

conjunto de nós transversais como uma componente do grafo.

Page 58: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 46

Formalmente o grafoIG de uma dada unidadeu é definido como um grafo dirigidoIG(u) =

(NI, EI, si, T I, CI), tal que:

• NI representa o conjunto não-vazio de nós de um grafoIG: NI = {ni|ni corresponde a uma

instrução de bytecodei, para todo bytecodei alcançável deu1}. Como cada nó corresponde

a uma única instrução bytecode, usa-se daqui por dianteni para referenciar indistintamente

o nó do grafoIG e a instrução a ele correspondente;

• EI = EIr ∪ EIe é o conjunto completo de arestas doIG tal que:

– EIr eEIe correspondem a dois subconjuntos disjuntos de arestas regulares e de exce-

ção, respectivamente:

∗ EIr é o conjunto de arestas regulares definido comoEIr = {(ni, nj)| a instrução

emnj pode ser executada imediatamente após a instrução emni e(ni, nj) /∈ EIe}.

∗ EIe é o conjunto de arestas de exceção definido comoEIe = {(ni, nj)| a instrução

deni está no escopo de um tratador de exceção2 que inicia na instrução denj};

• si ∈ NI é o nó de entrada que corresponde ao nó que contém a primeira instrução deu.

Considerex um nó de umIG, IN(x) corresponde ao número de arestas de entrada de x.

Tem-se queIN(si) = 0.

• TI ⊆ NI é o conjunto de nós de saída deu. Considerex um nó de umIG, OUT (x)

corresponde ao número de arestas de saída dex. Tem-se queTI = {ni ∈ NI|OUT (ni) =

0}.

• CI ⊆ NI é o conjunto (possivelmente vazio) de nós transversais, isto é, nós que representam

a execução de adendos de determinados aspectos. De fato, esses nós correspondem aos

nós cujas instruções de bytecode são invocações aos métodos correspondentes aos adendos

(Seção2.2.1).

Para adicionar informações relacionadas com o fluxo de dados das unidades noIG, a solução

adotada porVincenzi (2004) foi classificar as instruções de bytecode, relacionando cada uma com

o fluxo de dados envolvido. Essa classificação é apresentada na Tabela3.1.

Além da classificação das instruções de bytecode, é necessário fazer algumas suposições sobre

a identificação da definição e uso de variáveis (adaptado do trabalho deVincenzi (2004)):

1. Variáveis agregadas são consideradas como sendo uma única posição de memória e a de-

finição/uso de qualquer elemento da variável agregadaa[] é considerada como sendo uma

definição/uso dea[] . Assim sendo, em um comando do tipo “a[i] = a[j] + 1 ” existe uma

definição e um uso da variável agregadaa[] .

1Se o compilador gerar alguma instrução não-alcançável, essa instrução não será representada noIG.2Um tratador de exceçãoj é responsável por tratar exceções geradas pelas instruções de bytecode localizadas

dentre um determinado intervalo deoffsets[ojm ..ojn ]. Diz-se que uma instrução de bytecodei localizada no offsetoi

está no escopo do tratador de exceçãoj se e somente seoi ∈ [ojm ..ojn ].

Page 59: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 47

Tabela 3.1:Diferentes classes de instruções de bytecode (Vincenzi, 2004).

Classe Instrução de Bytecode Implicações no Fluxo de Dados

0 athrow, goto, goto_w, if_acmpeq, if_acmpne,if_icmpeq, if_icmpge, if_icmpgt, if_icmple, if_icmplt ,if_icmpne, ifeq, ifge, ifgt , ifle, iflt , ifne, ifnonnull , ifnull ,lookupswitch, tableswitch, areturn , dreturn , freturn ,ireturn , lreturn , return , ret, monitorenter, monitore-xit , pop, pop2, breakpoint, impdep1, impdep2, nop,checkcast, wide, swap

Essas instruções não têm implicações no fluxo de dados daunidade.

1 invokeinterface, invokespecial, invokestatic, invokevir-tual, jsr , jsr_w, dadd, ddiv, dmul, dneg, drem, dsub,fadd, fdiv , fmul , fneg, frem, fsub, iadd, iand, idiv , imul ,ineg, ior , irem, ishl, ishr, isub, iushr, ixor , ladd, land,ldiv , lmul , lneg, lor , lrem, lshl, lshr, lsub, lushr, lxor ,arraylength, instanceof, aconst_null, bipush, dconst,fconst, iconst, lconst, sipush, ldc, ldc_w, ldc2_w, d2f,d2i, d2l, f2d, f2i, f2l, i2b, i2c, i2d, i2f, i2l, i2s, l2d, l2f, l2i,new, multianewarray , anewarray, newarray, dcmpg,dcmpl, fcmpg, fcmpl, lcmp

Essas instruções não têm implicações no fluxo de dados daunidade. Além disso, elas deixam no topo da pilha de exe-cução um elemento desconhecido. Acessos a tal elementonão irão caracterizar definição ou uso de nenhuma variável.Por exemplo, a instruçãonew empilha a referência a umnovo objeto no topo da pilha de execução e qualquer usofuturo de tal referência, tal como o acesso de um de seusatributos, não é considerado um uso ou definição desse ob-jeto.

2 aaload, baload, caload, daload, faload, iaload, laload,saload

Carregam no topo da pilha de execução um elemento de umvetor caracterizando um uso do vetor.

3 aastore, bastore, castore, dastore, fastore, iastore, las-tore, sastore

Armazenam o valor do topo da pilha de execução em umelemento do vetor caracterizando uma definição do vetor.

4 putfield Armazena o valor do topo da pilha de execução em um atri-buto de instância caracterizando a definição de tal atributo.

5 putstatic Armazena o valor do topo da pilha de execução em umatributo de classe caracterizando a definição de tal atributo.

6 dup, dup2, dup_x1, dup_x2, dup2_x1, dup2_x2 Essas instruções duplicam o valor do topo da pilha de exe-cução e não têm implicações no fluxo de dados da unidade.

7 aload, dload, fload, iload, lload Carregam no topo da pilha de execução o valor armaze-nado em uma variável local caracterizando um uso de talvariável.

8 astore, dstore, fstore, istore, lstore Armazenam o valor do topo da pilha de execução em umavariável local caracterizando uma definição de tal variável.

9 getfield Carrega no topo da pilha de execução o valor armazenadoem um atributo de instância caracterizando um uso de talatributo.

10 getstatic Carrega no topo da pilha de execução o valor armazenadoem um atributo de classe caracterizando um uso de tal atri-buto.

11 iinc Incrementa o valor armazenado em uma dada variável localcaracterizando um uso e uma definição de tal variável.

2. Se uma variável agregadaa[][] é declarada, acessos aos seus elementos caracterizam uma

definição ou uso dea[][] , dependendo do tipo de acesso. Assim sendo, comandos de atri-

buição do tipo “a[0][0] = 10 ” ou “a[0] = new int[10]” caracterizam uma definição dea[][]

e a[] , respectivamente, ao passo que no comando “a[0][0] = a[2][3] ” existe um uso e uma

definição da variávela[][] .

3. Toda vez que um atributo de instância é usado (definido) existe um uso da variável de refe-

rência que permite o acesso ao atributo e um uso (definição) do atributo em si. Por exemplo,

considereref_1e ref_2duas variáveis de referência para objetos da classeC a qual contém

dois atributos de instânciax e y do tipo inteiro (int), no comando “ref_1.x = ref_2.y” existe

usos das variáveis de referênciaref_1 e ref_2, um uso do atributo de instânciaref_2.y, e

uma definição do atributo de instânciaref_1.x. Uma vez que os atributos de instância são

válidos no escopo de toda a classe (aspecto), cada atributo de instância usado em uma dada

Page 60: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 48

unidade, e que não tenha sido definido na unidade, é considerado como tendo sido definido

no primeiro nó do grafoIG da unidade em questão.

4. Atributos estáticos podem ser considerados como variáveis globais e o acesso a eles é feito

sem a necessidade de uma variável de instância. Considerando uma classeC com os atributos

estáticosw e z, ambos do tipoint, no comando “C.z = C.w + 10” existe um uso do atributo

C.we uma definição do atributoC.z. Mesmo que o acesso ao atributo estático seja feito por

meio de uma variável de instânciaref_1do tipo da classeC, tal como “ref_1.w = 10”, em

bytecode, tal variável de referência é automaticamente convertida no nome da classe, não

sendo caracterizado um uso da variável de referência nesse caso. Uma vez que os atributos

estáticos são válidos no escopo de toda a classe (aspecto), cada atributo estático usado em

uma dada unidade, e que não tenha sido definido na unidade, é considerado como tendo sido

definido no primeiro nó do grafoIG da unidade em questão.

5. Na invocação de um método, tal comoref_1.foo(e_1, e_2,. . ., e_n), considera-se que ocorre

um uso da variável de instânciaref_1. As regras para a identificação de definição e uso nas

expressõese_1, e_2,. . ., e_nsão as mesmas descritas nos itens de 1 a 4.

Ainda no caso das unidades de instância, uma definição para a variável que representa a ins-

tância correntethis é associada ao primeiro nó doIG . O mesmo ocorre para as variáveis

locais que correspondem aos parâmetros formais da unidade em execução. Para métodos de

classe, somente as variáveis locais correspondentes aos parâmetros formais são considera-

das definidas no nó de entrada deIG, já que nenhuma variável de instância é requerida para

invocar um método de classe.

O IG oferece uma maneira prática de percorrer o conjunto de instruções de uma dada unidade,

identificando usos e definições de variáveis. Entretanto, o número de nós e arestas envolvidos

nesse tipo de grafo pode ser muito grande. Dessa maneira, constrói-se oAODU baseando-se no

conceito de bloco de instruções, isto é, instruções que são executadas seqüencialmente em um fluxo

de controle normal, sem nenhuma possível interrupção (como na versão generalizada doAODUdefinida acima). OAODU é então o modelo base para derivar requisitos de teste baseados no

fluxo de controle e fluxo de dados para o teste de unidade de programas escritos em AspectJ. O

AODU de uma dada unidadeu é definido como um grafo dirigidoAODU(u) = (N, E, s, T, C),

tal que cada nón ∈ N representa um bloco de instruções de bytecode:

• N representa o conjunto de nós de um grafoAODU : N = {n|n corresponde a um bloco

de instruções de bytecode deu}. Isto é,N é o conjunto não-vazio de nós, representando as

instruções de bytecode deu. In é a n-tupla ordenada de instruções agrupadas no nóu;

• E = Er ∪ Ee é o conjunto completo de arestas do grafoAODU . Considere oIG(u) =

(NI, EI, si, T I, CI):

Page 61: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 49

– Er é o conjunto de arestas regulares definido comoEr = {(ni, nj)| existe uma aresta

regular que vai do último elemento deIniao primeiro elemento deInj

noIG(u)};

– Ee é o conjunto de arestas de exceção definido comoEe = {(ni, nj)| existe uma aresta

de exceção que vai do último elemento deIniao primeiro elemento deInj

noIG(u)};

– Ec ⊆ Er é o conjunto de arestas transversais (crosscutting edges) definido comoEc =

{(x, y) ∈ E|(x ∈ C) ∨ (y ∈ C)} (componenteC definida abaixo);

• s ∈ N |IN(s) = 0 é o nó de entrada deu;

• T ⊆ N é o conjunto (possivelmente vazio) de nós de saída, isto é,T = {n ∈ N |OUT (n) =

0};

• C ⊆ N é o conjunto (possivelmente vazio) de nós transversais. Nesse caso um nó transversal

corresponde a um bloco de instruções no qual uma das instruções representa uma invocação

de um método correspondente a um adendo de um dado aspecto.

O algoritmo utilizado para reduzir um grafo de instrução de fluxo de dadosIG para umAODUé apresentado na Figura3.1. O algoritmo também é estendido do trabalho deVincenzi (2004) para

considerar os nós e arestas transversais. Nas linhas15-20 os nós transversais são identificados

e adicionados ao conjuntoC. Também é garantido que haja apenas uma execução de adendo

para cada nó transversal. Além disso, nas linhas5-7, as arestas transversais (conjuntoEc) são

identificadas.

Na Figura3.2é mostrada uma aplicação OA simples escrita em AspectJ. Partes dos bytecodes

do métodoaffectedMethod sem e com a presença do aspecto são mostradas nas Figuras3.3e

3.4e os grafosAODU referentes ao método, sem e com a presença do aspecto, são mostrados na

Figura3.5. Os conjuntoscu, pu e d correspondem aos c-usos, p-usos e definições de variáveis. A

representação gráfica doAODU é definida da seguinte forma:

• Nós regulares são representados por círculos com o rótulo contendo a primeira instrução de

bytecode do bloco;

• Nós de chamada são representados por círculos duplos;

• Nós transversais são representados por elipses tracejadas, com informação de qual tipo de

adendo afeta aquele ponto (posterior, anterior ou de contorno –before, after ou around),

e a qual aspecto pertence. Por exemplo, se há uma interação com um adendo posterior de

um aspectoAspectem um certo ponto, o nó transversal correspondente é adicionado com a

informação� after − Aspect �;

• Nós de saída são representados por nós negritados;

Page 62: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 50

# Entrada: IG , o grafo de fluxo de dados de instrução# IG =< NI, EI, si, T I, CI > a ser reduzido;# Saída: AODU , o grafo de fluxo de dadosAODU =< N,E, s, T, C >01 s:= NovoBloco(si)02 para cadax ∈ N03 sex não tem sucessores04 T := T ∪ {x}05 para cada(x, y) ∈ E06 sex ∈ C ouy ∈ C07 Ec := Ec ∪ {(x, y)}#Função Auxiliar: NovoBloco#Entrada: Um nóy do grafoIG#Saída: Um bloco do grafoAODU08 ins := a instrução de bytecode emy09 sey já foi visitado10 retorne o nów ∈ N que contémy11 BlocoAtual := novobloco12 N := N ∪ {BlocoAtual}13 x := y14 faça15 sex ∈ CI //x é um nó transversal deIG16 seBlocoAtual ∈ C17 E := E ∪ {(BlocoAtual, NovoBloco(x))}18 x := null19 senão20 C := C ∪ {BlocoAtual}21 sex 6= null22 incluax como parte doBlocoAtual23 marquex como visitado24 sex termina o bloco atual25 para cadav tal que(x, v) ∈ EIr

26 Er := Er ∪ {(BlocoAtual, NovoBloco(v))}27 para cadav tal que(x, v) ∈ EIe

28 Ee := Ee ∪ {(BlocoAtual, NovoBloco(v))}29 x := null30 senão31 se existe umv tal que(x, v) ∈ EIr

32 x := v33 senãox := null34 enquantox 6= null35 retorneBlocoAtual

Figura 3.1: Algoritmo para gerar um grafoAODU a partir de um grafoIG.

• Arestas de exceção (Ee) são representadas por arestas tracejadas, representando o fluxo de

controle do ponto onde uma exceção é gerada até o primeiro nó correspondente ao tratador

daquela exceção.

Page 63: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 51

public class Point {public int x;public int y;public AClass a;

public Point( int _x, int _y) {x = _x; y = _y;

}

public void affectedMethod(Point p, int_x, int _y) {try {

if (p.x <= 10 && p.y <= 10) {p.x = _x; p.y = _y;p.a = new AClass(10, 20);

}p.printPoint(p);System.out.println(p.x);

} catch (AnException ae) {System.out.println("Exception " +

"catched!");}

}

public void printPoint(Point p)throws AnException {if (p.x == 0) {

AnException ae = new AnException();throw ae;

}...

}...public static class AnException

extends Exception {...

}}

public aspect AnAspect {pointcut exec(Point p, int i, int j):

execution ( voidPoint.affectedMethod(Point, int , int ))&& args (p, i, j);

pointcut settingA(AClass a):set (AClass Point.a) && args (a) &&! within (aspects.*);

pointcut handlerPC(Point p) :handler (Point.AnException) && this (p);

before (Point p, int i, int j):exec(p, i, j) {if (p.x >= 0) p.x = i + 3;if (p.y >= 0) p.y = j + 4;

}

after (Point p, int i, int j) returning ():exec(p, i, j) {System.out.println("after " +"returning exec");if (i > 10)

System.out.println("i > 10");else

System.out.println("i <= 10");if (p.x > 10)

System.out.println("p.x > 10");else

System.out.println("p.x <= 10");}

void around (AClass a) : settingA(a) {System.out.println("around settingA");a.a = 20; a.b = 30;proceed (a);

}

before (Point p) : handlerPC(p) {p.x = 40;

}}

Figura 3.2: Exemplo de um programa orientado a aspectos escrito em AspectJ.

Adendos de Contorno – AspectJ Na implementação atual do AspectJ (versão 1.2), quando

um adendo de contorno que utiliza o métodoproceed – que prossegue com a execução do ponto

de junção – é aplicado em uma determinada unidade, o ponto de junção original (bloco de by-

tecode) é extraído e colocado em um método separado que aceita quaisquer variáveis do método

onde o adendo é aplicado. O adendo de contorno recebe então um novo parâmetro, um objeto

fecho (closure object), e as chamadas aoproceed são substituídas por chamadas a um método

run do objeto fecho recebido como parâmetro, que por sua vez faz a chamada ao método que

encapsula o ponto de junção original. Isso é feito porque quando a chamada aoproceed é feita

em um tipo aninhado, o combinador deve assumir que a chamada é referente ao ponto de junção

mais próximo no aninhamento.

Sendo assim, em uma implementação da abordagem descrita neste capítulo em uma ferramenta

de teste para programas escritos em AspectJ, podem ser geradosAODUs também para os métodos

que encapsulam os pontos de junção originais. Dessa forma, permite-se a análise de cobertura para

os pontos de junção afetados por adendos de contorno que utilizam oproceed .

Page 64: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 52

0 aload_11 getfield #17 <Field int x>4 bipush 106 if_icmpgt 439 aload_110 getfield #19 <Field int y>13 bipush 1015 if_icmpgt 4318 aload_119 iload_220 putfield #17 <Field int x>23 aload_124 iload_325 putfield #19 <Field int y>28 aload_129 new #29 <Class components.AClass>32 dup33 bipush 1035 bipush 2037 invokespecial #31 <Method AClass(int,int)>

40 putfield #33 <Field components.AClassa>

43 aload_144 aload_145 invokevirtual #37 <Method void printPoint(

components.Point)>48 getstatic #43 <Field java.io.PrintStream

java.lang.System.out>51 aload_152 getfield #17 <Field int x>55 invokevirtual #49 <Method void

println(int)>58 goto 7161 astore 463 getstatic #43 <Field java.io.PrintStream

java.lang.System.out>66 ldc #51 <String "Exception catched!">68 invokevirtual #54 <Method void println(

java.lang.String)>71 return

Figura 3.3: Parte do bytecode do métodoaffectedMethod sem a presença do aspectoAnAspect .

0 aload_1...18 invokevirtual #116 <Method void

ajc$before$aspects_AnAspect$1$dcd6c0af(components.Point, int, int)>

21 aload_122 getfield #17 <Field int x>25 bipush 1027 if_icmpgt 10930 aload_131 getfield #19 <Field int y>34 bipush 1036 if_icmpgt 10939 aload_1...106 invokevirtual #110 <Method void

ajc$around$aspects_AnAspect$2$f8ad947f(components.AClass, org.aspectj.runtime.internal.AroundClosure)>

109 aload_1110 aload_1111 invokevirtual #37 <Method void

printPoint(components.Point)>

114 getstatic #43 <Field java.io.PrintStreamjava.lang.System.out>

117 aload_1118 getfield #17 <Field int x>128 invokestatic #106 <Method

aspects.AnAspect aspects.AnAspect.aspectOf()>

131 aload_0132 invokevirtual #113 <Method void

ajc$before$aspects_AnAspect$4$e6001804(components.Point)>

135 astore 4137 getstatic #43 <Field java.io.PrintStream

java.lang.System.out>140 ldc #51 <String "Exception catched!">142 invokevirtual #54 <Method void println(

java.lang.String)>145 goto 148...157 invokevirtual #119 <Method void

ajc$afterReturning$aspects_AnAspect$3$dcd6c0af(components.Point, int, int)>

160 return

Figura 3.4: Parte do bytecode do métodoaffectedMethod com a presença do aspectoAnAspect .

3.3.2 Critérios de Fluxo de Controle

Antes da definição dos critérios, alguns conceitos precisam ser definidos. Nos seguintes cri-

térios de teste estruturais – seguindo o trabalho deVincenzi (2004) – os requisitos de teste foram

divididos em dois conjuntos disjuntos: um contendo todos os requisitos que podem ser cobertos

durante a execução normal de um programa – denominado independente de exceção – e outro con-

tendo apenas os requisitos que necessitam do lançamento de uma exceção para serem cobertos –

denominado dependente de exceção. A partir daí, definem-se os seguintes conceitos:

Page 65: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 53

pu={p.x, p}

pu={p.y,p}

pu={p.y,p}

pu={p.x, p}

d={p,p.x,p.y,_x,_y}

cu={p,_x,_y}

cu={p.x}

d={p.a,p.x, p.y}

cu={p.x,p}

<<around−AnAspect>>

<<before−AnAspect>>

<<before−AnAspect>>

pu={p.x, p}

pu={p.y,p}

cu={p.x}

cu={p.x,p}

pu={p.y,p}

pu={p.x, p}

cu={p,_x,_y}d={p.x, p.y}

d={p,p.x,p.y,_x,_y}

cu={p, _x, _y}<<afterReturning−AnAspect>>

18

61

71

43

0

9

39

21

30

0

109

135

127

148

160

Figura 3.5: AODUs do métodoaffectedMethod sem e com a presença do aspectoAnAspect .

Page 66: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 54

• Conjunto de nós predicativos: ConsidereOUTr(i) como o número de arestas regulares de

saída de um nói, formalmente:OUTr(i) = |{(i, j)|(i, j) ∈ Er}|. O conjunto de nós

predicativos é o conjuntoNpred = {n ∈ N |OUTr(n) > 1}, isto é, o conjunto de todos os

nós do grafoAODU que contêm mais de uma aresta regular de saída.

• Caminhos livres de exceção: O conjunto de caminhos livres de exceção é o conjuntoπ|∀(ni

, nj) ∈ π ⇒ (ni, nj) é alcançável por um caminho que não contém nenhuma aresta de

exceção.

• Nós dependentes e independentes de exceção: O conjunto de nós dependentes de exceção é

definido comoNed = {n ∈ N |@ um caminho livre de exceçãoπ tal quen ∈ π}. O conjunto

de nós independentes de exceção é o conjunto definido comoNei = N −Ned.

• Arestas dependentes e independentes de exceção: As arestas dependentes de exceção for-

mam o conjuntoEed = {e ∈ E|@ um caminho livre de exceçãoπ tal quee ∈ π}. As arestas

independentes de exceção formam o conjuntoEei = E − Eed.

• Arestas transversais: O conjunto de arestas transversais é definido comoEc = {(x, y) ∈Er|(x ∈ C) ∨ (y ∈ C)}.

• C-usos globais e locais: Um c-uso de uma variávelx em um nój é um c-uso global se não há

nenhuma definição dex no mesmo nój, em uma instrução anterior ao c-uso. Caso contrário

é um c-uso local.

Dois critérios de fluxo de controle – todos-nós e todas-arestas – definidos porMyers (1979)

são aplicados no contexto de programas orientados a aspectos. ConsidereT um conjunto de casos

de teste para um programaP (sendo queAODU é o grafo de fluxo de controle/dados deP ), eΠ o

conjunto de caminhos exercitados na execução deT . Um conjuntoΠ inclui um nói seΠ contém

um caminho(ni, ..., nm) tal quei = nj para algumj, 1 ≤ j ≤ m. Similarmente, um conjuntoΠ

inclui uma aresta(i1, i2) seΠ contém um caminho(n1, ..., nm) tal quei1 = nj e i2 = nj+1 para

algumj, 1 ≤ j ≤ m− 1.

O Critério Todos-Nós

• Π satisfaz o critério todos-nós seΠ inclui cada nón ∈ N do grafoAODU . Em outras

palavras, esse critério garante que cada instrução (ou comando) de uma dada unidade é

executada pelo menos uma vez por um caso de teste deT .

Para utilizar as considerações de tratamento de exceção que foram feitas, seguindo o trabalho de

Vincenzi (2004), o critério Todos-Nós foi particionado em dois conjuntos disjuntos de elementos

de teste requeridos, resultando nos seguintes critérios:

• todos-nós-independentes-de-exceção (Todos-Nósei)

Page 67: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 55

– Π satisfaz o critério todos-nós-independentes-de-exceção se cada nónei ∈ Nei está in-

cluído emΠ. Em outras palavras, este critério requer que cada nó de um grafoAODUque é alcançável por meio de pelo menos um caminho livre de exceção seja executado

ao menos uma vez por algum caso de teste deT .

• todos-nós-dependentes-de-exceção (Todos-Nósed)

– Π satisfaz o critério todos-nós-dependentes-de-exceção se cada nóned ∈ Ned está in-

cluído emΠ. Em outras palavras, este critério requer que cada nó de um grafoAODUque não é alcançável por meio de um caminho livre de exceção seja executado ao me-

nos uma vez por por algum caso de teste deT .

Na aplicação do critério Todos-Nós em programas orientados a aspectos, uma propriedade

interessante seria a habilidade de saber quais dos nós cobertos são específicos desse contexto, para

que haja a possibilidade do testador focar nesses pontos na atividade de teste. Como observado na

seção anterior, um novo tipo de interação ocorre em unidades de programas orientados a aspectos,

representada pelos nós transversais.

Dessa maneira, seria interessante a existência de um critério de teste particular que requere-

ria a cobertura dos nós transversais, para auxiliar a revelar defeitos particulares a esses pontos.

Conseqüentemente, a partir da análise de cobertura baseada nesse critério, o testador teria conhe-

cimento sobre quando os casos de teste estariam – ou não – sensibilizando os aspectos.

A partir dessa motivação, define-se o seguinte critério:

• todos-nós-transversais (Todos-NósC)

– Π satisfaz o critério todos-nós-transversais se cada nóni ∈ C está incluído emΠ. Em

outras palavras, esse critério requer que cada nó transversal, e portanto cada execução

de adendo que ocorre na unidade afetada, seja exercitado pelo menos uma vez por

algum caso de teste deT .

O Critério Todas-Arestas

• Π satisfaz o critério Todas-Arestas se cada arestae ∈ E de um grafoAODU está incluída

em Π. Em outras palavras, esse critério garante que cada aresta do grafoAODU de uma

dada unidade é executada ao menos uma vez por algum caso de teste deT .

Assim como foi feito para o critério Todos-Nós, para utilizar as considerações de tratamento

de exceção que foram feitas, seguindo o trabalho deVincenzi (2004), o critério Todas-Arestas

foi particionado em dois conjuntos disjuntos de elementos de teste requeridos, resultando nos

seguintes critérios:

Page 68: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 56

• todas-arestas-independentes-de-exceção (Todas-Arestasei)

– Π satisfaz o critério todas-arestas-independentes-de-exceção se cada arestaeei ∈ Eei

está incluída emΠ. Em outras palavras, esse critério exige que cada aresta do grafo

AODU que é alcançável por pelo menos um caminho livre de exceção seja exercitada

pelo menos uma vez por algum caso de teste deT .

• todas-arestas-dependentes-de-exceção (Todas-Arestased)

– Π satisfaz o critério todas-arestas-dependentes-de-exceção se cada arestaeed ∈ Eed

está incluída emΠ. Em outras palavras, esse critério exige que cada aresta do grafo

AODU que é inalcançável por qualquer dos caminhos livres de exceção doAODU é

exercitada pelo menos uma vez por algum caso de teste deT .

Da mesma maneira que tem-se nós especiais noAODU – os nós transversais – pode-se consi-

derar também a existência de arestas especiais, que conectam os nós transversais. Do ponto de vista

do teste, seria interessante também a informação de quando tais arestas são exercitadas, seguindo a

mesma idéia do critério todos-nós-transversais. Essa informação é interessante porque um defeito

poderia ser revelado somente quando uma aresta transversal em particular fosse escolhida.

Na Figura3.6são mostrados dois exemplos de métodos afetados por um aspecto, um relacio-

nado com arestas transversais de entrada (methodA ) e outro relacionado com arestas transversais

de saída (methodB ). A cobertura dos nós transversais não revelaria necessariamente a divisão

por zero. Se a aresta transversal(0, 9) do métodomethodA e (0, 14) do métodomethodB são

exercitadas, uma exceção de divisão por zero é lançada.

A partir dessa motivação, define-se o critério todas-arestas-transversais:

• todas-arestas-transversais (Todas-ArestasC)

– Π satisfaz o critério todas-arestas-transversais se cada arestaec ∈ Ec está incluída em

Π. Em outras palavras, esse critério requer que cada aresta do grafoAODU que tem

um nó transversal como nó início ou destino seja exercitada por algum caso de teste de

T .

3.3.3 Critérios de Fluxo de Dados

Antes da definição dos critérios de fluxo de dados, alguns conceitos precisam ser definidos:

• Os conjuntos def, c-uso, p-uso, dcu e dpu: Na implementação dos critérios de fluxo de da-

dos, todos os usos de uma variável em um nó predicativoi ∈ Npred são considerados p-usos.

Essa decisão foi feita no trabalho deVincenzi (2004) porque é computacionalmente caro

distinguir c-usos de p-usos a partir das instruções de bytecode Java, considerando a estrutura

Page 69: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 57

public class ClassA {int n;public ClassA() {

n = 10;}public void methodA( boolean b) {

this .n = 1;if (b == true )

this .n = 0;}public void methodB( boolean b) {

int num;num = 10;if (b == true )

num = num / this .n;System.out.println(num);

}}

public aspect AspectA {after (ClassA c) returning () :

execution ( voidClassA.methodA( boolean ))&& this (c) {

int div = 10 / c.n;}before (ClassA c) :

execution ( voidClassA.methodB( boolean ))&& this (c) {

c.n = 0;}

}

<<afterRetrurning−AspectA>>

0

9

17

<<before−AspectA>>0

14

21

Figura 3.6: Um programa simples escrito em AspectJ e osAODUs dos métodosmethodA emethodB da classeClassA .

orientada a pilhas da máquina virtual Java. Assim, para um nói e uma variávelx do grafo

AODU , são definidos:

def(i) = {variáveis definidas no nói}

c-uso(i)=

variáveis com uso global emi sei é computacional

∅ caso contrário

p-uso(i)=

variáveis com uso local ou global emi sei é predicativo

∅ caso contráriodcu(x, i) = { nós j de um grafoAODU tal quex ∈ c-uso(j) e existe um caminho livre de

definição parax dei a j}

dpu(x, i) = { arestas(j, k) de um grafoAODU tal quex ∈ p-uso(j) e existe um caminho

livre de definição parax dei à aresta(j, k)}

• Pares def-c-uso e def-p-uso: Um par def-c-uso é uma tripla(i, j, x) ondei é um nó que

contém uma definição dex e j ∈ dcu(x, i). Um par def-p-uso é uma tripla(i, (j, k), x) onde

i é um nó que contém uma definição dex e (j, k) ∈ dpu(x,i). Um par Def-Uso é um par

def-c-uso ou def-p-uso.

Page 70: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 58

• Os conjuntos dcued, dcuei, dpued, dpuei: Os conjuntos de pares foram particionados, con-

siderando a existência ou não existência de caminhos livres de definição que também são

livres de exceção. Assim dcued(x, i) ={nós j de um grafoAODU tal quex ∈ c-uso(j) e

não existe nenhum caminho livre de definição parax que também é um caminho livre de

exceção dei a j}. O dcuei(x, i) = dcu(x, i)− dcued(x, i). O mesmo é feito com relação aos

p-usos: o dpued(x, i) ={arestas(j, k) de um grafoAODU tal quex ∈ p-uso(j) e não existe

nenhum caminho livre de definição parax que também é um caminho livre de exceção dei

a (j, k)}. O dpuei(x, i) = dpu(x, i)− dpued(x, i).

O critério Todos-Usos

• Π satisfaz o critério Todos-Usos se para cadai ∈ def(i), Π inclui um caminho livre de

definição parax de i a cada elemento de dcu(x, i) e a cada elemento dpu(x, i). Em outras

palavras, esse critério requer que cada par def-c-uso(i, j, x) tal quej ∈ dcu(x, i) e cada

par def-p-uso(i, (j, k), x) tal que(j, k) ∈ dpu(x, i) seja exercitado ao menos uma vez para

algum caso de teste deT .

Seguindo a mesma idéia que foi aplicada aos critérios Todos-Nós e Todas-Arestas, os requisitos

de teste do critério Todos-Usos são particionados em dois conjuntos disjuntos, como definido nos

seguintes critérios:

• todos-usos-independentes-de-exceção (Todos-Usosei)

– Π satisfaz o critério todos-usos-independentes-de-exceção se para cada nói ∈ N e

para cadax ∈ def(i), Π inclui um caminho livre de definição parax do nói a todos

elementos de dcuei(x, i) e todos elementos de dpuei(x, i). Em outras palavras, esse

critério requer que cada par def-c-uso livre de exceção(i, j, x)|j ∈ dcuei(x, i) e cada

par def-p-uso livre de exceção(i, (j, k), x)|(j, k) ∈ dpuei(x, i) seja exercitado pelo

menos uma vez por algum caso de teste deT .

• todos-usos-dependentes-de-exceção (Todos-Usosed)

– Π satisfaz o critério todos-usos-dependentes-de-exceção se para cada nói ∈ N e para

cadax ∈ def(i), Π inclui um caminho livre de definição parax do nói a todos os ele-

mentos de dcued(x, i) e a todos os elementos de dpued(x, i). Em outras palavras, esse

critério requer que cada par def-c-uso dependente de exceção(i, j, x)|j ∈ dcued(x, i) e

cada par def-p-uso dependente de exceção(i, (j, k), x)|(j, k) ∈ dpued(x, i) seja exerci-

tado ao menos uma vez para algum caso de teste deT .

Um ponto interessante a ser notado sobre o fluxo de dados de um programa orientado a aspectos

é que um aspecto e uma unidade afetada por seus adendos podem trocar dados (por exemplo,

Page 71: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 59

quando variáveis de contexto são passadas para algum adendo). Dessa forma, outra idéia de critério

para programas orientados a aspectos seria exercitar os pares Def-Uso cujos usos estão em nós

transversais – porque esses usos são evidências de troca de dados entre classes e aspectos. Esse

critério é interessante pois interações de dados errôneas entre classes e aspectos são uma possível

fonte de erros.

Quando variáveis de contexto são passadas a algum adendo, em bytecode, essas variáveis são

empilhadas na pilha de execução (e de maneira geral isso é feito no mesmo bloco da execução

do adendo, ou seja, em um nó transversal). Na Tabela3.1 pode ser notado que essas instruções

de pilha caracterizam o uso das variáveis empilhadas. Assim, quando variáveis de contexto –

e qualquer outra informação – são passadas para adendos, no modelo utilizado neste trabalho é

caracterizado um uso da variável em um nó transversal.

A partir daí define-se o critério todos-usos-transversais:

• todos-usos-transversais (Todos-UsosC)

– Π satisfaz o critério todos-usos-transversais se para cada nói ∈ def(i), Π inclui um ca-

minho livre de definição parax dei a cada elemento de dcu(x, i) que é um nó transver-

sal e a todos elementos de dpu(x, i) nos quais o nó início da aresta é um nó transversal.

Em outras palavras esse critério requer que cada par def-c-uso(i, j, x)|j ∈ dcu(x, i)

tal quej ∈ C e cada par def-p-uso(i, (j, k), x)|(j, k) ∈ dpu(x, i) tal quej ∈ C seja

exercitado pelo menos uma vez por algum caso de teste deT .

3.3.4 Exemplo

Na Tabela3.2 são mostrados os requisitos de teste para cada critério OA definido, para o

métodoaffectedMethod apresentado na Figura3.2. Pela simplicidade do exemplo, o conjunto

de casos de teste Todos-NósC-adequado gerado é também adequado para os outros critérios.

Tabela 3.2:Requisitos de teste para cada critério OA definido, para o métodoaffectedMethod .

Critério Conjunto de Requisitos Conjunto de Casos de Teste

Todos-NósC Rn = {0, 39, 127, 148} Rn = {((0, 0), 7, 6),((0, 0),−3, 7)}

Todas-ArestasC Re = {(0, 21), (21, 127)∗, (30, 39), Rn

(30, 127)∗, (39, 109), (39, 127)∗, (109, 148),(127, 135), (135, 148), (148, 160)}

Todos-UsosC Ru = {(_y, 0, 39), (_x, 0, 39), (p, 0, 39), Rn

(this, 0, 39), (this, 0, 127), (L@83, 0, 148),(L@9, 0, 148), (L@10, 0, 148)}

∗ Requisitos não-executáveis

Page 72: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 60

3.3.5 Comparação entre os Critérios de Teste de Unidade

Na Figura3.7 é mostrada a hierarquia de inclusão considerando os critérios definidos no tra-

balho deVincenzi (2004) e os critérios OA definidos neste trabalho (Todos-UsosC , Todos-NósCe Todas-ArestasC). A seguir, é feita a demonstração da não inclusão Todos-UsosC ; Todas-

ArestasC e da inclusão Todas-ArestasC ⇒ Todos-NósC .

Todos-C a m in h os

Todos-Usos

Todos-Usosei Todos-Usosed Todos-U sosC

Toda s-Aresta s

Toda s-Aresta sei Toda s-Aresta sedTodas-ArestasC

Todos-Nos

Todos-Nosei Todos-Nosed Todos-N osC

Figura 3.7: Hierarquia dos critérios definidos no trabalho deVincenzi (2004) e neste trabalho.

SejaT um conjunto de casos de teste para um programaP (AODU sendo o grafo de fluxo de

controle deP ) e sejaΠ o conjunto de caminhos executados porT .

• Todos-UsosC ; Todas-ArestasCPara provar que o critério Todos-UsosC não inclui o critério Todas-ArestasC , basta considerar

o grafoAODU da Figura3.8(a). O conjuntod corresponde às definições de variáveis,c aos

c-usos ep aos p-usos.{(0, 1, 4, 5, 6)} é Todos-UsosC-adequado mas não é Todas-ArestasC-

adequado, pois as arestas transversais(2, 3) e (3, 6) não são cobertas.

• Todas-ArestasC ⇒ Todos-NósCSuponha queT é Todas-ArestasC-adequado para P. Seja(i, j) ∈ Ec uma aresta transversal

de P. ComoT é Todas-ArestasC-adequado, isso implica que∀(n1, n2) ∈ Ec, existe um

caminho(n1, ..., nm) emΠ, tal quen1 = nj e n2 = nj+1, para algumj, 1 ≤ j ≤ m − 1.

SeT não é Todos-NósC-adequado, então existe pelo menos um nónc ∈ C tal quenc não

está incluído em nenhum dos caminhos deΠ. Entretanto, por definição, todo nó transversal

nc ∈ C é origem ou destino de uma aresta transversal. Desse modo, existe uma aresta

3Os nomes de variáveisL@N são gerados pela ferramenta JaBUTi/AJ (Capítulo4). Nesse caso, as variáveiscorrespondem a dados inseridos pelo compilador do AspectJ, e por isso o nomeL@N não foi substituído na tabelapelo nome das variáveis encontradas no código fonte.

Page 73: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 61

transversal(n1, nc) ∈ Ec ou uma aresta transversal(nc, n2) ∈ Ec. Portanto, seT é Todas-

ArestasC-adequado, entãoT é também Todos-NósC-adequado.

Para provar que Todos-NósC ; Todas-ArestasC , basta considerar oAODU apresentado

na Figura3.8(b). {(0, 1, 2)} satisfaz o critério Todos-NósC , porém não satisfaz o critério

Todas-ArestasC , pois não inclui a aresta transversal(0, 2).

<<before−AnAspect>><<before−AnAspect>>

0

c={X}

2

1

3

4

5

6

c={X}

d={X,Y}

p={Y} p={Y}

(a) Todos-UsosC ; Todas-ArestasC

2

<<before−AnAspect>>

1

0

(b) Todos-NósC ; Todas-ArestasC

Figura 3.8: GrafosAODU utilizados como contra-exemplos.

3.4 Teste Estrutural de Integração

Os diferentes tipos de teste de módulo definidos na Seção3.3 podem ser muito caros para

serem aplicados se todas as chamadas indiretas e interações indiretas com adendos forem consi-

deradas (a complexidade pode ser exponencial). Dessa forma, pode-se restringir a profundidade

das chamadas e interações com adendos, para apoiar uma atividade de teste praticável – um tipo

de teste similar ao teste par a par (pairwise).

Neste trabalho foca-se o teste do tipo Método-adendo, considerando somente as interações

diretas com adendos. Em trabalhos futuros esses tipos de teste podem ser mais detalhados e re-

finados, explorando, por exemplo, o teste intra/inter classes, considerando ou não a presença dos

aspectos e também o teste de aspectos isolados.

3.4.1 Teste Método-adendo

Para tornar possível a aplicação do teste de integração de fluxo de dados a programas orientados

a aspectos, mais especificamente ao teste Método-adendo, são estendidas as definições para o teste

de unidade apresentadas anteriormente. Evidentemente, esse tipo de teste é importante, já que,

Page 74: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 62

como apontado porAlexander (2003), Alexander e Bieman (2002b) e Alexander et al. (2004),

dependências de dados emergentes entre classes e aspectos nos artefatos combinados podem ser

possíveis fontes de erros. Um exemplo desse tipo de defeito seria um conjunto de junção pouco

restrito que captura mais pontos de junção do que deve, aplicado a um adendo anterior de chamada

que altera os parâmetros passados para o método chamado. As chamadas a métodos às quais o

adendo não deveria ser aplicado serão feitas com valores de parâmetros errados.

O modelo base para o teste de fluxo de dados de integração Método-adendo é o grafoMADU(Method-Advice Def-Use). OMADU é composto peloAODU do método em si, juntamente

com osAODUs dos adendos que o afetam diretamente. Os nós transversais doAODU do mé-

todo são quebrados em um nó de aprimoramento (enh– enhancement node) e um nó de retorno

(ret – return node). Esse mecanismo é similar àquele utilizado para o teste inter-procedimental,

na representação de chamadas e retornos de procedimentos (Harrold e Soffa, 1989). Arestas adi-

cionais são criadas para conectar os nósenh com os nós de entrada dosAODUs dos adendos e

para conectar os nós de saída dosAODUs dos adendos com os nósret. O grafoMADU deve ser

construído para cada método afetado por adendos.

O escopo do métodocorresponde aoAODU do método (incluindo os nósenh e ret) e os

escopos de adendoscorrespondem aosAODUs dos adendos. Cada interação de um adendo em

um determinado ponto de junção começa um novo escopo de adendo indexado, e os rótulos dos

nós dosAODUs dos adendos são prefixados com o índice do escopo correspondente. Isso é feito

porque a numeração das instruções de bytecode se repetem em cada unidade, iniciando sempre de

0.

Na Figura3.9é mostrado um exemplo de um grafoMADU do métodoaffectedMethod

mostrado anteriormente (Figura3.2), construído a partir da análise do bytecode combinado. Pode

ser notado que cada par de nósenh e ret substitui cada nó transversal doAODU do método

affectedMethod (Figura3.5). Além disso, informação de fluxo de dados é obtida para cada

nó e aresta, para os escopos do método e dos adendos. Na computação de definições e usos,

variáveis são renomeadas quando necessário – por exemplo, o argumento_x que é utilizado no

adendo posterior do aspectoAnAspect como variável locali .

Pares Def-Uso Aspectuais Baseando-se nas diferentes interações de dados que podem ocor-

rer em um método afetado por aspectos, e baseando-se nos diferentes escopos representados no

grafoMADU , quatro tipos de pares Def-Usoaspectuaispodem ser definidos. SejaM um mé-

todo afetado por adendos,d uma sentença contendo uma definição de uma variávelx e u uma

sentença contendo um uso dex, os seguintes pares são definidos:

• componente-componente: Sed eu estão emM , e existe um caminho livre de definição para

x ded au, então(x, d, u) é um par Def-Uso componente-componente.

Page 75: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 63

39

0

0

method−scope

pu={p.x, p}

d={p.x}

d={p.y}

advice−scope 1

advice−scope 4

pu={p.x,p} pu={p.x,p}

cu={p}

pu={p.y,p} pu={p.y,p}

cu={p}

pu={p.y,p} pu={p.y,p}

cu={p,_x,_y}pu={_x}pu={_x}

pu={p.x,p} pu={p.x,p}

cu={p.x,p}

pu={p.x, p}

127

127

148

148

d={p,p.x,p.y,_x,_y}

advice−scope 2cu={a}d={a.a, a.b}

advice−scope 3

d={p.x}cu={p}

d={p.x, p.y}

21

30

ret

ret

ret

39

1.15

1.22

1.29

1.36

1.0

4.0

4.14 4.25

4.33

4.42 4.53

4.61

3.0

ret

109

2.0

enh

enh

enh

enh

Figura 3.9: GrafoMADU do métodoaffectedMethod .

• componente-aspecto: Seja{A1, A2, ..., An} o conjunto de adendos que interagem comM

em uma invocação deM . Sed está emM , u está emAi, e existe um caminho livre de

definição parax ded au então(x, d, u) é um par Def-Uso componente-aspecto.

• aspecto-componente: Seja{A1, A2, ..., An} o conjunto de adendos que interagem comM

em uma invocação deM . Sed está emAi, tal queAi ∈ {A1, A2, ..., An}, u está emM ,

e existe um caminho livre de definição parax de d a u, então(x, d, u) é um par Def-Uso

aspecto-componente.

• aspecto-aspecto: Seja{A1, A2, ..., An} o conjunto de adendos que interagem comM em

uma invocação deM . Sed está emAi, tal queAi ∈ {A1, A2, ..., An}, u está emAj, tal

queAj ∈ {A1, A2, ..., An}, e existe um caminho livre de definição parax ded a u, então

(x, d, u) é um par Def-Uso aspecto-aspecto.

Page 76: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 64

Critérios de Teste de Integração Baseados no Fluxo de Dados

Antes da definição dos critérios são necessários alguns conceitos. Como no teste de fluxo de

dados de unidade, para cada nó do grafoMADU é associado um conjunto c-uso e um conjunto

def, e para cada aresta do grafo é associado um conjunto p-uso. Além disso são definidos os

conjuntos dcu e dpu:

• dcu(x, i) é o conjunto de todos os nósj de um dado grafoMADU , tal quex ∈ c-uso(j) e

existe um caminho livre de definição parax dei a j.

• dpu(x, i) é o conjunto de todas as arestas de um dado grafoMADU , tal quex ∈ p-uso(j)

e existe um caminho livre de definição parax dei a j.

SejaT um conjunto de casos de teste para o teste de um programaP , eΠ o conjunto de cami-

nhos exercitados a partir da execução deT . Baseado nos tipos de pares Def-Uso definidos anteri-

ormente, e no critério Todos-Usos, são definidos os seguintes critérios de teste Método-adendo:

• todos-cc-usos (todos-usos-componente-componente):T satisfaz o critério todos-cc-usos se

para cada nói no escopo do método do grafoMADU e para cadax ∈ def(i), Π inclui um

caminho livre de definição parax dei para cada elemento dedcu(x, i) e para cada elemento

dedpu(x, i) que estão no escopo do método.

• todos-ca-usos (todos-usos-componente-aspecto):T satisfaz o critério todos-ca-usos se para

cada nói no escopo do método do grafoMADU e para cadax ∈ def(i), Π inclui um

caminho livre de definição parax dei para cada elemento dedcu(x, i) e para cada elemento

dedpu(x, i) que estão em escopo de adendos.

• todos-ac-usos (todos-usos-aspecto-componente):T satisfaz o critério todos-ac-usos se para

cada nói em escopo de adendo do grafoMADU e para cadax ∈ def(i), Π inclui um

caminho livre de definição parax dei para cada elemento dedcu(x, i) e para cada elemento

dedpu(x, i) que estão no escopo de método.

• todos-aa-usos (todos-usos-aspecto-aspecto):T satisfaz o critério todos-aa-usos se para cada

nó i em escopo de adendo do grafoMADU e para cadax ∈ def(i), Π inclui um caminho

livre de definição parax de i para cada elemento dedcu(x, i) e para cada elemento de

dpu(x, i) que estão em escopo de adendo.

Também é definido o critério tradicional Todos-Usos para esse contexto, que inclui os quatro

critérios definidos acima:

• todos-usos: Um conjuntoΠ de caminhos executados por um conjunto de casos de teste

satisfaz o critério todos-usos se para cada nói do grafoMADU e para cadax ∈ def(i), Π

inclui um caminho livre de definição parax dei para cada elemento dedcu(x, i) e para cada

elemento dedpu(x, i).

Page 77: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 65

Exemplo

Na Figura3.9apresentada anteriormente, foi mostrado o grafoMADU do métodoaffect-

edMethod . Na Tabela3.3 são mostrados os conjuntos de pares Def-Uso aspectuais – todos os

requisitos de teste de cada um dos critérios definidos anteriormente coletados a partir de uma

análise doMADU –, juntamente com conjuntos de casos de teste adequados para cada critério.

A entrada para os casos de teste é composta de um ponto e dois inteiros, as entradas do método

affectedMethod . Por exemplo, para exercitar o par Def-Uso aspecto-aspecto (1.15, (4.33,

4.53), p.x), pode ser utilizada a entrada ((0, 1), 7, 10), que faria com que o programa exercitasse

o seguinte caminho: (0 enh, 1.0, 1.15, 1.22, 1.29, 1.36, 0 ret, 21, 109, 148 enh, 4.0, 4.25, 4.33,

4.53, 4.61, 148 ret). Na Figura3.10é mostrado este caminho no grafoMADU . A variável p.x

é definida no nó 1.15 e usada na aresta (4.33, 4.53) sem ser redefinida, assim exercitando o par

Def-Uso. Também pode ser notado que alguns requisitos de teste não são executáveis, isto é, não

existem entradas que podem exercitá-los.

Para dar uma idéia do custo relacionado com a abordagem, na Tabela3.4é mostrado o total de

casos de teste requeridos em um conjunto de casos de teste adequado para cada um dos critérios

definidos, para o métodoaffectedMethod integrado com os adendos que o afetam diretamente.

Os totais de requisitos não-executáveis também são apresentados.

Tabela 3.3:Pares Def-Uso aspectuais coletados a partir do grafoMADU do métodoaffectedMethod e conjuntos de casos de teste adequados para cada critério.

Critério Conjunto de Requisitos Conjunto de Casos de Teste

todos-ac-usos Rac = {(1.15, (21, 30), p.x), (1.15, (21, 109), p.x), Tac = {((0, 1), 7, 4), ((0, 1), 8, 4),(1.15, 109, p.x), (1.29, (30, 109), p.y), ((0, 1), 7, 10)}(1.29, (30, 39 enh), p.y)}

todos-ca-usos Rca = {(0 enh, (4.0, 4.25), _x), (0 enh, (4.0, 4.14), _x), Tca = {((0, 1), 10, 4),(0 enh, (4.33, 4.42), p.x)∗, (0 enh, (4.33, 4.53), p.x), ((0, 1), 11, 4), ((−1, 1), 7, 10),(39 enh, (4.33, 4.42), p.x)∗, (39 enh, (4.33, 4.53), p.x)} ((0, 1), 7, 4)}

todos-aa-usos Raa = {(1.15, (4.33, 4.42), p.x), (1.15, (4.33, 4.53), p.x), Taa = {((0, 1), 8, 10),(3.0, (4.33, 4.42), p.x)∗, (3.0, (4.33, 4.53), p.x)∗} ((0, 1), 7, 10)}

todos-cc-usos Rcc = {(0 enh, (21, 30), p), (0 enh, (21, 30), p.x), Tcc = Tac ∪ {((0,−1), 7, 4),(0 enh, (21, 109), p), (0 enh, (21, 109), p.x)∗, ((−1, 1), 7, 4)}(0 enh, (30, 39 enh), p), (0 enh, (30, 39 enh), p.y),(0 enh, (30, 109), p), (0 enh, (30, 109), p.y)∗,(0 enh, 39 enh, p), (0 enh, 39 enh, _x), (0 enh, 39 enh, _y),(0 enh, 109, p), (0 enh, 109, p.x)∗}

todos-usos Rac ∪Rca ∪Raa ∪Rcc Tac ∪ Tca ∪ Taa ∪ Tcc

* Requisitos não-executáveis

3.5 Comparação e Avaliação da Abordagem Proposta

Comparando a abordagem proposta neste trabalho com as outras propostas, algumas diferen-

ças e vantagens podem ser notadas. Em comparação com o trabalho deZhao (2003), no que diz

Page 78: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 66

39

0

0

method−scope

pu={p.x, p}

d={p.y}

advice−scope 1

advice−scope 4

pu={p.x,p} pu={p.x,p}

cu={p}

pu={p.y,p} pu={p.y,p}

cu={p}

pu={p.y,p} pu={p.y,p}

cu={p,_x,_y}pu={_x}pu={_x}

pu={p.x,p}

pu={p.x, p}

127

127

148

148

d={p,p.x,p.y,_x,_y}

advice−scope 2cu={a}d={a.a, a.b}

advice−scope 3

d={p.x}cu={p}

d={p.x, p.y}

cu={p.x,p}

pu={p.x,p}

d={p.x}

21

30

ret

ret

ret

39

1.15

1.22

1.29

1.36

1.0

4.0

4.14 4.25

4.33

4.42 4.53

4.61

3.0

ret

109

2.0

enh

enh

enh

enh

Figura 3.10: Caminho percorrido no grafoMADU do métodoaffectedMethod , a partir daentrada ((0, 1), 7, 10).

Tabela 3.4:Total de casos de teste e de requisitos não-executáveis para cada critério definido,para o métodoaffectedMethod .

Critério Casos de Teste Requisitos Não-executáveis

todos-ac-usos 3 0todos-ca-usos 4 2todos-aa-usos 2 2todos-cc-usos 5 3todos-usos 9 7

respeito ao teste de unidade, a abordagem proposta aqui oferece a vantagem de permitir a realiza-

ção do teste de unidade de adendos e métodos isoladamente. O teste intra-módulo proposto por

Zhao (2003) já inclui a interação entre métodos e adendos, sendo que o teste isolado de adendos e

Page 79: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 67

métodos não pode ser conduzido. Na Tabela3.5 são relacionadas as fases de teste da abordagem

de Zhao (2003, 2002) e deste trabalho. Como comentado na Seção2.3.5, o conceito demódulo

utilizado porZhao (2003) refere-se aos c-métodos e c-adendos, ou seja, aos métodos juntamente

com os adendos que o afetam e aos adendos juntamente com os métodos afetados por eles. Por

exemplo, analisando a Figura3.11na qual é mostrado umAOCFG de um dado método, na abor-

dagem deZhao (2003) um dos grafos dos c-métodos a serem testados seria referente a este método

somado com os grafos de fluxo de cada um dos adendos que o estão afetando (o que é feito na

abordagem proposta neste trabalho somente na fase de integração). Dessa forma, nem o método

nem os adendos podem ser testados em isolamento na fase de unidade. Na Figura3.12é mostrado

como ficaria esse grafo na abordagem deZhao (2003), com os adendos envolvidos por retângulos

tracejados, e utilizando o conceito de blocos de comandos ao invés de criar um nó para cada linha

de código, como é feito porZhao (2003)4. Outro fator que pode ser notado é a dificuldade em dis-

tinguir as partes relacionadas com os adendos das partes relacionadas com o método no grafo de

um c-método (na figura isso foi feito de manualmente), ao passo que na abordagem deste trabalho

as partes estão bem separadas e a análise de cobertura também é feita separadamente.

Tabela 3.5:Relação entre as fases de teste no teste de programas OA na abordagem destetrabalho e na abordagem deZhao (2003).

Menor Unidade: Método/Adendo

Fase Teste de Software Orientado a AspectosUnidade Intra-método e Intra-adendo

Integração Inter-método, Método-adendo, Adendo-Método,Adendo-Adendo, Intra-classe e Inter-classe

Sistema Toda a aplicaçãoMenor Unidade: C-Classe/C-Aspecto

Fase Teste de Software Orientado a AspectosUnidade Intra-módulo, Inter-módulo, Intra-classe ou Intra-Aspecto

Integração Inter-classeSistema Toda a aplicação

É importante notar também queZhao (2003) não define nenhum critério de teste em seus ar-

tigos, e a abordagem proposta neste trabalho define nove critérios de teste diferentes, focando

propriedades diversas.Zhao (2003) também não comenta sobre o teste baseado em fluxo de con-

trole.

No que diz respeito ao trabalho deXie et al. (2004), pode ser notado um problema no algoritmo

de detecção de casos de teste relevantes para o teste dos aspectos. O ponto é que não se pode inferir

4Na verdade, o grafo de um c-método é quase o mesmo que umMADU de um método afetado por adendos, coma diferença que na proposta deste trabalho, o teste Método-adendo é feito depois de se testar as unidades isoladas, ouseja, na fase de integração.

Page 80: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 68

<<before−FigureLogging>>

<<before−FigureLogging>>

<<afterReturning−FigureLogging>>

<<afterReturning−FigureLogging>>

0

4

60 81

200

224

227

239

248

251

257

8

Figura 3.11: GrafoAOCFG para um dado método.

que um caso de teste sensibilizou um dado aspecto pelo simples fato do caso de teste chamar um

método que é afetado pelo aspecto, pois isso pode depender da entrada do caso de teste.

Por exemplo, analisando a Figura3.11novamente, se um caso de teste para o método exercitar

o caminho(0, 4), tal caso de teste nem sequer faria com que os adendos que afetam o método

fossem executados, e portanto seria irrelevante para o teste do aspecto. No entanto, no algoritmo

para seleção de casos de teste relevantes proposto porXie et al. (2004), tal caso de teste seria

considerado relevante para o teste do aspecto, o que seria um equívoco.

Quanto ao trabalho deXu et al. (2004a), no que diz respeito à parte relacionada ao teste estru-

tural, não são definidos critérios de teste. Além disso, como acontece também com a proposta de

Zhao (2003), o teste isolado de adendos e métodos não pode ser realizado.

A justificativa para a definição dos critérios de teste de integração para programas OA é similar

à justificativa para a definição dos critérios de teste de integração baseados em fluxo de dados

propostos para o teste de programas procedimentais e orientados a objetos, quando procedimentos

Page 81: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 69

0

4

81

8

248

60

1.0

60

1.361.60

1.88

1.151

224

2.0

3.0

3.363.69

3.88 3.121

3.151

4.0

1.121

Figura 3.12: Grafo do c-método baseado no grafo do método apresentado na Figura3.11.

(métodos) interagem com outros procedimentos (métodos) que chamam. A principal diferença

é que em um programa orientado a aspectos essas interações são mais sutis, porque, de forma

geral, os desenvolvedores não sabem exatamente onde e como os aspectos vão interagir com os

componentes. O modelo e os critérios propostos expõem essas interações, facilitando não somente

o teste mas também o entendimento de programas OA.

Os critérios de teste de integração específicos para programas OA são partições do critério

tradicional Todos-Usos definido nesse contexto. A razão para particionar esse critério em quatro é

a informação particular que cada um oferece, que pode ser valiosa para o desenvolvedor/testador.

Por exemplo, os requisitos de teste expostos pelo critério todos-aa-usos podem expor interações de

dados entre diferentes adendos que afetam o mesmo método, e essas interações podem ser muito

Page 82: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 3. TESTE ESTRUTURAL DE PROGRAMAS ORIENTADOS A ASPECTOS 70

sutis para o desenvolvedor/testador. Se fosse definido somente um critério – o Todos-Usos – essa

informação somente poderia ser obtida de manualmente.

Comparando o critério Todos-Usos (definido nesse contexto) com cada um dos quatro critérios

de teste OA, utilizando a relação de inclusão (Zhu et al., 1997), pode ser provado que os últi-

mos são mais fracos, pois requerem subconjuntos dos requisitos de teste do critério Todos-Usos.

Porém, como apontado por Weyuker (Weyuker, 2002), um critério incluído não é necessariamente

menos eficiente em encontrar defeitos que o critério que o inclui, pois tipicamente existem diversos

conjuntos de casos de teste adequados para um dado critério.

A abordagem de teste de integração proposta pode auxiliar o testador a encontrar defeitos

particulares aos programas OA. Por exemplo, os defeitos do tipo 3 e 4 do modelo de defeitos

proposto porAlexander et al. (2004) (Seção2.3.5) são fortemente relacionados com interações

de dados que ocorrem em programas OA, isto é, um defeito em respeitar pós-condições definidas

ou em preservar invariantes de estado causadas por aspectos deve ser relacionado com aspectos

alterando dados nos componentes quando não deveriam. Dessa forma, o testador pode detectar tais

defeitos no exercício dos pares Def-Uso aspectuais nos quais as definições de variáveis ocorrem

em escopos de adendos (pares Def-Uso aspecto-componente e aspecto-aspecto).

3.6 Considerações Finais

Neste capítulo foi apresentada uma abordagem de teste estrutural para programas orientados a

aspectos, para o teste de unidade e de integração. O grafo de fluxo de controle/dados foi estendido

para representar as unidades e módulos de programas OA e critérios de teste baseados em fluxo

de controle e de dados foram definidos a partir dos grafos, incluindo critérios específicos para

programas OA.

Com a abordagem de teste definida, é necessário implementá-la em uma ferramenta de teste,

para facilitar a análise de cobertura a partir dos critérios de teste. No próximo capítulo são definidas

as extensões da ferramenta JaBUTi (Vincenzi, 2004), que levaram à criação da versão JaBUTi/AJ

(AspectJ), para apoiar o teste de unidade de programas orientados a aspectos escritos em AspectJ.

Para ilustrar a aplicabilidade da abordagem ainda são apresentados alguns exemplos de aplicação

da ferramenta no teste de programas OA.

Page 83: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO

4Teste de Unidade: Automatização e

Exemplos

4.1 Considerações Iniciais

Como observado no Capítulo2, a atividade de teste, se realizada manualmente, é geralmente

propensa a erros e limitada a aplicações de pequeno porte (dos Santos Domingues, 2001). Nesse

contexto, ferramentas de teste podem auxiliar a automatizar essa tarefa, permitindo a aplicação dos

critérios de teste estruturais de maneira mais eficiente e prática. Além disso, as ferramentas de teste

possibilitam a realização detestes de regressão, quando manutenções são feitas no programa e os

casos de teste armazenados são executados novamente para a validação da aplicação modificada

(dos Santos Domingues, 2001).

Para implementar a abordagem de teste de unidade de programas AspectJ proposta no capítulo

anterior, é necessária uma ferramenta que possibilite a instrumentação do código-objeto de Java –

o bytecode – e derive os modelos de fluxo de controle e de dados a partir da análise estática do

bytecode. A ferramenta JaBUTi proposta porVincenzi (2004) e discutida na Seção2.3.4oferece

essas funcionalidades, necessitando de algumas extensões para possibilitar o teste de programas

OA de acordo com a abordagem proposta neste trabalho.

Na Seção4.2são descritas as alterações da ferramenta JaBUTi que resultaram na versão JaBU-

Ti/AJ (Java Bytecode UnderstandiIng and Testing/ AspectJ) para o teste de unidade de programas

OA baseados na linguagem AspectJ. Na Seção4.3, a operação da ferramenta é ilustrada por meio

de três exemplos e, por fim, na Seção4.5são apresentadas as considerações finais do capítulo.

71

Page 84: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 72

4.2 Extensão da Ferramenta JaBUTi para Apoio ao Teste

de Unidade de Programas OA

A ferramenta JaBUTi foi estendida para possibilitar a utilização dos critérios orientados a as-

pectos propostos neste trabalho, ou seja, os critérios todos-nós-transversais, todas-arestas-transver-

sais e todos-usos-transversais. Nessa versão a ferramenta foi batizada de JaBUTi/AJ. Primeira-

mente a implementação do grafo Def-Uso definido para o teste de programas Java foi estendida

para representar o grafoAODU . O pacotegraph foi utilizado para essa atividade e, em parti-

cular, a classeCFGNodeque implementa um nó CFG de um grafo, foi estendida em uma classe

CFGCCNodepara representar os nós transversais (crosscutting nodes) com as informações extras

(o tipo do adendo que afeta o ponto e a qual aspecto ele pertence). Um nó transversal é identificado

sempre que existe uma chamada a um método referente a um adendo no bloco de bytecode relativo

ao nó (ver Seções2.2.1e3.3.1).

O pacotecriteria foi utilizado para a implementação dos critérios OA. Três classes novas

foram criadas:AllCrosscuttingNodes , AllCrosscuttingEdges e AllCrosscut-

tingUses , cada uma estendendo a classeAbstractCriterion que implementa métodos

comuns de critérios de teste estrutural. Para a classeAllCrosscuttingNodes , a alteração

feita teve o objetivo de filtrar os requisitos de teste, incluindo como requisitos somente os nós

transversais. Para a classeAllCrosscuttingEdges , uma estratégia similar foi seguida, in-

cluindo como requisitos somente as arestas cujo nó de início ou de destino são nós transversais.

Para a classeAllCrosscuttingUses os requisitos de teste também foram filtrados, incluindo

somente os requisitos nos quais os usos estão em nós transversais.

As outras alterações realizadas dizem respeito a: representação gráfica dos grafos, para mostrar

os nós transversais com as informações extras; mudança das nomenclaturas utilizadas na interface

(incluindo também os aspectos e adendos como unidades a serem testadas); e inclusão dos critérios

novos na interface gráfica. Para isso foram estendidos os pacotesgvf , project e gui . Em

termos quantitativos foram escritas em torno de 1000 linhas de código, além das alterações dos

códigos pré-existentes (Tabela4.1).

Tabela 4.1:Arquivos criados na extensão da JaBUTi para JaBUTi/AJ.Pacote Arquivo LOCcriteria AllCCNodes.java 225

AllCCEdges.java 157AllCCUses.java 350

graph CFGCCNode.java 118gvf GVFCCNode.java 146

Total 996

Page 85: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 73

4.3 Funcionamento da Ferramenta JaBUTi/AJ e Exem-

plos de Aplicação

Nesta seção são apresentados alguns exemplos de teste de aplicações OA utilizando a ferra-

menta JaBUTi/AJ, tanto para ilustrar a operação da ferramenta quanto para evidenciar a aplicabili-

dade da abordagem proposta neste trabalho. As características de operação da ferramenta não são

aprofundadas, já que poucas alterações foram feitas no que diz respeito a essa propriedade. Mais

informações sobre as demais funcionalidades da ferramenta JaBUTi podem ser obtidas a partir do

Manual do Usuário (Vincenzi et al., 2004).

4.3.1 Aplicação de Figuras 2D

O primeiro exemplo refere-se a uma aplicação simples de Figuras 2D, dividida em dois pacotes

– components e aspects – contendo os componentes e os aspectos da aplicação. Na Figura

4.1 é mostrado o diagrama UML da aplicação com estereótipos para representar os entrecortes e

os aspectos.

−x−y

+setX()+setY()+getX()+getY()+moveBy()+distance()+rotate

+moveBy()+distance()

+setP1()+setP2()+getP1()+getP2()

−p2−p1

FigureLogging

+<<pointcut>>pointConstr()+<<pointcut>>setY()+<<pointcut>>setX()

+indentationLevel

FigureElement<<interface>>

<<crosscuts>>

<<crosscuts>> <<crosscuts>>

Point LineSegment

+moveBy()

PointBoundsChecking

+<<pointcut>>setX()+<<pointcut>>setY()+<<pointcut>>pointConstr()

<<aspect>>

<<aspect>>

Figura 4.1: Diagrama UML da aplicação de figuras 2D orientada a aspectos.

O pacotecomponents contém:

• Uma interfaceFigureElement que possui um método para mover o elemento de figura;

Page 86: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 74

• Uma classePoint que modela pontos e uma classeLineSegment que modela segmentos

de reta, ambas implementando a interfaceFigureElement (Figura4.2);

package components;

public class Point implements FigureElement {private double x = 0, y = 0;public Point( double _x, double _y) {

x = _x;y = _y;

}public void setX( double _x) {

x = _x;}public void setY( double _y) {

y = _y;}public double getX() {

return x;}public double getY() {

return y;}public void moveBy( double dx, double dy) {

x = x + dx;y = y + dy;

}public double distance(Point pt) {

double d = java.lang.Math.sqrt(java.lang.Math.pow((x - pt.x),2) +java.lang.Math.pow((y - pt.y),2));

return d;}public void rotate( Point center, double angle ) {

double radius = this .distance( center );double deltaY = y - center.getY();double deltaX = x - center.getX();double theta = Math.atan( deltaY/deltaX );

x = center.getX() + radius * Math.cos( angle +theta );

y = center.getY() + radius * Math.sin( angle +theta );

}}

import java.lang.Double;import java.lang.Math;

public class LineSegment implements FigureElement {private Point p1, p2;public LineSegment (Point _p1, Point _p2) {

p1 = _p1;p2 = _p2;

}public Point getP1() {

return p1;}public Point getP2() {

return p2;}void setP1(Point p1) {

this .p1 = p1;}void setP2(Point p2) {

this .p2 = p2;}public void moveBy( double dx, double dy) {

p1.moveBy(dx, dy);p2.moveBy(dx, dy);

}double distance(Point pt) {

double t, bot, dot, xn, yn;if (pt == null )

return java.lang.Double.POSITIVE_INFINITY;

bot = java.lang.Math.pow((p2.getX() -p1.getX()),2) + java.lang.Math.pow(

(p2.getY() - p1.getY()),2);if ( bot == 0.0 ) {

xn = p1.getX();yn = p1.getY();

}else {

dot = (pt.getX() - p1.getX()) * (p2.getX() -p1.getX()) +

(pt.getY() - p1.getY()) * (p2.getY() -p1.getY());

t = dot / bot;xn = p1.getX() + t * (p2.getX() - p1.getX());yn = p1.getY() + t * (p2.getY() - p1.getY());

}

Point Pn = new Point(xn,yn);double dist = pt.distance(Pn);return dist;

}public Point intersection(LineSegment l2) {

double x1 = this .getP1().getX();double y1 = this .getP1().getY();double x2 = this .getP2().getX();double y2 = this .getP2().getY();double x3 = l2.getP1().getX();double y3 = l2.getP1().getY();double x4 = l2.getP2().getX();double y4 = l2.getP2().getY();double uaN = (x4 - x3)*(y1 - y3) -

(y4 - y3)*(x1 - x3);double ubN = (x2 - x1)*(y1 - y3) -

(y2 - y1)*(x1 - x3);double den = (y4 - y3)*(x2 - x1) -

(x4 - x3)*(y2 - y1);if (den == 0)

return null ;else {

double ua = uaN/den;double ub = ubN/den;double x = x1 + ua*(x2 - x1);double y = y1 + ua*(y2 - y1);

Point p = new Point(x, y);return p; // intersection

}}public void rotate( Point center, double angle ) {

p1.rotate( center, angle );p2.rotate( center, angle );

}public void scale( double factor ) {

double newXsubA = factor * p1.getX();double newYsubA = factor * p1.getY();double newXsubB = factor * p2.getX();double newYsubB = factor * p2.getY();p1.setX( newXsubA );p1.setY( newYsubA );p2.setX( newXsubB );p2.setY( newYsubB );

}}

public class Main {public static void main(String[] args ) {

Point p1 = new Point(10, 10);Point p2 = new Point(11, 11);LineSegment l1 = new LineSegment(p1, p2);LineSegment l2 = new LineSegment(p1, p2);

}}

Figura 4.2: Código das classesPoint , LineSegment eMain do pacotecomponent .

O pacoteaspects contém os aspectos (Figura4.3):

• O aspectoFigureLogging , para o registro na tela dos métodos que são chamados durante

a execução do programa;

Page 87: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 75

• O aspectoPointBoundsChecking , que define limites no plano onde os pontos podem

estar (nesse caso entre 100 e -100 tanto para o eixo das ordenadas quanto para o eixo das

abscissas);

package aspects;

import components.*;

public aspect FigureLogging {declare precedence: FigureLogging,PointBoundsChecking, *;

private int indentationLevel = 0;

public pointcut loggedOperations(): call (* components.*.*(..)) &&

! call (* components.*. get *(..));

before () : loggedOperations() {indentationLevel++;

Signature sig =thisJoinPointStaticPart.getSignature();

if (thisJoinPointStaticPart.getSignature().getDeclaringType().getName()

== "components.LineSegment")PrintIndented("LineSegment <" + sig.getName() +

">");else

if (thisJoinPointStaticPart.getSignature().getDeclaringType().getName()

== "components.Point")PrintIndented("Point <" + sig.getName() + ">");

elsePrintIndented("other <" + sig.getName() + ">");

}

after () returning (): loggedOperations() {indentationLevel--;

}

void PrintIndented(String s) {for ( int i = 0, spaces = indentationLevel * 4;

i < spaces; ++i) {System.out.print(" ");

}System.out.println(s);

}}

public aspect PointBoundsChecking {

pointcut setX( double x):execution ( void Point.setX( double )) && args (x);

pointcut setY( double y):execution ( void Point.setY( double )) && args (y);

pointcut pointConstr( double x, double y):execution (Point. new(..)) && args (x, y);

before ( double x): setX(x) {System.out.println("Checking bounds for x...");if (assertCoord(x) == 0)

throw newIllegalArgumentException("Coordinate x

is out of bounds (< -100)");else if (assertCoord(x) == 1)

throw newIllegalArgumentException("Coordinate x

is out of bounds (> -100)");}

before ( double y): setY(y) {System.out.println("Checking bounds for y...");if (assertCoord(y) == 0)

throw newIllegalArgumentException("Coordinate y

is out of bounds (< -100)");else if (assertCoord(y) == 1)

throw newIllegalArgumentException("Coordinate y

is out of bounds (> -100)");}before ( double x, double y): pointConstr(x, y) {

int xok = 2, yok = 2;System.out.println("Checking bounds for x...");xok = assertCoord(x);yok = assertCoord(y);if (xok == 0) {

if (yok == 0)throw new

IllegalArgumentException("Coordinates x,y are out of bounds" +

" (x < -100, y < -100)");else if (yok == 1)

throw newIllegalArgumentException("Coordinates x,

y are out of bounds" +" (x < -100, y > 100)");

elsethrow new

IllegalArgumentException("Coordinate xis out of bounds" +

" (< -100)");} else if (xok == 1) {

if (yok == 0)throw new

IllegalArgumentException("Coordinates x,y are out of bounds" +

" (x > 100, y < -100)");else if (yok == 1)throw new

IllegalArgumentException("Coordinates x,y are out of bounds" +

" (x > 100, y > 100)");elsethrow new

IllegalArgumentException("Coordinate xis out of bounds" +

" (> 100)");} else {

if (yok == 0)throw new

IllegalArgumentException("Coordinate yis out of bounds" +

" (< -100)");else if (yok == 1)throw new

IllegalArgumentException("Coordinates yis out of bounds" +

" (> 100)");}

}

public int assertCoord( double i) {if ( i < -100)

return 0;if ( i > 100)

return 1;return 2;

}}

Figura 4.3: Código dos aspectosFigureLogging ePointBoundsChecking .

Para a utilização da ferramenta JaBUTi/AJ, é necessário criar um projeto de teste. Para isso o

testador deve, primeiramente, fornecer o nome de uma classe base, ou seja, o nome de uma classe

do tipo aplicação a partir da qual as demais classes relacionadas serão derivadas1.

1Parte desta seção foi retirada/adaptada da tese deVincenzi (2004).

Page 88: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 76

No caso da aplicação para figuras 2D, pode ser escolhida como classe base a classeMain

que constrói pontos e segmentos de reta. Como os aspectos interagem com as classes de ponto e

segmento de reta, eles também são identificados como possíveis integrantes do projeto. Na Figura

4.4 é mostrada a tela do gerenciador de projetos da JaBUTi/AJ, após ter sido escolhida a classe

Main como classe base. A partir daí podem ser selecionadas todas as classes e aspectos a serem

instrumentados e testados.

Figura 4.4: Janela do gerenciador de projetos da JaBUTi/AJ.

JaBUTi/AJ cria então um novo projeto, construindo o grafo Def-Uso orientado a aspectos

(AODU) para cada método de cada classe a ser testada e para cada adendo de cada aspecto a ser

testado. Os requisitos de teste de cada critério são derivados e o peso dos requisitos é calculado. A

partir desse peso, a ferramenta utiliza diferentes cores para destacar os requisitos, para auxiliar o

testador a cobrir os de maior peso. Além disso, para cada requisito, a ferramenta calcula o número

de outros requisitos que seriam cobertos a partir da cobertura daquele requisito, e mostra esse

número juntamente com a cor relacionada.

Inicialmente, a ferramenta apresenta a tela com o bytecode de uma das classes em teste, como

ilustrado na Figura4.5(a). Além da visualização do bytecode, é oferecida ainda a visualização do

grafoAODU de cada método (adendo), conforme ilustrado na Figura4.5(b), e também do código

fonte correspondente ao bytecode, conforme ilustrado na Figura4.5(c) (quando o código fonte

encontra-se disponível).

Uma vez que o conjunto de requisitos de teste de cada critério foi determinado, tais requi-

sitos podem ser utilizados para avaliar a qualidade de um conjunto de teste existente e/ou para

desenvolver novos casos de teste visando a melhorar a cobertura dos requisitos pelo conjunto de

teste. Por exemplo, o testador pode decidir criar um conjunto de teste com base em critérios de

teste funcionais ou mesmo gerar um conjunto de teste sem nenhum método pré-definido e ava-

liar a cobertura desse conjunto de teste em relação a cada um dos critérios de teste estruturais da

ferramenta. Por outro lado, o testador pode visualizar o conjunto de requisitos de teste de cada

Page 89: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 77

(a) Bytecode do aspectoPointBoundsChecking . (b) AODU do métododistance .

(c) Código fonte do aspectoFigureLogging .

Figura 4.5: Telas da JaBUTi/AJ.

critério gerados para cada um dos métodos/adendos das classes/aspectos em teste, verificar quais

deles ainda não foram cobertos por algum caso de teste e então desenvolver um novo caso de teste

que cubra tais requisitos. Nas Figuras4.6(a), 4.6(b)e 4.6(c)são ilustrados os requisitos de teste

do métodoLineSegment.distance gerados pelos critérios Todos-NósC , Todas-ArestasC , e

Todos-UsosC , respectivamente.

Como pode ser observado na Figura4.6, a ferramenta permite ao testador ativar/desativar di-

ferentes combinações de requisitos de teste, bem como marcar um determinado requisito de teste

como não-executável quando não existir um caso de teste capaz de cobri-lo.

Page 90: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 78

(a) Todos-NósC (b) Todas-ArestasC

(c) Todos-UsosC

Figura 4.6: Requisitos de teste do métodoLineSegment.distance gerados pelos critériosTodos-NósC , Todas-ArestasC , e Todos-UsosC .

A partir dos requisitos dos critérios OA o testador pode então criar conjuntos de casos de

teste adequados para os critérios. Por exemplo, no caso do métodoLineSegment.distance ,

para cobrir todos os nós transversais pode ser criado um caso de teste a partir de 3 pontos:

P1 = (0, 1), P2 = (0,−1) e P3 = (4, 3). Cria-se um segmento de reta do pontoP1 ao P2 e

depois calcula-se a distância do pontoP3 à reta que contém o segmento de retaP1P2. Como o as-

pectoFigureLogging define adendos em todas as chamadas a métodos do pacotecomponent

(exceto chamadas aos métodosget ), as execuções dos adendos anteriores e posteriores à chamada

ao métodoPoint.distance são cobertas a partir da execução desse caso de teste. Na Figura

4.7(a)é mostrado o grafoAODU do método após a execução do caso de teste. Os requisitos de

teste cobertos – que são os próprios nós transversais, no caso do critério Todos-NósC – aparecem

no grafo com a cor branca. O caso de teste escrito utilizando o JUnit é mostrado na Figura4.8.

A partir da execução do caso de teste mostrado na Figura4.8, quando se analisa o critério

Todas-ArestasC , nota-se que a aresta transversal(60, 200) não é coberta. Na Figura4.7(b)é mos-

trado oAODU do método com base nesse critério. O nó60 aparece pintado de amarelo pelo

fato da aresta(60, 200) não ter sido coberta. Dessa forma, um conjunto de caso de teste Todas-

ArestasC-adequado poderia incluir o caso de teste anterior e mais um que faça com que a aresta

(60, 200) seja executada. Na Figura4.9é mostrado um caso de teste que exercita tal aresta, que é

o caso em que o segmento de linha para o qual se quer calcular a distância é formado por pontos

coincidentes.

Outra atividade importante no teste de programas OA é o teste dos próprios aspectos e, mais

especificamente, o teste dos adendos isoladamente. Os critérios OA geralmente não são apli-

Page 91: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 79

(a) Todos-NósC (b) Todas-ArestasC

Figura 4.7: GrafosAODU gerados pela ferramenta JaBUTi/AJ baseados nos critériosTodos-NósC e Todas-ArestasC , após a execução do caso de teste.

public void testCoverLineSegmentDistanceCCNodes() {Point p1 = new Point(0, 1);Point p2 = new Point(0, -1);Point p3 = new Point(4, 3);LineSegment l = new LineSegment(p1, p2);

double d = l.distance(p3);

System.out.println(d);

assertEquals(d, 4, .0);}

Figura 4.8: Caso de teste para cobrir os nós transversais do métodoLineSegment.distance .

public void testCoverLineSegmentDistanceNodes0Length() {Point p1 = new Point(0, 0);Point p2 = new Point(0, 0);Point p3 = new Point(4, 3);LineSegment l1 = new LineSegment(p1, p2);

double d = l1.distance(p3);

assertEquals(5, d, .0);}

Figura 4.9: Caso de teste para cobrir a aresta transversal(60, 200) do métodoLineSegment.distance .

cados aos próprios aspectos, já que de maneira geral não existem muitas interações adendo-

adendo. Apesar disso o restante dos critérios geralmente são aplicáveis. Por exemplo, na Figura

4.10 é mostrado o grafoAODU gerado a partir da JaBUTi/AJ do adendo anterior do aspecto

PointBoundsChecking que é aplicado ao conjunto de junçãopointConstr . A partir dos

requisitos gerados para o critério Todos-Nós, por exemplo, poderiam ser criados casos de teste para

cobrir todos os comandos do adendo. Na Figura4.11é mostrado um conjunto de casos de teste

Page 92: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 80

Todos-Nós-adequado escritos no JUnit, para o adendo mostrado anteriormente. Cada caso de teste

testa um dos casos no qual os limites estabelecidos pelo aspecto são extrapolados (por exemplo,

quando a coordenadax do ponto extrapola o limite inferior –< 100 – e a coordenaday extrapola

o limite superior –> 100). É interessante notar que, por sua própria definição, os adendos não po-

dem ser executados em isolamento (pelo menos sem alguma infra-estrutura especial). Dessa forma

os casos de teste para os adendos devem ser aplicados nos pontos de junção afetados por eles. Por

exemplo, no caso do adendo em questão é necessário criar e modificar pontos que extrapolem os

limites para que ele seja sensibilizado e testado.

Figura 4.10:AODU do adendo anterior do aspectoPointBoundsChecking .

4.3.2 Aplicação de Simulação de Telefonia

Este exemplo refere-se a um sistema simples que modela conexões telefônicas para as quais

os interesses de temporização e faturamento são implementados utilizando aspectos. O aspecto

de faturamento depende do aspecto de temporização. O exemplo simula um sistema de telefonia

no qual clientes fazem, aceitam, juntam e concluem ligações de longa distância ou locais. A

arquitetura da aplicação contém três camadas. Os objetos básicos oferecem a funcionalidade para

simular clientes, chamadas e conexões2.

As classes do sistema são:2Parte desta seção e o exemplo demonstrado foram baseados no texto da página mantida porAspectJ Team

(2004): http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/doc/progguide/index.html .

Page 93: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 81

public void testCoverPointBoundsCheckingCheckPointConstrOK() {Point p = new Point(1, 1);

assertEquals(1.0, p.getX(), 0.0);assertEquals(1.0, p.getY(), 0.0);

}

public void testCoverPointBoundsCheckingCheckPointConstrOnlyXLTNodes() {try {

Point p1 = new Point(-101, 0);fail();

} catch (java.lang.IllegalArgumentException e) {}}

public void testCoverPointBoundsCheckingCheckPointConstrOnlyYLTNodes() {try {

Point p1 = new Point(-100, -101);fail();

} catch (java.lang.IllegalArgumentException e) {}}

public void testCoverPointBoundsCheckingCheckPointConstrOnlyYGTNodes() {try {

Point p1 = new Point(100, 101);fail();

} catch (java.lang.IllegalArgumentException e) {}}

public void testCoverPointBoundsCheckingCheckPointConstrOnlyXGTNodes() {try {

Point p1 = new Point(101, 100);fail();

} catch (java.lang.IllegalArgumentException e) {}}

public void testCoverPointBoundsCheckingCheckPointConstrBothLTNodes() {try {

Point p1 = new Point(-101, -101);fail();

} catch (java.lang.IllegalArgumentException e) {}}

public void testCoverPointBoundsCheckingCheckPointConstrBothGTNodes() {try {

Point p1 = new Point(101, 101);fail();

} catch (java.lang.IllegalArgumentException e) {}}

public void testCoverPointBoundsCheckingCheckPointConstrXLTYGTNodes() {try {

Point p1 = new Point(-101, 101);fail();

} catch (java.lang.IllegalArgumentException e) {}}

public void testCoverPointBoundsCheckingCheckPointConstrXGTYLTNodes() {try {

Point p1 = new Point(101, -101);fail();

} catch (java.lang.IllegalArgumentException e) {}}

Figura 4.11: Conjunto de casos de teste Todos-Nós-adequado para o adendo anterior do aspectoPointBoundsChecking .

• Customer , que modela clientes e possui atributos para o nome e o código de área do

cliente;

• a classe abstrataConnection com suas duas classes concretasLocal eLongDistance ,

que modelam conexões locais e de longa distância;

• Call , que modela chamadas;

• Timer , que modela temporizadores.

Os aspectos do sistema são:

Page 94: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 82

• Timing , que implementa o interesse de temporização e se encarrega de medir os tempos

das conexões por cliente, iniciando e parando um temporizador associado a cada conexão;

• Billing , que implementa o interesse de faturamento e se encarrega de declarar que cada

conexão tem um cliente pagador – o cliente que inicia a chamada – e também que as chama-

das locais e de longa distância devem ser cobradas com taxas diferentes;

• TimerLog , que implementa um registro que imprime na tela os horários em que um tem-

porizador inicia e pára.

Na Figura4.12 é apresentado o diagrama de classes UML das classes-base da aplicação de

telefonia. Na Figura4.13é apresentado o código das classes-base e na Figura4.14é apresentado

o código dos aspectos.

Call

+hangUp()

Connection−state

+complete()

+pickUp()

+drop()+merge()

*−areaCode

receiver

caller

+call()

LongDistance Local

Customer

calls

−name

Figura 4.12: Diagrama UML das classes-base da aplicação de telefonia (adaptado da páginamantida porAspectJ Team (2004)).

Chamadas são criadas a partir da classeCall , com um cliente como chamador (caller )

e outro como chamado (receiver ). Se chamado e chamador têm o mesmo código de área,

a chamada é estabelecida a partir de uma conexão local, caso contrário é requerida uma cone-

xão de longa distância. Uma chamada é composta por um número de conexões entre clientes.

Inicialmente existe apenas uma conexão entre o chamador e o chamado, porém outras conexões

podem ser adicionadas se chamadas são juntadas para formarem conferências. A classe de cone-

xão (Connection ) modela os detalhes físicos do estabelecimento de uma conexão entre clien-

tes. Para isso é utilizada uma máquina de estados simples (conexões iniciam como pendentes –

PENDING–, depois são completadas –COMPLETED– e finalmente desligadas –DROPPED).

Para o teste estrutural dessa aplicação, primeiramente poder-se-ia criar um projeto na ferra-

menta JaBUTi/AJ, escolhendo todos os arquivos relevantes, inclusive os aspectos. Como os cri-

térios OA geralmente geram menos requisitos de teste do que os outros critérios (por causa da

Page 95: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 83

public class Customer {private String name;private int areacode;private Vector calls = new Vector();

protected void removeCall(Call c){calls.removeElement(c);

}protected void addCall(Call c){

calls.addElement(c);}public Customer(String name, int areacode) {

this .name = name;this .areacode = areacode;

}public String toString() {

return name + "(" + areacode + ")";}public int getAreacode(){

return areacode;}public boolean localTo(Customer other){

return areacode == other.areacode;}public Call call (Customer receiver) {

Call call = new Call( this , receiver);addCall( call );return call ;

}public void pickup(Call call ) {

call .pickup();addCall( call );

}public void hangup(Call call ) {

call .hangup( this );removeCall( call );

}public void merge(Call call1, Call call2){

call1.merge(call2);removeCall(call2);

}}

public class Call {private Customer caller, receiver;private Vector connections = new Vector();public Call(Customer caller, Customer receiver) {

this .caller = caller;this .receiver = receiver;Connection c;if (receiver.localTo(caller)) {

c = new Local(caller, receiver);} else {

c = new LongDistance(caller, receiver);}connections.addElement(c);

}public void pickup() {

Connection connection =(Connection)connections.lastElement();connection.complete();

}public boolean isConnected(){

return((Connection)connections.lastElement()).getState()

== Connection.COMPLETE;}public void hangup(Customer c) {

for (Enumeration e = connections.elements();e.hasMoreElements();) {((Connection)e.nextElement()).drop();

}}

public boolean includes(Customer c){boolean result = false ;

for (Enumeration e = connections.elements();e.hasMoreElements();) {result = result ||((Connection)e.nextElement()).connects(c);

}return result;

}public void merge(Call other){

for (Enumeration e = other.connections.elements();e.hasMoreElements();){Connection conn = (Connection)e.nextElement();other.connections.removeElement(conn);connections.addElement(conn);

}}

}

abstract class Connection {public static final int PENDING = 0;public static final int COMPLETE = 1;public static final int DROPPED = 2;Customer caller, receiver;private int state = PENDING;Connection(Customer a, Customer b) {

this .caller = a;this .receiver = b;

}public int getState(){

return state;}public Customer getCaller() { return caller; }public Customer getReceiver() { return receiver; }void complete() {

state = COMPLETE;System.out.println("connection completed");

}void drop() {

state = DROPPED;System.out.println("connection dropped");

}public boolean connects(Customer c){

return (caller == c || receiver == c);}

}class Local extends Connection {

Local(Customer a, Customer b) {super (a, b);System.out.println("[new local " +"connection from " + a + " to " + b + "]");

}}class LongDistance extends Connection {

LongDistance(Customer a, Customer b) {super (a, b);System.out.println("[new long distance " + "connection from " + a + " to " + b + "]");

}}class Timer {

long startTime, stopTime;public void start() {

startTime = System.currentTimeMillis();stopTime = startTime;

}public void stop() {

stopTime = System.currentTimeMillis();}public long getTime() {

return stopTime - startTime;}

}

Figura 4.13: Código das classes-base da aplicação de telefonia.

quantidade de interações com aspectos), é interessante que se comece por eles, cobrindo as partes

dos métodos e adendos relacionadas com os aspectos. Neste caso, os módulos interessantes são: a

classeCall e o aspectoTiming , pois eles são afetados por adendos. Na Figura4.15são mos-

trados os elementos requeridos para o critério todos-nós-transversais (All-Nodes-c), para todas as

unidades sendo testadas. A classeCall aparece com cinco requisitos de teste, o que quer dizer

que ela é afetada por adendos em cinco pontos. O aspectoTiming aparece com dois elementos

requeridos. É interessante notar que a informação dada por esse critério é muito valiosa, não só

Page 96: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 84

public aspect Timing {

public long Customer.totalConnectTime = 0;

public long getTotalConnectTime(Customer cust) {return cust.totalConnectTime;

}private Timer Connection.timer = new Timer();public Timer getTimer(Connection conn)

{ return conn.timer; }

after (Connection c): target (c) && call ( voidConnection.complete()) {

getTimer(c).start();}

pointcut endTiming(Connection c): target (c) &&call ( void Connection.drop());

after (Connection c): endTiming(c) {getTimer(c).stop();c.getCaller().totalConnectTime +=

getTimer(c).getTime();c.getReceiver().totalConnectTime +=

getTimer(c).getTime();}

}

public aspect TimerLog {

after (Timer t): target (t) && call (* Timer.start()) {System.err.println("Timer started: " + t.startTime);

}

after (Timer t): target (t) && call (* Timer.stop()) {System.err.println("Timer stopped: " + t.stopTime);

}}

public aspect Billing {declare precedence: Billing, Timing;

public static final long LOCAL_RATE = 3;public static final long LONG_DISTANCE_RATE = 10;

public Customer Connection.payer;public Customer getPayer(Connection conn)

{ return conn.payer; }

after (Customer cust) returning (Connection conn):args (cust, ..) && call (Connection+. new(..)) {conn.payer = cust;

}

public abstract long Connection.callRate();

public long LongDistance.callRate(){ return LONG_DISTANCE_RATE; }

public long Local.callRate(){ return LOCAL_RATE; }

after (Connection conn): Timing.endTiming(conn) {long time =

Timing. aspectOf ().getTimer(conn).getTime();long rate = conn.callRate();long cost = rate * time;getPayer(conn).addCharge(cost);

}

public long Customer.totalCharge = 0;public long getTotalCharge(Customer cust)

{ return cust.totalCharge; }

public void Customer.addCharge( long charge){totalCharge += charge;

}}

Figura 4.14: Código dos aspectos da aplicação de telefonia.

para o testador mas também para o desenvolvedor. Com os elementos requeridos, o testador/desen-

volvedor sabe exatamente em quais classes/aspectos os adendos estão definindo comportamento e

também a quantidade de adendos afetando as classes/aspectos.

Para testar a classeCall a partir do critério todos-nós-transversais, é necessário saber quais

métodos estão sendo afetados pelos adendos. Para isso, o testador pode visualizar tanto o byte-

code quanto o código fonte e observar onde a ferramenta indica que estão os requisitos de teste.

Na Figura4.16é mostrada a tela da ferramenta JaBUTi/AJ com o código fonte da classeCall ,

com os requisitos de teste referentes ao critério todos-nós-transversais destacados no código. Na

verdade, percebe-se que, nesse caso, os elementos requeridos acabam sendo os pontos de junção

afetados pelos adendos. Por exemplo, no caso do construtor deCall , deve haver algum adendo

que define comportamento nas chamadas aos construtores deLongDistance e Local . Isso

pode ser conferido visualizando o grafoAODU do construtor deCall (Figura4.17(a)). Os nós

transversais33 e 68 indicam que um adendo posterior do aspectoBilling afeta aqueles pontos

(esse adendo é responsável por atribuir a fatura pela ligação ao cliente chamador). A partir daí o

critério todos-nós-transversais requer que esses nós sejam cobertos, ou seja, que existam casos de

teste que os exercitem.

Analisando a lógica do construtor deCall , para cobrir os nós transversais são necessários

dois casos de teste: um que realize uma chamada local e outro que realize uma chamada de longa

distância. Como o adendo que atribui a fatura ao cliente chamador deve distinguir entre chamadas

locais e de longa distância, aqui o testador já pode ter evidências de que o aspecto está implemen-

Page 97: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 85

Figura 4.15: Elementos requeridos para o critério todos-nós-transversais para a aplicação detelefonia.

tado corretamente, já que o adendo afeta o ponto onde uma chamada local é criada e também o

ponto onde uma chamada de longa distância é criada. A partir dos dois casos de teste, que testarão

se o método realmente cria uma chamada local quando os clientes possuem o mesmo código de

área e uma chamada de longa distância quando os clientes possuem códigos de área diferentes, é

possível cobrir os dois nós transversais referentes às execuções do adendo para os dois casos.

Quanto ao métodohangup , também afetado por adendos, a lógica é a seguinte: quando a

ligação é concluída, é necessário terminar todas as conexões relacionadas a ela, o que é feito por

meio de um laço. Como o adendo do aspecto de temporização deve parar o temporizador toda

vez que uma conexão é terminada, ele é executado depois de cada chamada ao métododrop .

Já no caso do aspecto de faturamento, este também deve afetar o mesmo ponto, pois cada vez

que uma conexão é terminada, também é necessário calcular o custo da chamada e atribuí-lo à

fatura do cliente chamador. Na figura4.17(b)é mostrado o grafoAODU do métodohangup ,

com as execuções dos adendos representadas pelos nós transversais11 e32. Para cobrir esses nós

transversais é necessário um caso de teste que inicie uma chamada e a termine. Quando o método

hangup é chamado, os adendos são executados no término de cada conexão relacionada com a

chamada.

Page 98: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 86

Figura 4.16: Código-fonte da classeCall com os elementos requeridos do critériotodos-nós-transversais em destaque.

Aqui o testador também pode ter evidências de que os aspectos estão implementados corre-

tamente, e além disso que estão interagindo de forma correta, já que o aspecto de faturamento é

acionado após o aspecto de temporização. Note-se que a precedência dos aspectos é importante

nesse caso, pois se o aspecto de faturamento agisse antes do aspecto de temporização, o sistema

falharia. Esse tipo de defeito faz parte do modelo de defeitos definido porAlexander et al. (2004),

discutido na Seção2.3.5. É importante notar que esse caso evidencia a eficiência da abordagem

proposta neste trabalho, no que diz respeito a auxiliar na descoberta desse tipo de defeito.

O métodopickup , que é utilizado para simular o momento em que o cliente tira o telefone

do ganho e completa a ligação, é afetado pelo adendo posterior do aspectoTiming . Isso é feito

para que o aspecto inicie o temporizador toda vez que uma conexão é completada, por meio do

adendo. Para cobrir o nó transversal é necessário apenas um caso de teste que execute o método,

completando uma ligação e verificando que o temporizador é iniciado.

No caso do aspectoTiming , os dois adendos posteriores que iniciam e terminam o tempo-

rizador são afetados pelos adendos posteriores do aspectoTimerLog , para que seja registrado

o tempo de início e parada do temporizador. Nesses pontos podem ser observadas interações

aspecto-aspecto, pois o aspectoTimerLog afeta o aspectoTiming . Para cobrir os nós trans-

Page 99: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 87

(a) GrafoAODU do construtor da classeCall . (b) GrafoAODU do métodohangup .

Figura 4.17: GrafosAODU de construtor e método da classeCall .

versais é necessário um caso de teste que inicie e termine uma ligação, sensibilizando os adendos

do aspectoTiming que iniciam e terminam o temporizador, e por conseqüência, sensibilizando

também o aspectoTimerLog .

Na Figura4.18 é mostrada a classeTelecomTestCase , escrita utilizando o JUnit e que

contém os casos de teste utilizados no teste da aplicação de telefonia. Os primeiros casos de teste

referem-se aos casos de teste comentados anteriormente, utilizados para cobrir os nós transversais

contidos na aplicação. Os outros casos de teste cobrem o restante dos nós. Em razão da simplici-

dade da aplicação, esse conjunto de casos de teste também é adequado para os outros dois critérios

OA definidos.

public class TelecomTestCase extends TestCase {...public void testCoverCCNodesCallConstrLongDistance() {

Customer jim = new Customer("Jim", 650);Customer mik = new Customer("Mik", 500);Call c1 = new Call(jim, mik);

}public void testCoverCCNodesCallConstrLocal() {

Customer jim = new Customer("Jim", 650);Customer mik = new Customer("Mik", 650);Call c1 = new Call(jim, mik);

}public void testCoverCCNodesCallHangup() {

Customer jim = new Customer("Jim", 650);Customer mik = new Customer("Mik", 650);Call c1 = new Call(jim, mik); c1.hangup(jim);

}public void testCoverCCNodesCallPickup() {

Customer jim = new Customer("Jim", 650);Customer mik = new Customer("Mik", 650);Call c1 = new Call(jim, mik); c1.pickup();

}public void testCoverNodesTimingGetTotalTime() {

Customer jim = new Customer("Jim", 650);

Customer mik = new Customer("Mik", 650);Call c1 = new Call(jim, mik);c1.pickup();wait(2.0);c1.hangup(jim);Timing t = Timing. aspectOf ();System.out.println(t.getTotalConnectTime(jim));

}public void testCoverNodesBillingGetPayer() {

Customer jim = new Customer("Jim", 650);Customer mik = new Customer("Mik", 650);Connection c = new Local(jim, mik);Billing b = Billing. aspectOf ();Customer payer = b.getPayer(c);System.out.println(payer);

}public void testCoverNodesBillingGetRateLocal() {

Customer jim = new Customer("Jim", 650);Customer mik = new Customer("Mik", 650);Connection c = new Local(jim, mik);long l = c.callRate();System.out.println(l);

}}

Figura 4.18: Classe contendo um conjunto de casos de teste para o teste da aplicação de telefonia.

Page 100: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 88

4.4 Exemplo de Fluxo de Dados

Os dois exemplos apresentados anteriormente não exploram os critérios de fluxo de dados de-

finidos neste trabalho, pela simplicidade e tamanho das aplicações. O seguinte exemplo demonstra

o uso do critério Todos-UsosC . A aplicação não tem sentido, apenas ilustra interações de fluxo de

dados que podem ocorrer em uma unidade afetada por aspectos.

Na Figura4.19é mostrado o código do exemplo. A classeAClass é o alvo da atividade de

teste, ela possui um método chamadoaMethod que recebe quatro parâmetros: uma cadeia de

caracteres e três inteiros. O método cria um objeto da classeASecClass e, em alguns pontos,

chama o métodoaSecMethod , que recebe um parâmetro do tipo cadeia de caracteres. O as-

pectoAnAspect possui um adendo posterior que define comportamento toda vez que o método

aSecMethod é chamado e, além disso, obtém o parâmetro cadeia de caracteres que é passado

para esse método. O adendo apenas imprime uma mensagem, mostrando o valor da cadeia de

caracteres que foi passada como parâmetro para o método. Na Figura4.20é mostrado o bytecode

do métodoaMethod .

15 public class AClass {1617 public void aMethod(String s, int x, int y, int z) {1819 String str1 = new String("str1");20 String str2 = new String("str2");21 String str3 = new String("str3");2223 ASecClass asc = new ASecClass();2425 if (x > 0) {26 System.out.println("x > 0");27 s = str1;28 }29 if (y > 0) {30 System.out.println("y > 0");31 asc.aSecMethod(s);32 }33 if (y >= 1)34 if (z > 10)35 s = str2;36 else37 asc.aSecMethod(s);38 for ( int i = 0; i < x; i++) {39 if (z > 1) {40 asc.aSecMethod(s);41 z--;42 } else {43 s = str3;44 }45 }46 asc.aSecMethod(s);47 }48 }4950 public class ASecClass {5152 public int a = 0;53 public int b = 0;5455 public void aSecMethod(String s) {56 System.out.println("A Second Method... " + s);57 }58 }5960 public aspect AnAspect {6162 after (String s) returning () :63 call (* aSecMethod(String))64 && args (s){65 System.out.println("s = " + s);66 }67 }

Figura 4.19: Código fonte da aplicação para ilustração do critério de fluxo de dados.

Page 101: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 89

0 new #20 <Class java.lang.String>3 dup4 ldc #22 <String "str1">6 invokespecial #25 <Method String(java.lang.String)>9 astore 511 new #20 <Class java.lang.String>14 dup15 ldc #27 <String "str2">17 invokespecial #25 <Method String(java.lang.String)>20 astore 622 new #20 <Class java.lang.String>25 dup26 ldc #29 <String "str3">28 invokespecial #25 <Method String(java.lang.String)>31 astore 733 new #31 <Class components.ASecClass>36 dup37 invokespecial #32 <Method ASecClass()>40 astore 842 iload_243 ifle 5746 getstatic #38 <Field java.io.PrintStream

java.lang.System.out>49 ldc #40 <String "x > 0">51 invokevirtual #45 <Method void println(java.lang.String)>54 aload 556 astore_157 iload_358 ifle 8861 getstatic #38 <Field java.io.PrintStream

java.lang.System.out>64 ldc #47 <String "y > 0">66 invokevirtual #45 <Method void println(java.lang.String)>69 aload 871 aload_172 astore 1074 aload 1076 invokevirtual #50 <Method void

aSecMethod(java.lang.String)>79 invokestatic #98 <Method component.AnAspect

component.AnAspect.aspectOf()>82 aload 1084 invokevirtual #101 <Method void

ajc$afterReturning$component_AnAspect$1$7d6a5258(java.lang.String)>

87 nop88 iload_389 iconst_190 if_icmplt 12593 iload 495 bipush 1097 if_icmple 106100 aload 6102 astore_1103 goto 125

106 aload 8108 aload_1109 astore 11111 aload 11113 invokevirtual #50 <Method void

aSecMethod(java.lang.String)>116 invokestatic #98 <Method component.AnAspect

component.AnAspect.aspectOf()>119 aload 11121 invokevirtual #101 <Method void

ajc$afterReturning$component_AnAspect$1$7d6a5258(java.lang.String)>

124 nop125 iconst_0126 istore 9128 goto 168131 iload 4133 iconst_1134 if_icmple 162137 aload 8139 aload_1140 astore 12142 aload 12144 invokevirtual #50 <Method void

aSecMethod(java.lang.String)>147 invokestatic #98 <Method component.AnAspect

component.AnAspect.aspectOf()>150 aload 12152 invokevirtual #101 <Method void

ajc$afterReturning$component_AnAspect$1$7d6a5258(java.lang.String)>

155 nop156 iinc 4 -1159 goto 165162 aload 7164 astore_1165 iinc 9 1168 iload 9170 iload_2171 if_icmplt 131174 aload 8176 aload_1177 astore 13179 aload 13181 invokevirtual #50 <Method void

aSecMethod(java.lang.String)>184 invokestatic #98 <Method component.AnAspect

component.AnAspect.aspectOf()>187 aload 13189 invokevirtual #101 <Method void

ajc$afterReturning$component_AnAspect$1$7d6a5258(java.lang.String)>

192 nop193 return

Figura 4.20: Bytecode do métodoaMethod da classeAClass .

Para o teste dessa aplicação, são abordados apenas os critérios orientados a aspectos definidos

neste trabalho. Inicialmente poder-se-ia analisar o critério mais fraco, passando para os outros

dois mais fortes, em uma atividade de teste incremental. Na Figura4.21 é mostrado o sumário

dos requisitos de teste para os critérios Todos-NósC , Todos-ArestasC e Todos-UsosC , para o mé-

todo aMethod da classeAClass . É importante notar que a maioria dos requisitos de teste do

critério Todos-UsosC referem-se à variávels (identificada porL@1 na ferramenta), pois o adendo

do aspectoAnAspect utiliza essa variável de contexto. Já os requisitos do critério Todos-NósC

indicam o número de pontos onde os adendos do aspectoAnAspect definem comportamento na

classeAClass . Ao utilizar a ferramenta para observar o código da classe pode-se notar esses

pontos, que são as chamadas ao métodoaSecMethod da classeASecClass (Figura4.22). O

grafoAODU do método é mostrado na Figura4.23.

A partir dos requisitos do critério Todos-NósC , observando o código e os pesos atribuídos pela

ferramenta, poderia ser criado um caso de teste para cobrir todos os nós transversais, analisando

as condições contidas no método. Um caso de teste com entradas nas quaisx > 0, y > 0 e

Page 102: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 90

(a) Todos-NósC (b) Todas-ArestasC

(c) Todos-UsosC

Figura 4.21: Requisitos de teste dos critérios Todos-NósC , Todos-ArestasC e Todos-UsosC , parao métodoaMethod da classeAClass .

z > 1, faz com que todos os nós transversais sejam cobertos. Um desses casos de teste poderia

ser (s1, 1, 1, 9), ondes1 é uma cadeia de caracteres qualquer. Observando a ferramenta após a

execução desse caso de teste, percebe-se que o mesmo caso de teste também cobre todas as arestas

transversais e, portanto, um conjunto de teste com apenas esse caso de teste é adequado para ambos

os critérios Todos-NósC e Todas-ArestasC .

Page 103: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 91

Figura 4.22: Código fonte da aplicação exemplo mostrado na ferramenta JaBUTi/AJ, com baseno critério Todos-NósC .

Passando para o critério de fluxo de dados Todos-UsosC , analisando a cobertura a partir da

execução do caso de teste comentado anteriormente, nota-se que 9 dos 17 requisitos de teste (52%)

foram cobertos. A partir daí, os requisitos que sobraram podem ser analisados um a um, para

auxiliar na construção de casos de teste para completar a cobertura.

Analisando a Figura4.24, que mostra o código fonte3 do métodoaMethod com base no

critério Todos-UsosC , podem ser visualizados os pontos onde existem definições de variáveis –

partes vermelhas – que são subseqüentemente usadas em nós transversais (e portanto formam pa-

res Def-Uso que são requisitos do critério em questão). É importante notar que os usos não são

explicitamente aparentes no código fonte, já que são caracterizados a partir do bytecode e nas

partes adicionadas pelo aspecto. Porém, a ferramenta identifica os pontos dos usos geralmente

como sendo os pontos de junção (como acontece nesse exemplo, destacando a chamada ao mé-

todoaSecMethod ). As partes em branco no código fonte indicam definições para as quais todos

os subseqüentes usos foram cobertos pelos casos de teste ativos. Clicando com o botão direito do

mouse sobre um dos pontos onde as variáveis são definidas, o testador pode escolher a variável que

3Para a visualização do código com melhor definição pode ser utilizada a Figura4.20, que utiliza a mesma nume-ração de linhas mostrada na ferramenta.

Page 104: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 92

Figura 4.23:AODU do métodoaMethod da classeAClass .

deseja analisar, e a partir daí a ferramenta mostra os pontos que tal definição pode alcançar, por

meio de um caminho livre de definição. Por exemplo, se o testador clicar sobre a parte vermelha

indicada na figura na linha 19 do código fonte, e escolher a variávels – que é a cadeia de caracteres

passada para o métodoaSecMethod –, a ferramenta indicará todos os usos em nós transversais

que ainda não foram cobertos, utilizando a cor vermelha; e também os que foram cobertos, utili-

zando a cor branca. Na Figura4.25é mostrada a tela da ferramenta, depois do testador completar

esses passos. A mesma funcionalidade pode ser explorada a partir do grafo Def-Uso, clicando nos

nós nos quais existe definição de alguma variável.

A partir dos pares não cobertos, podem ser construídos casos de teste para percorrer caminhos

nos quais as definições alcançam os usos sem passarem por nenhuma outra definição da mesma

variável. Por exemplo, para cobrir o par(s, 0, 61) representado na Figura4.25pelas linhas19–31

do código fonte, é necessário um caso de teste que faça com que a definição des no início do

método alcance o uso na linha31, sem passar pela definição que ocorre na linha27. Para que o

caminho percorrido pelo caso de teste não passe pela linha27, é necessário que a entradax seja

menor do que zero. Sendo assim, um caso de teste formado pela entrada(s1,−1, 1, 9), no quals1

é qualquer cadeia de caracteres, e capaz de cobrir esse par Def-Uso. Além disso, executando esse

mesmo caso de teste e analisando a cobertura na ferramenta, percebe-se que o par representado

pelas linhas19–37 também é coberto, já que a definição no início do método também alcança a

linha 37. Assim, para a definição des no nó inicial doAODU do método, resta apenas o par

representado pelas linhas19–40. Analisando a lógica do método, para cobrir esse par é necessário

Page 105: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 93

Figura 4.24: Código fonte da aplicação exemplo mostrado na ferramenta JaBUTi/AJ, com baseno critério Todos-UsosC .

que a entradax seja maior do que zero, para que o laço que inicia na linha38 seja executado pelo

menos uma vez, alcançando a linha40. Porém, sex > 0, s é redefinida na linha27 e, portanto, a

definição do início do nó não alcança o uso em40. Assim, tem-se que o par(s, 0, 137) representado

no código fonte pelas linhas19–40 não é executável. Os requisitos não-executáveis podem ser

marcados como tais na ferramenta JaBUTi/AJ, para que a cobertura deles seja desprezada.

Depois da construção desses outros dois casos de teste, ainda resta cobrir os usos da variável

s cujas definições encontram-se nos nós100 e 162, representados no código fonte pelas linhas35

e 43. Os pares Def-Uso cujas definições encontram-se no nó100 são(s, 100, 137) e (s, 100, 174).

O primeiro, representado no código fonte pelas linhas35–40, pode ser coberto com um caso de

teste no qual as entradas respeitem as condições:x > 0, para que o laço seja executado pelo

menos uma vez,y ≥ 1 para que a condição em33 seja satisfeita ez > 10, para que a condição

em 35 seja satisfeita. Já o segundo caso de teste pode ser coberto quando as condiçõesx < 0,

y ≥ 1 e z > 10 sejam satisfeitas. A partir daí podem ser construídos dois casos de teste, com as

entradas(s1, 1, 1, 11) e (s1,−1, 1, 11). Após a construção desses casos de teste, resta a cobertura

dos pares(s, 162, 137) e (s, 162, 174) representados pelas linhas43–40 e 43–46, respectivamente.

O primeiro par Def-Uso não é executável, pois as condiçõesz > 1 ez ≤ 1 deveriam ser satisfeitas

Page 106: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 94

Figura 4.25: Código fonte da aplicação exemplo mostrado na ferramenta JaBUTi/AJ, após aseleção da definição da variávels no início do método.

com uma iteração do laço, e comoz decresce a cada iteração, essas condições nunca poderiam

ser satisfeitas de maneira que a definição em46 alcance o uso em43. Já o par representado pelas

linhas43–46 pode ser coberto com um caso de teste no qual as entradas satisfaçam as seguintes

condições:x > 0 e z ≤ 1. A entrada(s1, 1, 1,−1) satisfaz essas condições. Na Figura4.26são

mostrados todos os casos de teste construídos utilizando o framework JUnit.

public void testCoverCCNodes1() {String s1 = new String("");AClass ac = new AClass();ac.aMethod(s1, 1, 1, 9);

}

public void testCoverCCUses19_31() {String s1 = new String("");AClass ac = new AClass();ac.aMethod(s1, -1, 1, 9);

}

public void testCoverCCUses35_40() {String s1 = new String("");AClass ac = new AClass();ac.aMethod(s1, 1, 1, 11);

}

public void testCoverCCUses35_46() {String s1 = new String("");AClass ac = new AClass();ac.aMethod(s1, -1, 1, 11);

}

public void testCoverCCUses43_46() {String s1 = new String("");AClass ac = new AClass();ac.aMethod(s1, 1, 1, -1);

}

Figura 4.26: Casos de teste para a aplicação exemplo.

Page 107: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 4. TESTE DE UNIDADE: AUTOMATIZAÇÃO E EXEMPLOS 95

4.5 Considerações Finais

Neste capítulo foi apresentada uma implementação da abordagem de teste estrutural de unidade

proposta neste trabalho para o teste de programas OA escritos na linguagem AspectJ. A ferramenta

implementada chama-se JaBUTi/AJ por estender a ferramenta JaBUTi, resultado do trabalho de

Vincenzi (2004) para o teste estrutural de programas Java. O capítulo deu enfoque às mudanças da

ferramenta, deixando de lado detalhes já abordados no trabalho deVincenzi (2004). Em particular,

os critérios orientados a aspectos definidos na Seção3.3foram mais enfatizados.

É importante ressaltar também que a ferramenta irá auxiliar em experimentos futuros, para

avaliar a habilidade dos critérios em encontrar erros específicos de programas OA. Além disso, de

maneira geral, uma atividade de teste estrutural de programas OA seria impraticável, se realizada

manualmente, o que mostra a importância da ferramenta.

No próximo capítulo são apresentadas as conclusões finais do trabalho, apresentando as con-

tribuições e os trabalhos futuros a serem realizados.

Page 108: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO

5Conclusão

5.1 Considerações Finais

Neste trabalho foi investigada uma abordagem de teste estrutural baseada em fluxo de controle

e no fluxo de dados para programas orientados a aspectos, adaptando as abordagens existentes para

programas procedimentais e orientados a objetos. O grafo de fluxo foi estendido para contemplar

as peculiaridades existentes no fluxo de controle das unidades dos programas OA em que aspectos

definem comportamento por meio de adendos. Grafo de Fluxo de Controle Orientado a Aspectos

(AOCFG) foi o nome dado ao grafo de fluxo de controle estendido, e grafo Def-Uso Orientado

a Aspectos (AODU) foi o nome dado ao grafo de fluxo de dados estendido. Com base nesses

modelos foram definidos critérios de teste estruturais, entre eles, três específicos para programas

OA: todos-nós-transversais, todas-arestas-transversais e todos-usos-transversais.

Para o teste de integração baseado em fluxo de dados foi concebido o Grafo Def-Uso Método-

Adendo (MADU), que consiste noAODU do método juntamente com osAODUs dos adendos

que definem comportamento no método. A partir desse grafo foi concebido o conceito de pares

Def-Uso aspectuais, com base nos diferentes escopos representados no grafo – escopos de aden-

dos e escopo do próprio método. Critérios de teste baseados no fluxo de dados foram definidos

tomando como base os pares Def-Uso aspectuais.

A abordagem de teste estrutural de unidade foi implementada em um protótipo de ferramenta

estendido da ferramenta JaBUTi, resultado do trabalho deVincenzi (2004). Algumas restrições

podem ser notadas na implementação:

• A ferramenta é restrita à linguagem AspectJ e às versões mais recentes;

96

Page 109: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

CAPÍTULO 5. CONCLUSÃO 97

• Apenas os aspectos do tiposingleton, ou seja, que possuem somente uma instância durante

toda a execução do programa, foram investigados. Porém, os grafos também podem ser

derivados a partir de aplicações que contêm aspectos do tipoper*, mas essas ocorrências

devem ser investigadas com mais profundidade.

5.2 Contribuições

No que diz respeito ao teste de unidade, as contribuições de ordem teórica do trabalho referem-

se a concepção de uma abordagem de teste de unidade, a partir da adaptação dos modelos de

fluxo de controle e de dados e da definição de critérios estruturais baseados nesses modelos. A

contribuição de ordem prática é a extensão da ferramenta JaBUTi em um protótipo de ferramenta

chamado JaBUTi/AJ, que implementa a abordagem de teste de unidade proposta.

No que diz respeito ao teste de integração, algumas considerações teóricas foram feitas, com a

definição do grafoMADU para representar o fluxo de controle e de dados das unidades integradas

com os adendos que as afetam, e com a definição de cinco critérios baseados nesse modelo.

Em suma, este trabalho contribui com uma adaptação da técnica de teste estrutural para pos-

sibilitar o seu uso no teste de programas OA tanto em unidade quanto em integração, porém com

ênfase no teste de unidade.

5.3 Pesquisas Futuras

Outros critérios mais fortes, ou que explorem diferentes propriedades, podem ser investigados

no contexto da POA, tanto para o teste de unidade quanto para o teste de integração. Por exemplo,

os critérios Potenciais-Uso deMaldonado (1991) poderiam ser explorados no contexto de progra-

mas OA. Além disso, pouco foi feito na direção da avaliação dos critérios propostos, tanto no que

se refere ao custo de aplicação quanto ao que se refere à habilidade em encontrar erros. O tra-

balho deAlexander et al. (2004) pode ser explorado nesse sentido, investigando os tipos de erros

específicos de programas OA que podem ser encontrados com o auxílio dos critérios propostos, e

também com a ajuda de estudos de caso maiores e/ou mais complexos e de experimentos.

O teste de integração foi investigado de maneira superficial e pode ser aprofundado em outro

trabalho. Percebe-se um nicho a ser explorado nesse sentido, principalmente no que diz respeito

ao teste baseado em fluxo de dados, explorando as outras fases de teste definidas neste trabalho e

também a implementação de ferramentas automatizadas.

Page 110: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

Referências Bibliográficas

ADRION, W. R.; BRANSTAD, M. A.; CHERNIAVSKY, J. C. Validation, Verification, and Testing

of Computer Software.ACM Comput. Surv., v. 14, n. 2, p. 159–192, 1982.

AGRAWAL , H. Dominators, super blocks, and program coverage. In:Proceedings of the 21st

ACM SIGPLAN-SIGACT symposium on Principles of programming languages, ACM Press, p.

25–34, 1994.

AGRAWAL , H.; ALBERI, J. L.; HORGAN, J. R.; LI , J. J.; LONDON, S.; WONG, W. E.; GHOSH,

S.; WILDE , N. Mining system tests to aid software maintenance.Computer, v. 31, n. 7,

p. 64–73, 1998.

ALEXANDER, R. Aspect-Oriented Programming: the Real Costs?IEEE Software, v. 20, n. 6,

p. 90–93, 2003.

ALEXANDER, R. T.; BIEMAN , J. M. Challenges with aspect-oriented technology. In:Procee-

dings of the ICSE Workshop on Software Quality, Orlando, Florida, USA, 2002a.

ALEXANDER, R. T.; BIEMAN , J. M. Will aspect-oriented programming improve software qua-

lity? In: Proceedings of the 13th International Conference on Software Reliability Engineering

(ISSRE 2002), Annapolis, Maryland, 2002b.

ALEXANDER, R. T.; BIEMAN , J. M.; ANDREWS, A. A. Towards the Systematic Testing of

Aspect-Oriented Programs. Relatório Técnico, Colorado State University, Fort Collins, CO,

2004.

ASPECTJ TEAM Aspectj programming guide. [On-line].

Disponível em http://dev.eclipse.org/viewcvs/indextech.cgi/

~checkout~/aspectj-home/doc/progguide/index.html (Acessado em

21/09/2004)

98

Page 111: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

REFERÊNCIAS BIBLIOGRÁFICAS 99

BANIASSAD, E.; CLARKE , S. Theme: An Approach for Aspect-Oriented Analysis and Design.

In: Proceedings of the 26th International Conference on Software Engineering, IEEE Computer

Society, p. 158–167, 2004.

BECK, K.; GAMMA , E. JUnit cookbook. [On-line].

Disponível emwww.junit.org (Acessado em 27/11/2003)

BECKER, U. D2AL: A design-based aspect language for distribution control. In:Proceedings of

the 12th International Workshop on Aspect-Oriented Programming at ECOOP, Brussels, Bel-

gium, 1998.

BINDER, R. V. Testing Object-Oriented Systems: Models, Patterns, and Tools. 1 ed. Massa-

chusetts: Addison Wesley, 1191 p., 1999.

BODKIN , R. Commercialization of AOSD: The Road Ahead. In:Proceedings of the Workshop

on Commercialization of AOSD Technology, at the 2nd International Conference on Aspect-

Oriented Software Development (AOSD), Boston, Massachussets, USA, 2003.

CAPRETZ, L. F. A brief history of the object-oriented approach.SIGSOFT Softw. Eng. Notes,

v. 28, n. 2, p. 6, 2003.

CLARKE , S.; WALKER , R. J. Towards a standard design language for AOSD. In:Proceedings

of the 1st international conference on Aspect-oriented software development, ACM Press, p.

113–119, 2002.

DIJKSTRA, E. W. A Discipline of Programming. 1 ed. New Jersey – USA: Prentice-Hall, 217

p., 1976.

ELRAD , T.; FILMAN , R. E.; BADER, A. Aspect-oriented programming: Introduction.Commun.

ACM, v. 44, n. 10, p. 29–32, 2001a.

ELRAD , T.; KICZALES, G.; AKSIT, M.; L IEBERHER, K.; OSSHER, H. Discussing Aspects of

AOP. Communications of the ACM, v. 44, n. 10, p. 33–38, 2001b.

FONTOURA, M. The UML Profile for Frameworks Architectures. 1 ed. Addison-Wesley, 352

p., 2002.

FRANKL , P. G.; WEYUKER, E. J. An Applicable Family of Data Flow Testing Criteria. In:

IEEE Transactions on Software Engineering, p. 1483–1498, 1988.

FRANKL , P. G.; WEYUKER, E. J. Testing Software to Detect and Reduce Risk.Journal of

Systems and Software, v. 53, n. 3, p. 275–286, 2000.

HARROLD, M. J. Testing: a roadmap. In:Proceedings of the conference on The future of

Software engineering, ACM Press, p. 61–72, 2000.

Page 112: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

REFERÊNCIAS BIBLIOGRÁFICAS 100

HARROLD, M. J.; ROTHERMEL, G. Performing Dataflow Testing on Classes. In:Proceedings of

the ACM SIGSOFT ’94 Symposium on the Foundations of Software Engineering, New Orleans,

LA, USA: ACM, p. 154–163, 1994.

HARROLD, M. J.; SOFFA, M. L. Interprocedual data flow testing. In:Proceedings of the ACM

SIGSOFT ’89 third symposium on Software testing, analysis, and verification, ACM Press, p.

158–167, 1989.

HILSDALE , E.; HUGUNIN, J. Advice Weaving in AspectJ. In:Proceedings of the 4th Inter-

national Conference on Aspect-oriented software development 2004, Lancaster, UK, p. 26–35,

2004.

HOWDEN, W. E. Functional Program Testing and Analisys. New York: McGraw-Hill, 1987.

HUANG, J. Experience Using AspectJ to Implement Cord. In:Proc. OOPSLA 2000 Workshop

on Advanced Separation of Concerns in Object-Oriented Systems, 2000.

HUTCHINS, M.; FOSTER, H.; GORADIA , T.; OSTRAND, T. Experiments of the effectiveness of

dataflow- and controlflow-based test adequacy criteria. In:Proceedings of the 16th internatio-

nal conference on Software engineering, IEEE Computer Society Press, p. 191–200, 1994.

KARR, D. A.; RODRIGUES, C.; LOYALL , J. P.; SCHANTZ, R. E.; KRISHNAMURTHY, Y.; PYA -

RALI , I.; SCHMIDT, D. C. Application of the QuO Quality-of-Service Framework to a Distri-

buted Video Application. In:Proceedings of the 3rd International Symposium on Distributed

Objects and Applications, 2001.

KERSTEN, M. AspectJ: The Language and Development Tools. [On-line].

Disponível em http://www.parc.com/research/csl/projects/aspectj/

downloads/OOPSLA2002-demo.ppt (Acessado em 06/12/2003)

K ICZALES, G.; HILSDALE , E.; HUGUNIN, J.; KERSTEN, M.; PALM , J.; GRISWOLD, W. G.

An Overview of AspectJ.Lecture Notes in Computer Science, v. 2072, p. 327–355, 2001.

K ICZALES, G.; LAMPING, J.; MENHDHEKAR, A.; MAEDA , C.; LOPES, C.; LOINGTIER, J.-

M.; I RWIN, J. Aspect-Oriented Programming. In: AKSIT, M.; MATSUOKA, S., eds.Procee-

dings European Conference on Object-Oriented Programming, v. 1241, Berlin, Heidelberg, and

New York: Springer-Verlag, p. 220–242, 1997.

LADDAD , R. AspectJ in Action: Practical Aspect-Oriented Programming. 1 ed. Greenwich,

Connecticut – USA: Manning Publications Company, 512 p., 2003.

LEMOS, O. A. L.; MALDONADO , J. C.; MASIERO, P. C. A Contribution to Data Flow Based

Integration Testing of Aspect-Oriented Programs, a ser submetido, 2004a.

Page 113: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

REFERÊNCIAS BIBLIOGRÁFICAS 101

LEMOS, O. A. L.; MALDONADO , J. C.; MASIERO, P. C. Data-flow integration testing criteria

for aspect-oriented programs. In:Anais do 1o Workshop de Desenvolvimento de Software

Orientado a Aspectos (WASP’2004) – realizado em conjunto com o SBES’2004, Brasília, DF,

Brasil, 2004b.

LEMOS, O. A. L.; VINCENZI, A. M. R.; MALDONADO , J. C.; MASIERO, P. C. Teste de uni-

dade de programas orientados a aspectos. In:Anais do 18o Simpósio Brasileiro de Engenharia

de Software (indicado para Best Paper), Brasília, DF, Brasil, p. 55–70, 2004c.

LEMOS, O. A. L.; VINCENZI, A. M. R.; MALDONADO , J. C.; MASIERO, P. C. Unit Testing

of Aspect-Oriented Programs: the Impact of the Underlying Control and Data Flow Models, a

ser submetido, 2004d.

LOPES, C. V. D: A Language Framework for Distributed Programming. Tese de Doutoramento,

College of Computer Science, Northeastern University, Boston, MA, 1997.

MALDONADO , J. C. Critérios potenciais usos: Uma contribuição ao teste estrutural de software.

Tese de Doutoramento, DCA/FEE/UNICAMP, Campinas, SP, 1991.

MALDONADO , J. C.; BARBOSA, E. F.; VINCENZI, A. M. R.; DELAMARO , M. E.; DO ROCIO

SENGER DESOUZA, S.; JINO, M. Teste de Software: Teoria e prática. In:Minicurso – XVII

Simpósio Brasileiro de Engenharia de Software (SBES 2003), Manaus – AM, 2003.

MALDONADO , J. C.; FABBRI , S. C. P. F. Teste de Software. In:DA ROCHA, A. R. C.;

MALDONADO , J. C.; WEBER, K. C., eds.Qualidade de Software – Teoria e Prática, 1 ed, São

Paulo: Prentice Hall, p. 73–84, 2001.

MURPHY, G. C.; WALKER , R. J.; BANIASSAD, E. L. A.; ROBILLARD , M. P.; LAI , A.; KERS-

TEN, M. A. K. Does aspect-oriented programming work?Commun. ACM, v. 44, n. 10,

p. 75–77, 2001.

MYERS, G. J. The Art of Software Testing. 1 ed. New York: Wiley, 177 p., 1979.

NTAFOS, S. C. A Comparison of Some Structural Testing Strategies.IEEE Transactions on

Software Engineering, v. 14, n. 6, p. 868–874, 1988.

PANDE, H.; LANDI , W.; RYDER, B. Interprocedural def-use associations in C programs.IEEE

Transactions on Software Engineering, v. 20, n. 5, p. 385–403, 1994.

PRESSMAN, R. S. Engenharia de Software. 5 ed. Rio de Janeiro: McGraw-Hill, 843 p., 2002.

RAPPS, S.; WEYUKER, E. J. Data flow analysis techniques for test data selection. In:Proc. of

the 6th International Conference on Software Engineering, Tokio, Japan, p. 272–278, 1982.

Page 114: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

REFERÊNCIAS BIBLIOGRÁFICAS 102

RYDER, B. G.; SOFFA, M. L. Influences on the design of exception handling: ACM SIGSOFT

project on the impact of software engineering research on programming language design.SIG-

PLAN Not., v. 38, n. 6, p. 16–22, 2003.

DOS SANTOS DOMINGUES, A. L. Avaliação de Critérios e Ferramentas de Teste para Progra-

mas OO. Dissertação de Mestrado, ICMC-USP, São Carlos - SP, Brasil, 2001.

SINHA , S.; HARROLD, M. J. Analysis of programs with exception-handling constructs. In:

Proceedings of the International Conference on Software Maintenance, Bethesda, MD, p. 348–

357, 1998.

SOMMERVILLE , I. Software engineering. 6 ed. Addison Wesley, 693 p., 2000.

STANDARDS COORDINATING COMITTEE OF THE COMPUTER SOCIETY OF THE IEEE IEEE

Standard Glossary of Software Engineering Terminology. 345 East 47th Street, New York, NY

10017, USA, 1990.

STEIN, D.; HANENBERG, S.; UNLAND , R. A uml-based aspect-oriented design notation for

aspectj. In:Proceedings of the 1st international conference on Aspect-oriented software deve-

lopment, ACM Press, p. 106–112, 2002.

STÖRZER, M.; KRINKE, J.; BREU, S. Trace Analysis for Aspect Application. In:Analysis of

Aspect-Oriented Software (AAOS), Germany, 2003.

V INCENZI, A. M.; WONG, E. W.; DELAMARO , M. E.; SIMÃO , A. S.; MALDONADO , J. C.

JaBUTi – Java Bytecode Understanding and Testing – user’s guide – version 1.0. Relatório

Técnico, ICMC/USP, em preparação, 2004.

V INCENZI, A. M. R. Orientação a objeto: Definição, implementação e análise de recursos de

teste e validação. Tese de Doutoramento, Universidade de São Paulo, 2004.

V INCENZI, A. M. R.; WONG, W. E.; DELAMARO , M. E.; MALDONADO , J. C. JaBUTi:

A Coverage Analysis Tool for Java Programs. In:Sessão de Ferramentas do 17o Simpósio

Brasileiro de Engenharia de Software, Manaus, AM, Brasil, 2003.

WALIGORA , S.; COON, R. Improving the Software Testing Process in NASA’s Software Engi-

neering Laboratory. In:Proceedings of the Twentieth Annual Software Engineering Workshop,

1995.

WALKER , D.; ZDANCEWIC, S.; LIGATTI , J. A theory of aspects. In:Proceedings of the eighth

ACM SIGPLAN international conference on Functional programming, ACM Press, p. 127–139,

2003.

Page 115: Teste de programas orientados a aspectos: uma abordagem ... · gramação orientada a aspectos (POA) foi concebida como uma proposta de resolução desse problema, a partir do uso

REFERÊNCIAS BIBLIOGRÁFICAS 103

WALKER , R. J.; BANIASSAD, E. L. A.; MURPHY, G. C. An initial assessment of aspect-

oriented programming. In:Proceedings of the 21st international conference on Software engi-

neering, IEEE Computer Society Press, p. 120–130, 1999.

WEYUKER, E. J. Thinking formally about testing without a formal specification. In:Proce-

edings of the Formal Approaches to Testing of Software (FATES’02), Brno, Czech Republic:

INRIA Press, p. 1–10, 2002.

X IE, T.; ZHAO, J.; MARINOV, D.; NOTKIN , D. Detecting Redundant Unit Tests for AspectJ

Programs. Relatório Técnico UW-CSE-04-10-03, Department of Computer Science and Engi-

neering, University of Washington, Seattle, WA, 2004.

XU, D.; XU, W.; NYGARD, K. A State-Based Approach to Testing Aspect-Oriented Programs.

Relatório Técnico NDSU-CS-TR04-XU03, Computer Science Department, North Dakota State

University, Fargo, ND, 2004a.

XU, W.; XU, D.; GOEL, V.; NYGARD, K. Aspect flow graph for testing aspect-oriented pro-

grams. In:Proc. of the 8th IASTED International Conference on Software Engineering and

Applications, 2004b.

ZHAO, J. Tool Support for Unit Testing of Aspect-Oriented Software. In:OOPSLA 2002

Workshop on Tools for Aspect-Oriented Software Development, Seattle, WA, 2002.

ZHAO, J. Data-Flow-Based Unit Testing of Aspect-Oriented Programs. In:Proceedings of

the 27th Annual IEEE International Computer Software and Applications Conference, Dallas,

Texas, USA, 2003.

ZHOU, Y.; RICHARDSON, D.; ZIV, H. Towards a practical approach to test aspect-oriented

software. In:Proc. of the 2004 Workshop on Testing Component-based Systems (TECOS 2004),

Net.ObjectiveDays, 2004.

ZHU, H.; HALL , P. A. V.; MAY, J. H. R. Software Unit Test Coverage and Adequacy.Computer

Survey, v. 29, n. 4, p. 367–427, 1997.