RAIDE - Repositório Institucional da UFBA

185
Universidade Federal da Bahia Instituto de Matem´ atica e Estat´ ıstica Programa de P´ os-Gradua¸c˜ ao em Ciˆ encia da Computa¸c˜ ao RAIDE: UMA ABORDAGEM SEMI-AUTOMATIZADA PARA IDENTIFICAC ¸ ˜ AO E REFATORAC ¸ ˜ AO DE TEST SMELLS Railana dos Santos Santana DISSERTAC ¸ ˜ AO DE MESTRADO Salvador Julho de 2020

Transcript of RAIDE - Repositório Institucional da UFBA

Universidade Federal da BahiaInstituto de Matematica e Estatıstica

Programa de Pos-Graduacao em Ciencia da Computacao

RAIDE: UMA ABORDAGEMSEMI-AUTOMATIZADA PARA

IDENTIFICACAO E REFATORACAO DETEST SMELLS

Railana dos Santos Santana

DISSERTACAO DE MESTRADO

SalvadorJulho de 2020

RAILANA DOS SANTOS SANTANA

RAIDE: UMA ABORDAGEM SEMI-AUTOMATIZADA PARAIDENTIFICACAO E REFATORACAO DE TEST SMELLS

Esta Dissertacao de Mestrado foiapresentada ao Programa de Pos-Graduacao em Ciencia da Com-putacao da Universidade Federal daBahia, como requisito parcial paraobtencao do grau de Mestre emCiencia da Computacao.

Orientador: Prof. Dr. Ivan do Carmo MachadoCo-orientadora: Profa. Dra. Larissa Rocha Soares

SalvadorJulho de 2020

Ficha catalográfica elaborada pela Biblioteca Universitária de Ciências e Tecnologias Prof. Omar Catunda, SIBI - UFBA.

 

 

  

S232 Santana, Railana dos Santos

RAIDE: uma abordagem semi-automatizada para Identificação e Refatoração de Test Smells/ Railana dos Santos Santana. – Salvador, 2020.

185 f.

Orientador: Prof. Dr. Ivan do Carmo Machado Co-orientadora: Profa. Dra. Larissa Rocha Soares

Dissertação (Mestrado) – Universidade Federal da Bahia.

Instituto de Matemática e Estatística, 2020.

1. Software - Teste. 2. Java. 3. Computação. I. Machado, Ivan do Carmo. II. Soares, Larissa Rocha. III. Universidade Federal da Bahia. IV. Título.

CDU 004.415.538

“RAIDE: uma abordagem semi-automatizada para Identificação e Refatoração

de Test Smells”

Railana dos Santos Santana

Dissertação apresentada ao Colegiado do Programa de Pós-Graduação em Ciência da Computação na Universidade Federal da Bahia, como requisito parcial para obtenção do Título de Mestre em Ciência da Computação.

Banca Examinadora

_______________________________________________________________

Prof. Dr. Ivan do Carmo Machado (Orientador-UFBA)

_______________________________________________________________

Prof.ª Dr.ª Vânia de Oliveira Neves (UFF)

_______________________________________________________________

Prof. Dr. Pierre-Yves Schobbens (University of Namur)

Aos quatro amores da minha vida: Daniela, Antonio Jose,

Pabline e Jeziel.

AGRADECIMENTOS

Agradeco primeiramente a Deus, pelo Seu amor incondicional que nunca me desamparoue por ter permitido a concretizacao de mais um sonho em minha vida.

Agradeco ao meu querido esposo, Jeziel Lago, que sempre esteve presente, mesmoestando do outro lado do paıs enquanto ainda eramos noivos. Te agradeco por todos osconselhos, por ter me acompanhado, por ter me apoiado e principalmente pelas noitesem claro para me ajudar. Ao teu lado, quero continuar construindo minha carreira etracando novas metas.

Agradeco aos meus pais Daniela e Antonio Jose que tambem se fizeram presentes,pela educacao dada a mim, por ter acreditado e investido no meu sonho e por fazer parteconstante da minha vida! Sou grata a minha irma Pabline, o meu exemplo e a quemtenho muito orgulho. Irma, obrigada por me incentivar e torcer pelas minhas conquistasjunto comigo. Cada dia sem voces parecia uma eternidade e os poucos finais de semanasque passamos juntos a cada mes significaram muito para mim. Agradeco a todos osfamiliares que sempre me recebiam com muita festa e muito amor em todas as visitas aJequie.

Ao professor Ivan Machado, meu muito obrigada! Agradeco pelo conhecimento trans-mitido nas orientacoes, pelas correcoes, pela parceria, pelo voto de confianca dado a mim,e por me inspirar a ser um profissional de excelencia. A minha coorientadora Larissa Ro-cha Soares, agradeco pela sua dedicacao e compromisso em me orientar, gratidao portodas as conversas de motivacao e encorajamento. Voces foram fundamentais para aconstrucao da pessoa e da pesquisadora que sou hoje.

Agradeco aos professores que lecionaram as disciplinas durante o mestrado, os quaiscontribuıram para a minha formacao e aprendizado. Tambem gostaria de expressar meuobrigada aos professores da banca, Vania de Oliveira Neves e Pierre-Yves Schobbens, peladisponibilidade e contribuicoes dadas. Assim como, aos participantes que foram solıcitosem participar do experimento realizado nesta pesquisa.

Agradeco a Hellen Paz e a Fernando Humberto por me receber de forma tao acolhedoraem Salvador e por socorrer as minhas duvidas de Estatıstica.

Sou grata aos meus amigos e companheiros de papers, Tassio Virgınio e Luana Mar-tins, que estiveram juntos durante a construcao da pesquisa e compartilharam algunsdesafios mais de perto. Tambem agradeco meus grandes amigos Sara Mendes Oliveira,Nildo Silva Jr, Franklin Silva, Joselito Mota Jr, Denivan Campos, Brunna Caroline, SamiaCapistrano, Mayka Lima, Tiago Motta e demais colegas do LES e do grupo de pesquisa.

A caminhada do mestrado foi mais facil com voces por perto. Sou grata a todos voces!

vii

Testes de programas podem ser uma maneira muito eficaz para

demonstrar a presenca de erros, mas e irremediavelmente insuficiente

para mostrar a sua ausencia.

—EDSGER DIJKSTRA (1972)

RESUMO

Teste de unidade e um tipo especıfico de teste que lida com as menores unidades dosistema. Ele representa o primeiro teste apos a implementacao do componente. Quandoa implementacao dos testes de unidade nao segue boas praticas, e provavel que anti-padroes sejam introduzidos no codigo. Anti-padroes nos testes, tambem conhecidos comotest smells, sao mas decisoes para projetar e implementar codigo de teste. Os test smellsprejudicam a qualidade do codigo de teste e reduzem a capacidade de os desenvolvedoresinteragirem com o codigo de teste, o que dificulta a compreensao, leitura e, consequen-temente, a manutenibilidade e evolucao do sistema. Uma estrategia para remover testsmells e a refatoracao do codigo de teste. Poucos estudos na literatura oferecem suporteautomatizado para a deteccao e refatoracao de test smells em projetos Java com o fra-mework JUnit. Assim, o presente estudo fornece uma abordagem semi-automatizadapara auxiliar a identificacao de test smells e sugerir refatoracoes para o codigo de testeem projetos que utilizam as tecnologias Java e JUnit. A abordagem proposta e apoiadapela ferramenta RefActorIng test Design Errors (RAIDE), desenvolvida de modointegrado ao Eclipse IDE, para lidar com codigo de teste desenvolvido em Java. ORAIDE oferece suporte a dois test smells : Assertion Roulette e Duplicate Assert. Apesarde existir outras ferramentas capazes de identificar test smells, ate onde sabemos, aindanao ha evidencias de ferramentas que fornecam suporte automatizado a refatoracao detest smells. Alem disso, as ferramentas existentes nao fornecem interfaces amigaveis eintegradas a uma IDE para a identificacao de test smells. Para avaliar como a abordagemproposta pode contribuir com a melhoria na qualidade do codigo de teste, realizamos umestudo experimental. Comparamos nossa ferramenta com o estado da arte e verificamosque o uso da abordagem RAIDE possibilitou a identificacao de test smells de forma maisfacil e rapida. Alem disso, RAIDE tambem se mostrou eficiente na refatoracao de metodosde teste. Como RAIDE e uma ferramenta integrada ao Eclipse IDE, os processos deidentificacao e refatoracao sao mais rapidos e intuitivos em comparacao com o estado daarte e a refatoracao manual,uma vez que com o RAIDE e possıvel realizar a identificacaode test smells e a refatoracao com alguns cliques em apenas alguns segundos.

Palavras-chave: Test Smells. Teste de Unidade. Refatoracao de teste. Teste desoftware automatizado.

xi

ABSTRACT

Unit testing is a specific type of test that deals with the smallest units in the system. Itrepresents the first test after the component is implemented. When the implementation ofunit tests does not follow good practices, anti-patterns are likely to be introduced in thecode. Anti-patterns in tests, also known as test smells, are poor decisions for designingand implementing test code. Test smells impair the quality of the test code and reducethe ability of developers to interact with the test code, making it difficult to understand,read, and, consequently, maintain and evolve the system. One strategy to remove testsmells is to refactor the test code. Few studies in the literature offer automated supportfor the detection and refactoring of test smells in Java projects with the JUnit framework.Therefore, this study provides a semi-automated approach to assist the identification oftest smells and suggest refactorings for the test code in projects using Java and JUnit

technologies. The proposed approach is supported by the RefActorIng test Design

Errors (RAIDE) tool, an Eclipse IDE plugin, to deal with Java test code. RAIDE

supports two test smells, Assertion Roulette and Duplicate Assert. Although there areother tools capable of identifying test smells, as far as we know, there is no evidenceof tools that provide automated support for test smells refactoring. In addition, we areunaware of a user-friendly and IDE-integrated tool to identify test smells. To assesshow the proposed approach can improve the quality of the test code, we carried out anexperimental study. We compared RAIDE with the state-of-the-art tool and found thatwhen using RAIDE, test smells are easier and faster to be identified. Also, RAIDE proved tobe efficient in refactoring test methods. The identification and refactoring processes arefaster and more intuitive compared to the state-of-the-art tool and the manual refactoring.With RAIDE, it is possible to perform test smells identification and refactoring with a fewclicks in a few seconds.

Keywords: Test Smells. Unit Testing. Test Refactoring. Automated Software Tes-ting.

xiii

SUMARIO

Lista de Figuras xix

Lista de Tabelas xxi

Lista de Acronimos xxiii

Capıtulo 1—Introducao 1

1.1 Motivacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.2 Problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.3 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.4 Visao geral da abordagem proposta . . . . . . . . . . . . . . . . . . . . . 51.5 Metodologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.6 Fora de escopo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.7 Estrutura do trabalho . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Capıtulo 2—Referencial Teorico 9

2.1 Qualidade de Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.1.1 Qualidade do processo de software . . . . . . . . . . . . . . . . . . 112.1.2 Qualidade do produto de software . . . . . . . . . . . . . . . . . . 11

2.2 Teste de Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.2.1 Tecnicas de Teste . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.2.2 Nıveis de Teste . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

Teste de Unidade. . . . . . . . . . . . . . . . . . . . . . . . . . . . 15Teste de Integracao. . . . . . . . . . . . . . . . . . . . . . . . . . 16Teste de Validacao/Aceitacao. . . . . . . . . . . . . . . . . . . . . 16Teste de Sistema. . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

2.3 Code Smell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.4 Test Smells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.4.1 Mystery Guest . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.4.2 Resource Optimism . . . . . . . . . . . . . . . . . . . . . . . . . . 222.4.3 Test Run War . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232.4.4 General Fixture . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242.4.5 Eager Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252.4.6 Lazy Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

xv

xvi SUMARIO

2.4.7 Assertion Roulette . . . . . . . . . . . . . . . . . . . . . . . . . . 27

2.4.8 Indirect Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

2.4.9 For Testers Only . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

2.4.10 Sensitive Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

2.4.11 Test Code Duplication . . . . . . . . . . . . . . . . . . . . . . . . 32

2.4.12 Condicional Test Logic . . . . . . . . . . . . . . . . . . . . . . . . 33

2.4.13 Constructor Initialization . . . . . . . . . . . . . . . . . . . . . . 34

2.4.14 Default Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

2.4.15 Duplicate Assert . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

2.4.16 Empty Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

2.4.17 Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . 38

2.4.18 Ignored Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

2.4.19 Magic Number Test . . . . . . . . . . . . . . . . . . . . . . . . . . 40

2.4.20 Redundant Print . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

2.4.21 Redundant Assertion . . . . . . . . . . . . . . . . . . . . . . . . . 42

2.4.22 Sleepy Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

2.4.23 Unknown Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

2.5 Tecnicas de Refatoracao . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

2.6 Sıntese do Capıtulo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

Capıtulo 3—Identificacao e Refatoracao automatizada de smells 47

3.1 Ferramentas para codigo de producao . . . . . . . . . . . . . . . . . . . . 48

PTIDEJ. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

PMD. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

Checkstyle. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

FindBugs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

SonarQube. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

JDeodorant. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

3.2 Ferramentas para codigo de teste . . . . . . . . . . . . . . . . . . . . . . 55

TRex. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

TeReDetect. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

TestLint. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

TestHound. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

OraclePolish. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

TeCReVis. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

Similar Test Method Detector. . . . . . . . . . . . . . . . . . . . . 61

TestQ. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

tsDetect. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

JNose Test. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

3.3 Sıntese do Capıtulo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

SUMARIO xvii

Capıtulo 4—RAIDE 67

4.1 Tecnologias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684.2 Tipos de test smells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 694.3 Desenvolvimento do RAIDE . . . . . . . . . . . . . . . . . . . . . . . . . 694.4 Processos do RAIDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

4.4.1 Deteccao de test smells . . . . . . . . . . . . . . . . . . . . . . . . 71Assertion Roulette (AR). . . . . . . . . . . . . . . . . . . . . . . . 72Duplicate Assert (DA). . . . . . . . . . . . . . . . . . . . . . . . . 73

4.4.2 Refatoracao de test smells . . . . . . . . . . . . . . . . . . . . . . 74Assertion Roulette (AR). . . . . . . . . . . . . . . . . . . . . . . . 74Duplicate Assert (DA). . . . . . . . . . . . . . . . . . . . . . . . . 75

4.5 Exemplo de uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 764.6 Licenca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 804.7 Sıntese do Capıtulo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

Capıtulo 5—Avaliacao Experimental 83

5.1 Questoes de Pesquisa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 845.2 Visao Geral do Experimento . . . . . . . . . . . . . . . . . . . . . . . . . 845.3 Estudo Piloto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 855.4 Participantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 865.5 Material experimental e tarefas . . . . . . . . . . . . . . . . . . . . . . . 885.6 Design e Procedimentos . . . . . . . . . . . . . . . . . . . . . . . . . . . 895.7 Analise dos Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905.8 Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

5.8.1 Deteccao de test smells (QP1) . . . . . . . . . . . . . . . . . . . . 925.8.2 Refatoracao de codigo de teste (QP2) . . . . . . . . . . . . . . . . 93

5.9 Discussoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 965.10 Ameacas a validade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 975.11 Sıntese do Capıtulo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

Capıtulo 6—Consideracoes Finais 99

6.1 Contribuicoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 996.2 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

Apedice A—AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE 111

A.1 Questionario preliminar . . . . . . . . . . . . . . . . . . . . . . . . . . . 111A.2 Protocolo do experimento . . . . . . . . . . . . . . . . . . . . . . . . . . 117A.3 Questionario de feedback . . . . . . . . . . . . . . . . . . . . . . . . . . . 141A.4 Dados coletados: tempo gasto pelos participantes para realizar as tarefas 143A.5 Respostas do Survey . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145A.6 Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

LISTA DE FIGURAS

1.1 Fases da pesquisa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.1 Estrutura do modelo de qualidade. ISO/IEC 25010:2011 . . . . . . . . . 12

3.1 Visualizacao de problemas detectados com PMD no Eclipse IDE - CodeSmell OverrideBothEqualsAndHashcode . . . . . . . . . . . . . . . . . . 49

3.2 Visualizacao de problemas detectados com PMD no Eclipse IDE - CodeSmell LawOfDemeter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

3.3 Problemas detectados com Checkstyle no Eclipse IDE . . . . . . . . . 513.4 Tela inicial do SonarQube com o resultado do projeto. . . . . . . . . . . . 523.5 Detalhamento dos code smells identificados pelo SonarQube. . . . . . . . 533.6 Visao geral do plugin JDeodorant (FOKAEFS et al., 2011) . . . . . . . . 553.7 Visao geral do plugin TRex . . . . . . . . . . . . . . . . . . . . . . . . . . 563.8 Assistente para a visualizacao da refatoracao com TRex . . . . . . . . . . 563.9 Visao geral do TeReDetect . . . . . . . . . . . . . . . . . . . . . . . . . . 573.10 Visao geral do TestHound . . . . . . . . . . . . . . . . . . . . . . . . . . 593.11 TestHound - Relatorio de test smells para o projeto eGit (Greiler; van

Deursen; Storey, 2013) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593.12 TestHound - Relatorio detalhado de test smells para o projeto eGit (Grei-

ler; van Deursen; Storey, 2013) . . . . . . . . . . . . . . . . . . . . . . . 603.13 TeCReVis - Test Coverage Graph (KOOCHAKZADEH; GAROUSI, 2010a) 613.14 TeCReVis - Test Redundancy Graph (KOOCHAKZADEH; GAROUSI,

2010a) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 613.15 Grafico de visualizacao de test smells gerados com TestQ (BREUGEL-

MANS; ROMPAEY, 2008) . . . . . . . . . . . . . . . . . . . . . . . . . . 623.16 Processo para executar a ferramenta Test Smell Detector (tsDetect) 633.17 Captura da tela principal do JNose Test . . . . . . . . . . . . . . . . . . 65

4.1 Principais componentes do RAIDE . . . . . . . . . . . . . . . . . . . . . . 704.2 Processos do plugin RAIDE . . . . . . . . . . . . . . . . . . . . . . . . . . 714.3 Descricao da conversao do array feito pelo metodo MapDuplications() . 764.4 Etapas para executar o RAIDE . . . . . . . . . . . . . . . . . . . . . . . . 784.5 Assertion Roulette (AR) identificado com o plugin RAIDE . . . . . . . . . 794.6 AR refatorado com o plugin RAIDE . . . . . . . . . . . . . . . . . . . . . 794.7 Duplicate Assert (DA) identificado com o plugin RAIDE . . . . . . . . . . 794.8 DA refatorado com o plugin RAIDE . . . . . . . . . . . . . . . . . . . . . 804.9 Licenca do tsDetect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

xix

xx LISTA DE FIGURAS

4.10 Licenca do JDeodorant . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

5.1 Fluxo do experimento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 855.2 Latin Square para o tratamento do experimento . . . . . . . . . . . . . . 905.3 Fluxo do experimento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 915.4 Tempo de deteccao de test smells com as ferramentas RAIDE e tsDetect 935.5 Refatoracao do AR com o RAIDE e com a refatoracao manual . . . . . . . 955.6 Refatoracao do DA com o RAIDE e com a refatoracao manual . . . . . . . 955.7 Media de Tempo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

LISTA DE TABELAS

3.1 Arquivo de saıda tsDetect . . . . . . . . . . . . . . . . . . . . . . . . . 643.2 Retorno da execucao do JNose Test . . . . . . . . . . . . . . . . . . . . 66

5.1 Perfil e experiencia (em anos) dos Participantes . . . . . . . . . . . . . . 875.2 Projetos selecionados para o estudo experimental . . . . . . . . . . . . . 885.3 Estatıstica descritiva do tempo para detectar e localizar os test smells AR

e DA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 925.4 Estatıstica descritiva do tempo para refatorar codigo de teste com AR . . 945.5 Estatıstica descritiva do tempo para refatorar codigo de teste com DA . . 95

A.1 Tempo de realizacao das atividades do experimento . . . . . . . . . . . . 143

xxi

LISTA DE ACRONIMOS

AR Assertion Roulette

AST Abstract Syntax Tree

BAT Business Acceptance Testing

CMMI Capability Maturity Model Integration

DA Duplicate Assert

LOC Lines of Code

MPS.BR Melhoria do Processo de Software Brasileiro

RAIDE RefActorIng test Design Errors

SQuaRE Software product Quality Requirements and Evaluation

tsDetect Test Smell Detector

TTCN-3 Testing and Test Control Notation

UAT User Acceptance Testing

xxiii

Capıtulo

1INTRODUCAO

Uma forma de aprimorar a qualidade do codigo e validar os componentes de um produto etestar as menores partes do sistema. Essa tecnica e denominada teste de unidade, na qualo proposito e isolar cada parte do sistema para certificar que estas estejam funcionandode acordo com sua especificacao (NAIK; TRIPATHY, 2018). Os testes de unidade temsido amplamente utilizados na industria como parte de uma estrategia de garantia dequalidade (ATHANASIOU et al., 2014; TOURE; BADRI; LAMONTAGNE, 2014).

Testes de unidade podem ser elaborados de forma manual, em que os testadores im-plementam casos de teste, individualmente, com base nas especificacoes do sistema, oucom o suporte de ferramentas de automacao de testes, em que estrategias de geracaoautomatizada sao empregadas para a producao (em massa) de casos de teste (normal-mente, tomando como base, alem das especificacoes, dados de entrada e saıdas possıveis eimpossıveis). Ambos sao importantes e se complementam. Entretanto, testar um sistemapode nao ser algo tao trivial.

O caso de teste desenvolvido manualmente nao consegue cobrir tantas porcoes decodigo quanto aqueles desenvolvidos de modo automatizado. Isto se deve ao esforcoexaustivo no processo de criacao de testes manuais (RAMLER; WOLFMAIER, 2006).Por outro lado, embora a automacao de testes consiga gerar grandes quantidades decasos de teste, em tempo e custo relativamente baixos, quando gerados de forma nao-sistematizada, podem resultar em baixa eficacia, i.e., testes incapazes de identificar pro-blemas no codigo.

Para escrever testes de unidade e necessario mais do que apenas entender o codigodo software, o testador precisa ter o conhecimento necessario para criar esses artefatosde maneira bem estruturada. Portanto, pode ser mais desafiador projetar bons casos deteste do que produzir o proprio software (WAZLAWICK, 2013).

Assim, apesar de relevantes, testes automatizados de software apresentam uma seriede dificuldades (e.g., disponibilidade de pessoal para codificar os testes, conhecimentonecessario para escreve-los e mante-los atualizados conforme a evolucao do software) (HI-RAMA, 2012). Alem disso, a qualidade dos testes deve ser tao bem mantida quanto

1

2 INTRODUCAO

a qualidade do codigo dos componentes implementados. Neste contexto, esta pesquisainvestiga a qualidade do codigo dos testes de unidade. Esse capıtulo introduz o tema quesera explorado no decorrer do trabalho. O Capıtulo consiste em seis secoes:

Secao 1.1 relata os fatores que motivaram a investigacao do tema;

Secao 1.2 define o problema abordado nesta pesquisa;

Secao 1.3 descreve o objetivo do trabalho;

Secao 1.4 apresenta uma visao geral da abordagem proposta;

Secao 1.5 descreve os procedimentos metodologicos utilizados nesta pesquisa;

Secao 1.6 discute os aspectos fora de escopo; e

Secao 1.7 apresenta a estrutura deste documento.

1.1 MOTIVACAO

Os testes de software representam um estagio essencial dentro do processo de desen-volvimento de software. Eles sao amplamente utilizados na industria para garantir aqualidade dos produtos de software (ATHANASIOU et al., 2014; TOURE; BADRI; LA-MONTAGNE, 2014). O teste de unidade, por exemplo, e geralmente realizado apos aimplementacao de um modulo ou componente do sistema. Eles sao responsaveis por pri-orizar as menores unidades de projetos de software. Nesse tipo de teste, a descricao dodesign no nıvel do componente e um guia para testar os caminhos de controle, alem deencontrar erros nos modulos (NAIK; TRIPATHY, 2018; ZHU; HALL; MAY, 1997).

Existe uma grande apreensao em relacao a qualidade dos testes de unidade tanto naacademia quanto na industria (PALOMBA; ZAIDMAN; LUCIA, 2018), principalmenteporque os testes fazem parte do processo de garantia da qualidade do software. No en-tanto, estes nao possuem uma camada de verificacao de qualidade acima, i.e., geralmentenao ha testes para os testes, o que dificulta garantir a qualidade dos testes e por con-sequencia, a qualidade do software (GUERRA, 2005). Portanto, levando em consideracaoa importancia dos testes para a validacao das menores unidades, o foco desta pesquisa efornecer estrategias que possibilitam melhorar os testes de unidade e que proporcionembenefıcios para a area.

1.2 PROBLEMA

Apesar da importancia, a criacao de testes de unidade apresenta varias dificuldades.Geralmente, um engenheiro de teste precisa compreender o codigo de producao paraescrever o codigo de teste. Por sua vez, o codigo precisa ser escrito com alta qualidade e co-

1.2 PROBLEMA 3

evoluir com o codigo de producao (YUSIFOgLU; AMANNEJAD; CAN, 2015; GAROUSI;KUCUK, 2018). Alem de sistematico, o processo de teste deve incluir um conjunto deboas praticas. E crucial garantir que o codigo do teste seja claro e compreensıvel, afim de facilitar sua evolucao e permitir sua reproducao (ATHANASIOU et al., 2014;YUSIFOgLU; AMANNEJAD; CAN, 2015).

Semelhantemente ao codigo-fonte de um projeto, testes devem ser bem elaborados,respeitando padroes que facilitem a compreensao e futuras implementacoes. Embora oteste de unidade seja parte essencial de um processo de teste de software, geralmente naoe realizado sistematicamente e isso pode interferir de forma negativa na qualidade dessesartefatos (FANTINATO et al., 2004).

Segundo Fowler (2018), quando um codigo e mal projetado, as correcoes se tornamtarefas custosas, pois se torna arduo compreender onde e necessario modificar o codigo,o que aumenta a probabilidade de um programador introduzir defeitos. Analogamente,o codigo de teste tambem pode incluir anti-padroes devido a fatores limitantes, como aalta complexidade dos sistemas e a constante necessidade de sua evolucao. Tais anti-padroes sao denominados test smells e a sua presenca pode dificultar a manutencao e acompreensao do codigo de teste (DEURSEN et al., 2001; GREILER et al., 2013).

Por exemplo, Empty Test e um tipo de test smell que ocorre quando um metodo deteste nao contem instrucoes executaveis. Como o metodo nao tem corpo, o teste semprepassa. Quando os desenvolvedores introduzem mudancas de quebra de comportamento,um teste vazio nao notifica sobre resultados alternativos (DEURSEN et al., 2001; PE-RUMA et al., 2019). Ja o Test Code Duplication, outro test smell muito comum,consiste em um teste com codigo duplicado, o qual, muitas vezes, requer um alto esforcode manutencao (DEURSEN et al., 2001).

Recentemente, os test smells ganharam importancia no campo de teste de software(BAVOTA et al., 2012; TUFANO et al., 2016; BAVOTA et al., 2015; PALOMBA; ZAID-MAN, 2017; VIRGINIO et al., 2019; PERUMA et al., 2019). Embora Meszaros (2007)e Greiler et al. (2013) propoem boas praticas de teste e diretrizes que possam evitar testsmells, essas praticas nem sempre sao seguidas. Por exemplo, se um projeto ja inclui umgrande conjunto de testes, criar novos testes do zero pode nao ser tao economico. Nessecaso, um processo de inspecao e refatoracao nos testes existentes pode ser empregadopara reduzir ou mesmo corrigir imperfeicoes nos testes.

A deteccao de test smells consiste na inspecao do codigo para verificar a linha ou otrecho de codigo afetado pelo smell. A deteccao e um atividade necessaria para realizara correcao dos test smells atraves da refatoracao. A refatoracao diz respeito ao meca-nismo utilizado para alterar a estrutura do codigo de um software sem modificar o seucomportamento externo, ou seja, uma melhoria do codigo ja escrito. Segundo Fowler(2018), a refatoracao nao e algo simples, requer conhecimento, experiencia, domınio noprojeto e deve ser feita de forma sistematica, buscando evitar que novos defeitos sejamimplementados ao corrigir um problema antigo. Normalmente, o codigo e mantido emexecucao apos cada refatoracao, reduzindo as chances de um sistema ser severamentequebrado durante a reestruturacao (FOWLER, 1999).

Garousi, Kucuk e Felderer (2018) identificaram na literatura algumas ferramentas quedao suporte ao calculo de metricas de teste e identificacao de anti-padroes. Contudo, a

4 INTRODUCAO

maioria das ferramentas existentes para analise de teste nao esta disponıvel.

Dentre as ferramentas existentes disponıveis, o Test Smell Detector (tsDetect)

(PERUMA et al., 2019), por exemplo, identifica 21 test smells no codigo de teste im-plementado com JUnit1. A identificacao e agrupada por classe, isto e, nao informaexplicitamente onde estao os test smells, mas apresenta apenas um indicativo se umadeterminada classe de teste possui ou nao um determinado smell.

Outra ferramenta que identifica automaticamente os test smells e o JNose Test

(VIRGINIO et al., 2019; VIRGINIO et al., 2020b; VIRGINIO et al., 2020a). O JNose

Test fornece suporte a geracao automatizada de metricas de qualidade, dentre elas, da-dos quantitativos de test smells encontrados. Semelhante ao tsDetect, o JNose Test

tambem identifica 21 tipos de test smells no codigo de teste de unidade implementadoem Java com o framework JUnit.

As ferramentas de identificacao tsDetect e JNose Test sao relevantes, principal-mente para coletar dados para pesquisas sobre test smells, mas sao limitadas uma vezque elas se responsabilizam ate a identificacao dos test smells ; a apresentacao dos testsmells identificados nao e clara a ponto de informar onde os test smells estao localizadosno codigo.

Entende-se que para melhorar a qualidade dos testes de unidade, alem de se identificaros test smells e importante prover melhorias para corrigir os test smells. Uma forma demelhorar a qualidade dos testes sob a perspectiva de test smells e atraves da refatoracaodo codigo de teste. Deursen et al. (2001) propoem um catalogo de solucoes de test smellse refatoracoes de teste para remove-los, contudo a remocao e feita de forma manual, oque e propıcio ao erro humano. As evidencias na literatura sobre test smells ainda naoapresentam suporte ferramental para a refatoracao de forma automatizada em projetosJava com suporte ao framework JUnit.

Nesse sentido, o problema investigado neste trabalho pode ser sintetizado da seguinteforma:

A pratica de desenvolver testes de unidade de qualidade e eficientes desem-penha um papel importante no ciclo de vida do software. Contudo, quandotest smells sao inseridos no codigo de teste, torna-se necessario realizar aidentificacao e a refatoracao desses anti-padroes de design para melhorar aqualidade dos testes. Se feitos de forma manual, a identificacao e refatoracaode test smells podem ser atividades dispendiosas e custosas para o projeto.Contudo, ate onde sabemos, nao ha evidencias de ferramentas que viabilizama identificacao explıcita de test smell no codigo fonte Java com o frameworkJUnit, nem refatoracao automatizada de codigo de teste contendo test smells.Dessa forma, a pratica automatizada de identificacao e refatoracao de testsmells pode beneficiar e tornar o processo de manutencao do codigo de testemais pratico e intuitivo.

1Disponıvel em 〈https://junit.org/〉

1.3 OBJETIVO 5

1.3 OBJETIVO

Com base no problema apresentado anteriormente, e possıvel definir o principal obje-tivo desta dissertacao como sendo prover e avaliar uma ferramenta que apresente re-cursos capazes de identificar e refatorar codigo de teste com test smells de modo semi-automatizado. Para alcancar esse objetivo, planejamos:

• Levantar o estado da arte das abordagens propostas para deteccao e refatoracao detest smells ;

• Propor uma ferramenta para identificar e refatorar testes de unidade, sob a pers-pectiva de test smells ; e

• Realizar um estudo empırico para avaliar o uso da ferramenta proposta para iden-tificar e refatorar codigo de teste com test smells.

1.4 VISAO GERAL DA ABORDAGEM PROPOSTA

A identificacao e refatoracao de testes de unidade sob a perspectiva de test smells euma tarefa nao trivial e pode exigir um esforco consideravel. Para resolver esses proble-mas, esta dissertacao propoe o desenvolvimento do RefActorIng test Design Errors

(RAIDE)2, uma ferramenta desenvolvida como plugin do Eclipse IDE3, que busca forne-cer um ambiente para a deteccao automatizada de linhas ou trechos de codigo afetadospor test smells, bem como refatoracao semi-automatizada de test smells em projetosJava, desenvolvidos com o suporte do framework JUnit. Diferente das ferramentas men-cionadas anteriormente, a principal finalidade do RAIDE e mostrar de foma explıcita aostestadores onde os test smells estao sendo inseridos e com isso criar oportunidades paramelhorar o codigo de teste.

No contexto deste trabalho, a ferramenta prove a deteccao e a refatoracao de dois tiposimportantes de smells, Assertion Roulette (AR) e Duplicate Assert (DA). RAIDE auxiliana manutencao dos codigos de teste e, consequentemente, na qualidade do produto final desoftware. Uma abordagem combinada com identificacao e refatoracao de test smells podeapoiar desenvolvedores e testadores em termos de eficiencia e praticidade nas atividadesdiarias.

A ferramenta RAIDE foi avaliada empiricamente atraves de um estudo experimental.O estudo compara o RAIDE com o tsDetect em termos de deteccao de test smells. Japara avaliar o RAIDE em termos de refatoracao, comparamos RAIDE com o metodo derefatoracao tradicional, ou seja, a refatoracao manual, visto que nao ha ferramentasdisponıveis que realizam a refatoracao automatica de test smells em projetos Java.

1.5 METODOLOGIA

O desenvolvimento da pesquisa foi organizado em tres fases principais (Figura 1.1), con-forme descrito a seguir:

2Disponıvel em 〈https://github.com/raideplugin/Plugin-RAIDE〉3Disponıvel em 〈https://www.eclipse.org/〉

6 INTRODUCAO

• Fase 1: Fase destinada a fazer o levantamento conceitual que sera utilizado comobase para o estudo. Ela e composta pela seguinte tarefa:

1. Revisao de literatura: Consiste na busca estruturada por textos relevantesda area de Engenharia de Software que investigam a tematica de qualidadede teste de software, em particular aqueles estudos que discutam conceitos eferramental relacionados a test smells e refatoracao de codigo de teste.

• Fase 2: Nessa fase, os recursos foram direcionados a implementacao de um metodosemi-automatizado para a identificacao e refatoracao dos test smells e todos osartefatos complementares. Essa fase e composta pelas seguintes atividades:

1. Definicao e Especificacao: A principal finalidade da etapa de definicao eespecificacao e a realizacao do levantamento/analise dos requisitos da ferra-menta RAIDE. Assim, o objetivo e agrupar o maior numero de informacoesnecessarias para se ter o controle de todo projeto. Apos a definicao dos requi-sitos da ferramenta, a tarefa seguinte e a especificacao, definicao de recursos eestrutura para a construcao da ferramenta.

2. Codificacao: Essa atividade consistiu na implementacao da ferramenta RAIDE.Esta tarefa pode ser compreendida em atividades menores e sequenciais: (a)interface grafica da ferramenta; (b) deteccao de test smells ; (c) identificacaoda linha ou trecho de codigo com test smell ; e (d) correcao do test smell iden-tificado atraves da refatoracao semi-automatizada.

3. Testes: A ferramenta foi testada apos cada implementacao mencionada naatividade anterior, de forma a garantir o bom funcionamento de cada etapa.

4. Documentacao: Ao disponibilizar uma versao estavel da ferramenta foi cons-truıdo um Website4 para a ferramenta e elaborado o manual do usuario paraauxiliar os usuarios e outros desenvolvedores que desejarem contribuir como projeto. Dessa forma, essa atividade tem como objetivo a elaboracao deartefatos relacionados a documentacao da ferramenta.

• Fase 3: Essa fase visa a realizacao de uma avaliacao empırica da ferramenta pro-posta, a qual foi baseada no estudo de Soares et al. (2018). As etapas dessa faseforam divididas conforme sugerido por Wohlin et al. (2012) e sao descritas a seguir:

1. Definicao do contexto: Atividade responsavel por analisar o experimentoem termos de problema, objetivo e metas.

2. Planejamento: Atividade que diz respeito ao projeto do experimento, ondesao definidos o design do experimento e a instrumentacao, alem de avaliar aspossıveis ameacas.

3. Execucao: Processo no qual e desenvolvido o experimento seguindo o plane-jamento elaborado.

4Disponıvel em 〈https://raideplugin.github.io/RAIDE/〉

1.5 METODOLOGIA 7

Figura 1.1 Fases da pesquisa

8 INTRODUCAO

4. Analise: Os dados que foram coletados na etapa de execucao do experimentosao analisados com suporte estatıstico.

5. Apresentacao e empacotamento: Os resultados do experimento sao apre-sentados e empacotados a fim de disponibiliza-los para a comunidade, atravesde um banco de dados (Apendices A.4 e A.5).

1.6 FORA DE ESCOPO

Esta dissertacao de mestrado visa explorar a identificacao e refatoracao de smells nocodigo de teste com JUnit. A identificacao e correcao de anti-padroes no codigo deproducao, denominada code smells, nao faz parte do escopo desse trabalho, embora suadefinicao seja importante para a compreensao dos test smells.

1.7 ESTRUTURA DO TRABALHO

Esta dissertacao esta organizada em seis capıtulos. Alem da introducao, ora apresentada,contempla os seguintes capıtulos:

• Capıtulo 2: apresenta o referencial teorico utilizado, o qual trata sobre Qualidadede Software, Teste de Software, Code Smells, Test Smells e Tecnicas de Refatoracao;

• Capıtulo 3: discute as principais abordagens automatizadas para analise de anti-padroes que sao apresentadas pela literatura;

• Capıtulo 4: e detalhada a proposta dessa pesquisa, que consiste em uma solucaosemi-automatizada para a identificacao e refatoracao de test smells ;

• Capıtulo 5: aborda o contexto e o planejamento do experimento para avaliacaoda proposta sugerida; e

• Capıtulo 6: conclui o documento com o resumo da dissertacao, as consideracoesfinais e trabalhos futuros.

Capıtulo

2REFERENCIAL TEORICO

Este capıtulo aborda a fundamentacao teorica deste trabalho. Ele apresenta os concei-tos pertinentes a esta dissertacao de mestrado. Assim, esse capıtulo e composto pelasseguintes secoes:

Secao 2.1 introduz a tematica sobre qualidade de software;

Secao 2.2 apresenta definicoes, estrategias e tecnicas de teste de software;

Secao 2.3 apresenta conceitos basicos e termos relacionamos a code smells ;

Secao 2.4 apresenta definicao e termos relacionamos a test smells ;

Secao 2.5 discute sobre refatoracao e as principais tecnicas existentes; e

Secao 2.6 sintetiza o capıtulo.

2.1 QUALIDADE DE SOFTWARE

A utilizacao de software trouxe grandes benefıcios e hoje e considerado um bem funda-mental para sociedade devido, principalmente, a sua integracao a diversas atividades docotidiano (HIRAMA, 2012). Contudo, de acordo com Bartie (2002), os softwares passa-ram a ganhar complexidade e, como consequencia direta, surgiram problemas envolvendoa qualidade.

O termo qualidade pode assumir diversos significados que dependem de fatores edefinicoes pre-estabelecidas. A ISO 9000, por exemplo, define qualidade como o grauem que um conjunto de caracterısticas inerentes preenchem os requisitos (SCHMAUCH,1993). Outra definicao do termo qualidade e apresentado por Crosby (1979) e Gryna

9

10 REFERENCIAL TEORICO

(2001), que a definem como “conformidade com requisitos” e “adequacao para uso”,respectivamente.

Guerra e Colombo (2009) descrevem que o software e um produto complexo, depen-dendo em boa parte da interpretacao das necessidades do usuario, necessitando converteros requisitos dos usuarios nos do produto para o seu desenvolvimento; dessa forma, ne-cessita de tecnicas de verificacao e validacao para todo o ciclo de desenvolvimento doproduto e tecnicas de avaliacao do produto intermediario e final, garantindo que o pro-duto e correto, seguro, entre outros atributos que asseguram a sua qualidade.

Qualidade de software constitui uma area cuja demanda esta crescendo significativa-mente. Os usuarios exigem cada vez mais eficiencia, eficacia, dentre outras caracterısticasde qualidade consideradas importantes para um produto como software (GUERRA; CO-LOMBO, 2009). Contudo, verificar a qualidade de um software nao e trivial. Deixar dese preocupar com qualidade ou nao dar a devida atencao a mesma pode ser consideradoimprudente.

Em 2012, um dos maiores fabricantes norte-americanos de software para o mercado deacoes lutou para se manter no mercado depois que um bug provocou uma perda de US$ 440milhoes em apenas 30 minutos. As acoes da empresa perderam 75% em valor de mercadoem apenas dois dias apos o software defeituoso inundar o mercado com operacoes nao-intencionais. Os algoritmos de negociacao do fabricante comecaram a empurrar negocioserraticos em cerca de 150 acoes diferentes (EHA, 2012). Outro caso de prejuızo causadopela qualidade de software ocorreu entre os anos de 2017 e 2018, onde foram perdidos oequivalente a mais de US$ 500 milhoes em criptomoedas, motivados por bugs em codigos(SEDGWICK, 2018).

De acordo com Bartie (2002), mais de 30% dos projetos sao cancelados antes dasua conclusao, e aproximadamente 70% desses projetos sao entregues com falhas nasfuncionalidades previstas. Alem disso, o custo medio dos projetos de software costumaexceder mais de 180% do que o previsto e os prazos ultrapassam em 200% a definicaoinicial. De acordo com especialistas, bastam tres ou quatro defeitos a cada 1.000 linhas decodigo - ou Lines of Code (LOC) - para que um programa execute de forma inadequada.

Apesar de os modelos aplicados na garantia da qualidade de software atuarem, emespecial, no processo de desenvolvimento, o principal objetivo e garantir um produtofinal que satisfaca as expectativas do cliente, dentro do que foi acordado inicialmente. Noentanto, e difıcil obter um software de qualidade com processos de desenvolvimento frageise deficientes. Portanto, faz-se necessario estabelecer um processo de garantia da qualidadeque foque simultaneamente no produto tecnologico e no processo de desenvolvimentodesse software.

De modo geral, na Engenharia de Software, o termo qualidade pode ser compreendidoem duas dimensoes fundamentais: a qualidade do processo e a qualidade do produto. Deacordo com Bartie (2002), para se atingir a qualidade do produto de software e necessariocontemplar a qualidade do processo de software, pois sao dimensoes complementares enao podem ser analisadas de forma separada. As secoes 2.1.1 e 2.1.2 discutem essas duasdimensoes.

2.1 QUALIDADE DE SOFTWARE 11

2.1.1 Qualidade do processo de software

Processo de software consiste em um conjunto de atividades, metodos, praticas e trans-formacoes que a equipe de desenvolvimento emprega para construir e manter software eseus produtos associados. Especificacao de requisitos, gerencia de configuracao e desen-volvimento de software sao exemplos de processos que podem ser formalizados e docu-mentados para desenvolver um produto (BARTIE, 2002).

A partir da decada de 1990 ate os dias atuais, houve uma grande preocupacao com amodelagem e a melhoria do processo para a producao de software de qualidade, dentro doprazo e com orcamentos confiaveis. Assim, foram propostas algumas normas e modelosdesenvolvidos na busca pela qualidade de processo de software, como descritos a seguir:

• ISO/IEC/IEEE 90003:20181

• ISO/IEC 12207:20172

• ISO/IEC 33001:20153

• Capability Maturity Model Integration (CMMI)4

• Melhoria do Processo de Software Brasileiro (MPS.BR)5

Para estabelecer um processo de garantia da qualidade robusto, e necessario evidenciarsimultaneamente o produto tecnologico e o processo de desenvolvimento desse software.Embora seja compreendido a relevancia das duas dimensoes de qualidade, esse trabalhotem como finalidade explorar particularidade da qualidade do produto de software.

2.1.2 Qualidade do produto de software

Guerra e Colombo (2009) definem qualidade do produto de software como a conformidadea requisitos funcionais declarados explicitamente, padroes de desenvolvimento claramentedocumentados e as caracterısticas implıcitas que sao esperadas de todo software desenvol-vido profissionalmente. Por requisitos explıcitos, pode-se entender requisitos do usuarioou requisitos funcionais; por sua vez, requisitos implıcitos, ou requisitos nao-funcionais,relacionam-se com os atributos de qualidade da aplicacao, por exemplo, com o desempe-nho de execucao do sistema.

A qualidade do produto de software tem o proposito de garantir a qualidade do pro-duto tecnologico gerado durante o ciclo de desenvolvimento. Todas as atividades quetenham por objetivo “estressar” telas e funcionalidades de um sistema informatizadopodem ser categorizadas na dimensao da garantia da qualidade do produto tecnologico(BARTIE, 2002).

1〈https://www.iso.org/standard/74348.html〉2〈https://www.iso.org/standard/63712.html〉3〈https://www.iso.org/standard/54175.html〉4〈https://cmmiinstitute.com〉5〈https://softex.br/mpsbr/〉

12 REFERENCIAL TEORICO

A ISO/IEC 25010:20116 define um modelo de qualidade de produto detalhado, sendouma das normas Software product Quality Requirements and Evaluation (SQuaRE). Eutilizado uma estrutura hierarquica de caracterısticas de qualidade, no qual e descritoo que se espera de um produto de software. Nessa norma sao definidos os conceitos dequalidade em uso e qualidade do produto.

A SQuaRE constitui uma estrutura para garantir que todas as caracterısticas dequalidade sejam consideradas, sendo dividida em tres modelos de qualidade: modelo dequalidade em uso, modelo de qualidade do produto e o modelo de qualidade de dadospresente na ISO/IEC 25012 (ISO, 2008b)7.

De acordo com a ISO/IEC 25010 (2011), a qualidade do produto e categorizada emcaracterısticas e subcaracterısticas, como e mostrado na Figura 2.1.

Figura 2.1 Estrutura do modelo de qualidade. ISO/IEC 25010:2011

O modelo de qualidade em uso define cinco caracterısticas: efetividade, eficiencia,satisfacao, ausencia de risco e cobertura de contexto. A qualidade em uso caracteriza oimpacto que o produto tem sobre o usuario.

O modelo de qualidade do produto aborda as propriedades do produto em oito carac-terısticas: adequabilidade funcional, eficiencia do desempenho, compatibilidade, usabili-dade, confiabilidade, seguranca, portabilidade e manutenibilidade.

Essas caracterısticas estao descritas a seguir:

• Adequabilidade Funcional - Representa o grau em que um produto ou sis-tema forneceu as funcoes que atendem as necessidades anteriormente declaradase implıcitas quando usadas em condicoes especıficas. Sub-caracterısticas: comple-tude funcional, correcao funcional e adequacao funcional.

• Eficiencia de Desempenho - Representa o desempenho em relacao ao numerode recursos usados nas condicoes definidas. Sub-caracterısticas: comportamentotemporal, utilizacao de recursos e capacidade.

6〈https://www.iso.org/standard/35733.html〉7〈https://www.iso.org/standard/35736.html〉

2.1 QUALIDADE DE SOFTWARE 13

• Compatibilidade - Grau de troca de informacoes e/ou execucao das suas funcoesentre os produtos, sistemas ou componentes, enquanto compartilham do mesmoambiente de software e hardware. Sub-caracterısticas: co-existencia e interoperabi-lidade.

• Usabilidade - Grau de uso dos usuarios de um produto ou sistema para alcancarmetas especıficas com eficacia, eficiencia e satisfacao em um contexto especıfico deuso. Sub-caracterısticas: reconhecimento de adequabilidade, aprendizagem, ope-racionalidade, protecao contra erros do usuario, estetica da interface do usuario eacessibilidade.

• Confiabilidade - Grau que durante um perıodo de tempo um produto, sistema oucomponente executa funcoes especıficas sob condicoes especıficas. Sub-caracterısticas:maturidade, disponibilidade, tolerancia a falhas e recuperabilidade.

• Seguranca - Grau para o qual um sistema ou produto protege dados e informacoespara que pessoas/produtos/sistemas tenham o nıvel de acesso e autorizacao dosdados que sejam autorizacao. Sub-caracterısticas: confidencialidade, integridade,nao-repudio, autenticidade e prestacao de contas.

• Manutenibilidade - Grau de eficacia e eficiencia com o qual um produto/sistemapode ser melhorado, corrigido e adaptavel as mudancas nos requisitos e no ambiente.A norma NBR ISO/IEC 9126-18 descreve: “Capacidade do produto de software deser modificado. As modificacoes podem incluir correcoes, melhorias ou adaptacoesdo software devido a mudancas no ambiente e nos seus requisitos ou especificacoesfuncionais.”

• Portabilidade - Grau de eficiencia/eficacia que um sistema pode ser transferido deambiente (hardware, software, ambiente operacional). Sub-caracterısticas: adapta-bilidade, capacidade de ser instalado (instalabilidade) e capacidade para substituir(substitubilidade).

As caracterısticas definidas pelos modelos de qualidade de uso e qualidade de produtosao relevantes para todos os produtos de software e sistemas de computador. As ca-racterısticas e subcaracterısticas fornecem uma terminologia consistente para especificar,medir e avaliar a qualidade do sistema de software. Eles tambem fornecem um conjuntode caracterısticas de qualidade com relacao as quais os requisitos de qualidade declaradospodem ser comparados.

Embora o escopo do modelo de qualidade do produto seja o software e os sistemas decomputador, muitas das caracterısticas tambem sao relevantes para sistemas e servicosmais amplos. A ISO/IEC 25012:20089 contem um modelo para qualidade de dados quee complementar ao modelo ISO/IEC 25010:201110. O escopo dos modelos exclui propri-edades puramente funcionais, mas inclui adequacao funcional.

8〈https://aplicacoes.mds.gov.br/sagirmps/simulacao/sum executivo/pdf/fichatecnica 21.pdf〉9〈https://www.iso.org/standard/35736.html〉

10〈https://www.iso.org/standard/35733.html〉

14 REFERENCIAL TEORICO

O escopo de aplicacao dos modelos de qualidade inclui suporte a especificacao e ava-liacao de software e sistemas de computacao intensivos de software de diferentes perspecti-vas por aqueles associados com sua aquisicao, requisitos, desenvolvimento, uso, avaliacao,suporte, manutencao, controle e garantia de qualidade e auditoria.

Os modelos podem, por exemplo, ser usados por desenvolvedores, adquirentes, equipede controle e garantia de qualidade e avaliadores independentes, particularmente aquelesresponsaveis por especificar e avaliar a qualidade do produto de software. De acordo coma ISO/IEC 25010:201111, as atividades durante o desenvolvimento do produto que podemse beneficiar do uso dos modelos de qualidade incluem:

• identificar software e requisitos do sistema;

• validar a abrangencia de uma definicao de requisitos;

• identificar os objetivos de software e design do sistema;

• identificar os objetivos de software e teste de sistema;

• identificar os criterios de controle de qualidade como parte da garantia de qualidade;

• identificar criterios de aceitacao para um produto de software e/ou sistema de com-putador intensivo de software; e

• estabelecer medidas de caracterısticas de qualidade em apoio a essas atividades.

Esta secao introduziu aspectos inerentes a qualidade de software, em particular no quediz respeito as duas preocupacoes de qualidade que, embora distintas, possuem similarimportancia: qualidade do processo e qualidade do produto, realizando uma enfase naqualidade do produto e suas oito caracterısticas, das quais daremos enfase na questaode manutenibilidade posteriormente, com o advento dos code smells e test smells queveremos ainda neste capıtulo. Uma das etapas para alcancar a qualidade do software ea realizacao de testes. A proxima secao se dedicara a apresentar conceitos fundamentaissobre a area de testes de software.

2.2 TESTE DE SOFTWARE

Testar um software e uma estrategia eficiente para identificar defeitos ainda no processode desenvolvimento e evitar que os usuarios finais se deparem com tais falhas. A finalidadedo teste e definida em Hirama (2012) como um processo em que os aspectos estruturais,logicos e sistemicos do software sao verificados com o objetivo de identificar erros.

Teste e um dos pilares da qualidade de software, e de acordo com Guerra e Colombo(2009) “teste de software e a atividade de executar um software com o objetivo de en-contrar diferencas entre os resultados obtidos e os resultados esperados”. Em outraspalavras, o teste busca por erros no software e por aspectos que nao estao corretos coma descricao da documentacao prescrita.

11〈https://www.iso.org/standard/35733.html〉

2.2 TESTE DE SOFTWARE 15

De acordo com Sommerville (2011), de muitas formas, o teste e um processo individu-alista, e o numero de tipos diferentes de testes varia tanto quanto as diferentes estrategiasde desenvolvimento. Por muitos anos, as unicas defesas contra os erros de programacaoeram um projeto cuidadoso e a inteligencia do programador. Contudo, atualmente exis-tem muitas tecnicas de projeto e recursos que permitem otimizar as revisoes de softwaree reduz a quantidade de erros iniciais inerentes ao codigo. Similarmente, as tecnicase metodos relacionados a testes estao comecando a se agrupar em varias abordagens efilosofias distintas.

Ainda de acordo com Sommerville (2011), o processo de teste tem dois objetivos dis-tintos: i) demonstrar ao desenvolvedor e ao cliente que o software atende a seus requisitos;ii) descobrir situacoes em que o software se comporta de maneira incorreta, indesejavelou de forma diferente das especificacoes.

2.2.1 Tecnicas de Teste

Sommerville (2011) atribui duas categorias principais as tecnicas de teste: (i) abordagemfuncional (“black box” ou “caixa preta”), e (ii) abordagem estrutural (“white box” ou“caixa branca”).

• Funcional (Caixa Preta): nao importa o codigo interno do programa ou a tecno-logia utilizada, o testador visualiza o software como uma caixa preta. O objetivoe considerar somente os dados de entrada e observar os dados de saıda gerados,verificando se estao de acordo com o esperado.

• Estrutural (Caixa Branca): nesta abordagem o testador esta interessado no queacontece dentro do codigo, avalia as funcionalidades internas dos componentes,com base no codigo fonte; e com foco nas estruturas de controle interno e dados, otestador valida os caminhos logicos possıveis.

2.2.2 Nıveis de Teste

A execucao dos testes e realizada durante o ciclo de vida do desenvolvimento do software,considerando-se diferentes estagios (ou nıveis), que podem ser agrupados de acordo como objetivo principal do teste (GRAHAM et al., 2008; MYERS; SANDLER, 2004):

Teste de Unidade. Os testes de unidade priorizam as menores unidades dos projetosde software, que podem ser componentes ou modulos do sistema. Nesse tipo de teste,a descricao de projeto a nıvel de componente e usada como guia, de modo que os ca-minhos de controle sao testados para descobrir erros dentro dos limites do modulo. Acomplexidade relativa dos testes e os erros que revelam sao limitados pelo escopo doteste de unidade. Esse teste tem como princıpio evidenciar o fluxo da logica interna e osdados dentro nos limites do componente e pode ser realizado em paralelo para diversoscomponentes (GRAHAM et al., 2008).

Naik e Tripathy (2018) descrevem o fluxo dos testes de unidade da seguinte forma: osprogramadores testam unidades de softwares individuais, como procedimentos, funcoes,

16 REFERENCIAL TEORICO

metodos ou classes, isoladamente. Depois de garantir que as unidades individuais funcio-nem de forma satisfatoria, os modulos sao montados para construir subsistemas maiores,seguindo as tecnicas de teste de integracao.

Teste de Integracao. As interfaces entre os componentes e as unidades que foramtestadas individualmente no estagio anterior sao testadas de forma integrada. Para re-alizar a integracao, os componentes sao adicionados um a um e, apos cada passo, umteste e necessario (teste incremental), o que permite antecipar a deteccao e a correcao deerros mais rapidamente. A desvantagem e o custo elevado para testar cada componenteadicionado, ja que vai ser necessario um novo teste. Ha duas formas de se realizar o testede integracao: Bottom-up e Top-down. Na primeira os testes comecam na parte maisbasica, como os testes de unidade, ate o nıvel mais alto, como os testes de interface. Nasegunda os testes sao realizados de forma inversa (GRAHAM et al., 2008).

De acordo com Naik e Tripathy (2018), o teste de integracao e realizado em conjuntopor desenvolvedores de software e engenheiros de teste de integracao.

Teste de Validacao/Aceitacao. O usuario e o responsavel pela realizacao deste teste.O proposito e determinar se o sistema esta de acordo com os requisitos do usuario, estandorelacionado com a validacao do mesmo. Os testes de aceitacao podem ser realizadosde duas formas: testes alfa e testes beta. Os primeiros sao realizados nas instalacoesdo desenvolvedor, que observa o funcionamento do sistema a partir da utilizacao dosusuarios, anotando os problemas identificados. Por sua vez os testes beta sao realizadosno ambiente real de trabalho do usuario, que instala o sistema e testa, sem a presenca dodesenvolvedor, o qual registra os problemas encontrados para o envio aos desenvolvedorespara correcao (GRAHAM et al., 2008).

Naik e Tripathy (2018) descrevem os testes de aceitacao quando o cliente realiza suapropria serie de testes. O objetivo do teste de aceitacao e medir a qualidade do produto,em vez de procurar os erros, o que e objetivo do teste do sistema. Uma nocao fundamentalno teste de aceitacao e a expectativa do cliente em relacao ao sistema. Durante o testede aceitacao, o cliente deve ter desenvolvido seus criterios de aceitacao com base em suasproprias expectativas do sistema. Naik e Tripathy (2018) descrevem dois tipos de testesde aceitacao, conforme explicado a seguir:

• Business Acceptance Testing (BAT): E realizado dentro da organizacao de desen-volvimento do fornecedor. A ideia de ter um BAT e garantir que o sistema acabarapor passar no teste de aceitacao do usuario. E um ensaio da User AcceptanceTesting (UAT) nas instalacoes do fornecedor.

• UAT: O teste de aceitacao do usuario e conduzido pelo cliente, para garantir queo sistema satisfaz os criterios de aceitacao contratual, satisfazendo as necessidadesdo usuario;

Teste de Sistema. A realizacao dos testes de sistema conta com uma infraestru-tura mais complexa de hardware (se aproximando do ambiente de producao). Devem

2.3 CODE SMELL 17

concentrar-se mais nos aspectos de performance, seguranca, disponibilidade, instalacao,recuperacao, entre outros. Nesse nıvel de testes, determinados aspectos das funcionalida-des que nao puderam ser testados deverao integrar o planejamento dos testes de sistema,como testes de integracoes com sistemas externos (sem simulacao), testes com disposi-tivos fısicos (hardware), utilitarios externos e operacionalizacao do ambiente tecnologico(BARTIE, 2002).

Naik e Tripathy (2018) afirmam que o teste do sistema e uma fase crıtica em um pro-cesso de desenvolvimento de software devido a necessidade de se cumprir cronogramas deentrega, para descobrir a maioria das falhas e para verificar se as correcoes estao funcio-nando e nao resultaram em novas falhas. O teste do sistema compreende varias atividadesdistintas: criar um plano de teste, projetar um conjunto de testes, preparar ambientes deteste, executar os testes seguindo uma estrategia clara e monitorar o processo de execucaodo teste.

2.3 CODE SMELL

Bad smells podem ser definidos como “sintomas” de algo no software que podem estarfora dos padroes estabelecidos, ou ate mesmo indıcios que possam indicar um problemade qualidade mais profundo. Entao, caso um software apresente bad smells, e importantesubmete-lo a uma analise rigorosa e corrigi-los, caso necessario. Os bad smells podemafetar o sistema de varias formas e em varias etapas do processo de vida do sistema (e.g.,requisitos, design, codigo-fonte, testes, etc.) (ROMPAEY et al., 2007; BOUHOURS;LEBLANC; PERCEBOIS, 2009; GARCIA et al., 2009; OLBRICH; CRUZES; SJØBERG,2010; FEMMER et al., 2014).

O termo code smells foi inicialmente descrito por Kent Beck e Martin Fowler na obraRefactoring (FOWLER, 1999). Nessa obra, e discutido sobre o quanto os bad smells decodigo podem afetar a sua compreensao e legibilidade, alem de prejudicar o processo demanutencao do sistema. Os bad smells de codigo sao definidos como code smells, e elespodem gerar possıveis problemas no futuro.

Os code smells podem apresentar-se no codigo de varias formas. Esses problemassao exacerbados quando o codigo-fonte contem combinacoes de diferentes code smells(ABBES et al., 2011). A seguir sao apresentados os tipos de code smells definidos porFowler (1999):

• Duplicated Code : E o code smell mais comum nos codigos. Ele ocorre quandose tem replicacao de um determinado codigo uma ou mais vezes. Uma alternativapara refatora-lo e extrair o codigo para um local que possa ser acessado pelas partesque irao utilizar.

• Long Method : Sao metodos que acumulam uma grande quantidade de tarefas, oque dificulta sua compreensao. Os programas orientados a objeto que vivem pormais tempo e com qualidade sao aqueles com metodos curtos. Logo, um LongMethod e um grande candidato a refatoracao.

• Large Class: Consiste em uma classe que faz muitas coisas, possui uma grandequantidade de variaveis de instancia. Por exemplo, uma classe com 10 metodos

18 REFERENCIAL TEORICO

grandes pode se tornar uma classe com 10 metodos de um bom tamanho com mais20 metodos pequenos de 2 linhas. A possibilidade de codigos repetidos em classesgrande e maior.

• Long Parameter List : E um code smell que ocorre quando ha uma longa lista deparametros, a qual dificulta a compreensao e a legibilidade. A base da refatoracaodesse smell e substituir o parametro por outras possibilidades, como por exemplo,os dados contidos na propria classe, ou ainda acessar outra classe que contenha osdados que se deseja. O objetivo e passar como parametro somente as informacoesabsolutamente necessarias ao metodo para o seu funcionamento.

• Divergent Change : Uma alteracao divergente e quando uma classe e frequente-mente alterada de diferentes maneiras por diferentes razoes. Esse smell indica anecessidade de particionar as regras de negocio da classe em uma nova classe oumais classes.

• Shotgun Surgery : De certa forma o oposto do smell anterior, a “cirurgia comrifle” e quando e necessario alterar varias classes para realizar uma mudanca damesma. Se o desenvolvedor nao consegue fazer as alteracoes de forma eficiente, ebem provavel que defeitos sejam inseridos de forma equivocada.

• Feature Envy : Esse smell ocorre quando um metodo esta mais interessado emdados de outras classes do que dados da classe a qual pertence. Para correcao, esugerido mover esse metodo para o qual ele mais se interessa.

• Data Clumps : Ocorre quando ha um conjuntos de dados que sempre aparecemjuntos e nao pertencem a mesma classe, mas acabam sendo dependentes uns dosoutros. Nesse caso, uma alternativa e realizar uma refatoracao, ou ate mesmo criaruma classe com esses dados.

• Primitive Obsession : A maioria dos ambientes de programacao tem dois tiposde dados: os tipos registros e os tipos primitivos. Os primitivos sao os blocos deconstrucao dos tipos registros. A ideia aqui e utilizar as possibilidades de criar seusproprios tipos registros, especializando os dados em classes apropriadas para tal. Ecomo base, utilizar os tipos primitivos para estruturar seus registros.

• Switch Statements : O problema principal do switch sao os codigos duplicados,normalmente os comandos switch(case) ficam espalhados pelo codigo, e quando enecessario realizar alguma alteracao, como por exemplo uma nova opcao de umenum, se torna necessario alterar em todos os switch que precisem desse novo fluxo.Uma forma de refatorar e utilizando polimorfismo para substituir o switch.

• Parallel Inheritance Hierarchies : Cada vez que for necessario criar uma sub-classe de uma classe, tem que criar uma subclasse de outra. Nesse caso as classessao de certa forma dependentes. E um caso especial de Shotgun Surgery.

2.3 CODE SMELL 19

• Lazy Class: E uma classe que nao esta realizando muitas tarefas, de modo quenao necessariamente deveria ser uma classe, e seus metodos poderiam estar melhoralocados em outros locais. Nesse caso, essa classe torna-se desnecessaria.

• Speculative Generality : Ocorre quando um codigo e desenvolvido especulandosua necessidade em um futuro proximo (ou nao). Esse tipo de smell e de facildeteccao, pois ocorre comumente em classes de testes. Esse smell dificulta a le-gibilidade do codigo, ja que o mesmo nao esta sendo utilizado em producao. Suarefatoracao e simples, basta apagar a classe do projeto e a classe de teste corres-pondente, ja que ambas nao tem relevancia.

• Temporary Field : Por padrao, os atributos em um objeto devem ter significadoe objetivo. Assim, quando ha um atributo em sua presenca que nao e justificado,trata-se de um smell. Atributos temporarios dificultam o entendimento da classee a logica por tras dela. E comum que atributos temporarios sejam criados parauso em um algoritmo que requer uma grande quantidade de entradas. Em vez decriar um grande numero de parametros no metodo, o desenvolvedor decide criaratributos para esses dados na classe. Contudo, esses atributos sao usados apenasno algoritmo e permanecem sem uso o resto do tempo.

• Message Chains: Quando temos uma cadeia de requisicoes (metodos getThis)em cadeia, um objeto chama outro objeto, que por sua vez, chama outro objetoe assim por diante. Se for necessario alterar um metodo pai, todas as requisicoesfilhas tambem terao que ser alteradas. Alem disso, esse tipo de smell dificulta amanutencao e a legibilidade das regras de negocio vinculadas a essa cadeia.

• Middle Man : Ocorre quando uma classe tem em sua maioria metodos que redire-cionam as requisicoes para metodos de outras classes, transformando a classe atualem uma fachada. Essa delegacao dificulta o entendimento do codigo, obrigando odesenvolvedor a navegar nas classes para entender o seu funcionamento.

• Inappropriate Intimacy : Esse tipo de code smell ocorre quando classes saointimamente ligadas, como por exemplo classes filhas com acesso a propriedadesdas classes pais. Esse tipo de smell diminui a coesao das classes e o controle dassuas propriedades.

• Alternative Classes with Different Interfaces : Sao metodos que se propoema fazer a mesma coisa, porem possuem assinaturas distintas. Esse smell podeocorrer na mesma classe ou em classes distintas.

• Incomplete Library Class : A reutilizacao e comumente indicada como mo-tivacao para o uso dos conceitos de orientacao a objetos. O problema desse smelle que muitas vezes e ruim, e normalmente impossıvel, modificar uma biblioteca declasses para realizar algo que gostarıamos que ele fizesse.

• Data Class: Sao classes que sao formadas, em sua maioria, por atributos emetodos de acesso e alteracao desses atributos (getters e setters). Para Fowler

20 REFERENCIAL TEORICO

(1999) “Classes de dados sao como criancas. Elas sao boas como ponto de partida,mas para participarem como metodos maduros, precisam adquirir um pouco deresponsabilidade”. Ou seja, as classes tambem devem conter metodos da sua regrade negocio.

• Refused Bequest : Se uma subclasse nao faz uso dos metodos que a super classeapresenta, e bem provavel que a super classe tenha metodos desnecessarios. Essemetodos podem ser utilizados somente por uma subclasse das varias que herdam dasuperclasse. Faz-se necessario deslocar esse metodos para a subclasse que os utiliza.Uma boa pratica e desenvolver superclasses que contenham somente os metodosque sao comuns a todas as subclasses.

• Comments : Comentarios nao sao considerados ruins ao codigo. Contudo, quandoestes sao utilizados como “muletas” para codigos mal feitos, podem se tornar umsmell para o codigo.

Embora Fowler (1999) apresente um catalogo de refatoracao, a refatoracao dos codesmells e vista de forma subjetiva. Contudo, pesquisas mais recentes apresentam novasestrategias com a participacao de ferramental de apoio com suporte a deteccao automaticade code smells no codigo-fonte (FOKAEFS; TSANTALIS; CHATZIGEORGIOU, 2007;MAZINANIAN et al., 2016; PALOMBA et al., 2018). Segundo Fokaefs, Tsantalis eChatzigeorgiou (2007), uma ferramenta pode facilitar o processo de deteccao e tende amelhorar o codigo gerado e, por consequencia, a qualidade do sistema.

2.4 TEST SMELLS

De acordo com Deursen et al. (2001), os smells nao se limitam ao codigo-fonte deproducao, mas tambem podem prejudicar os codigos de testes. Os test smells sao masdecisoes para projetar ou implementar o codigo de teste (GREILER et al., 2013). Apresenca de smells no codigo de teste pode afetar a qualidade do codigo, principalmenterelacionada a compreensao e legibilidade do teste. Consequentemente, os test smells po-dem reduzir a eficacia dos testes na deteccao de falhas e a capacidade dos desenvolvedoresde interagir com o codigo de teste (YUSIFOgLU; AMANNEJAD; CAN, 2015; GAROUSI;KUCUK, 2018).

Os test smells podem aparecer no codigo de teste de varias maneiras. Deursen etal. (2001) apresentaram um conjunto inicial de 11 test smells : Mystery Guest, ResourceOptimism, Test Run War, General Fixture, Eager Test, Lazy Test, Assertion Roulette,Indirect Testing, For Testers Only, Sensitive Equality, e Test Code Duplication.

Mais recentemente, Peruma et al. (2019) propuseram outros 12 tipos de test smells :Conditional Test Logic, Constructor Initialisation, Default Test, Duplicate Assert, EmptyTest, Exception Handling, Ignored Test, Magic Number Test, Redundant Assertion, Re-dundant Print, Sleepy Test e Unknown Test. As proximas subsecoes abordarao os tiposde test smells definidos na literatura por Deursen et al. (2001) e Peruma et al. (2019).

Alguns exemplos de codigo com test smell apresentados nas proximas subsecoes foramrecortados de projetos reais, os quais sao mencionados. Outros exemplos de codigo com

2.4 TEST SMELLS 21

test smells e todos os codigos refatorados foram elaborados exclusivamente para estadissertacao de mestrado, com a finalidade de melhor explicar o processo de identificacaoe refatoracao.

2.4.1 Mystery Guest

O test smell Mystery Guest ocorre quando utiliza-se recursos externos como diretorios,bancos de dados, entre outros.

Exemplo: O Codigo 2.1 apresenta um metodo de teste contendo Mystery Guest (li-nhas 2, 7 e 8). O exemplo apresenta um metodo da classe de teste SystemStateTest.javado projeto Battery Logger12.

1 public void testPersistence() throws Exception {

2 File tempFile = File.createTempFile("systemstate-", ".txt");

3 try {

4 SystemState a = new SystemState(then, 27, false, bootTimestamp);

5 a.addInstalledApp("a.b.c", "ABC", "1.2.3");

6

7 a.writeToFile(tempFile);

8 SystemState b = SystemState.readFromFile(tempFile);

9

10 assertEquals(a, b);

11 } finally {

12 //noinspection ConstantConditions

13 if (tempFile != null) {

14 //noinspection ResultOfMethodCallIgnored

15 tempFile.delete();

16 }

17 }

18 }

Codigo 2.1 Exemplo - Mystery Guest

Possıvel efeito: Dificulta a compreensao do teste devido a valores desconhecidos,e ainda, o uso de recursos externos pode ocasionar dependencias ocultas, ou seja, se oarquivo for modificado ou excluıdo os testes comecam a falhar.

Deteccao: Verificar se o teste depende de informacoes externas como diretorios ebancos de dados.

Refatoracao: Uma forma de eliminar esse test smell e removendo a dependenciaentre um metodo de teste e algum recurso externo, de forma que o recurso seja incor-porado ao codigo de teste (Refatoracao Inline Resource). Caso seja necessario o usode recursos externos, e importante verificar se o teste que os utiliza cria ou aloca taisrecursos explicitamente antes do testes e os libera ao final (Refatoracao Setup ExternalResource). O Codigo 2.2 mostra uma possıvel refatoracao para o exemplo do codigoanterior utilizando Setup External Resource .

12Disponıvel em 〈https://github.com/walles/batterylogger〉

22 REFERENCIAL TEORICO

1 File tempFile = null;

2

3 @Before

4 public void setUp() {

5 tempFile = File.createTempFile("systemstate-", ".txt");

6 if (!tempFile.exists()) {

7 throw new FileNotFoundException("tempFile not created yet.");

8 }

9 }

10

11 @Test

12 public void testPersistence() {

13 SystemState a = new SystemState(then, 27, false, bootTimestamp);

14 a.addInstalledApp("a.b.c", "ABC", "1.2.3");

15

16 a.writeToFile(tempFile);

17 SystemState b = SystemState.readFromFile(tempFile);

18

19 assertEquals(a, b);

20 }

21

22 @After

23 public void after() {

24 if (tempFile != null) {

25 tempFile.delete();

26 }

27 }

Codigo 2.2 Exemplo - Mystery Guest Refatorado

2.4.2 Resource Optimism

O test smell Resource Optimism ocorre quando um teste faz suposicoes sobre o estado/e-xistencia de recursos externos, sem verifica-lo.

Exemplo: O Codigo 2.3 apresenta um metodo que utiliza a classe File mas naoverifica o arquivo antes de ser utilizado (linha 5). Esse trecho de codigo pertence a classede teste LoggingTest.java do projeto Gadgetbridge13.

1 @Test

2 public void saveImage_noImageFile_ko() throws IOException {

3 File outputFile = File.createTempFile("prefix", "png", new File("/tmp"));

4

5 ProductImage image = new ProductImage("01010101010101", ProductImageField.FRONT, outputFile);

6

7 Response response = serviceWrite.saveImage(image.getCode(), image.getField(), image.getImguploadFront

↪→ (), image.getImguploadIngredients(), image.getImguploadNutrition()).execute();

8

9 assertTrue(response.isSuccess());

10 assertThatJson(response.body()).node("status").isEqualTo("status not ok");

11 }

Codigo 2.3 Exemplo - Resource Optimism

Possıvel efeito: Resultado nao determinıstico dependendo do estado dos recursos.Deteccao: Se um teste utiliza uma instancia de uma classe File sem chamar os

metodos exists(), isFile() ou notExists() do objeto, ha grande chances de apresen-tar um test smell em sua estrutura.

13Disponıvel em 〈https://github.com/Freeyourgadget/Gadgetbridge〉

2.4 TEST SMELLS 23

Refatoracao: incluir uma verificacao antes de usar uma instancia externa, ou aloca-la explicitamente (Refatoracao Setup External Resource). Uma possıvel forma decorrigir esse smell e apresentada no Codigo 2.4.

1 File outputFile = null;

2

3 @Before

4 public void setUp() {

5 outputFile = File.createTempFile("prefix", "png", new File("/tmp"));

6 if (!outputFile.exists()) {

7 throw new FileNotFoundException("outputFile not created yet.");

8 }

9 }

10

11 @Test

12 public void saveImage_noImageFile_ko() throws IOException {

13 ProductImage image = new ProductImage("01010101010101", ProductImageField.FRONT, outputFile);

14

15 Response response = serviceWrite.saveImage(image.getCode(), image.getField(), image.getImguploadFront

↪→ (), image.getImguploadIngredients(), image.getImguploadNutrition()).execute();

16

17 assertTrue(response.isSuccess());

18 assertThatJson(response.body()).node("status").isEqualTo("status not ok");

19 }

Codigo 2.4 Exemplo - Resource Optimism Refatorado

2.4.3 Test Run War

O test smell Test Run War ocorre quando um metodo de teste aloca recursos (porexemplo, arquivos tmp) tambem usados por outros testes.

Exemplo: O Codigo 2.5 apresenta os metodos de teste testReadImageFromCache etestDeleteImageFromCache que utilizam o mesmo recurso, a imagem product.png (li-nhas 5 e 13).

1 @Test

2 public void testReadImageFromCache() {

3 Image expectedImage = new Image(readBitmapFromAssets(PRODUCT_IMG));

4

5 Image image = cache.readImage("product.png");

6

7 assertEquals("Read image from cache", expectedImage, image);

8 }

9

10 @Test

11 public void testDeleteImageFromCache() {

12

13 boolean deleteSuccess = cache.deleteImage("product.png");

14

15 assertTrue(deleteSuccess);

16 }

Codigo 2.5 Exemplo - Test Run War

Possıvel efeito: Falhas ocorrem quando varios testes sao executados simultanea-mente, devido a interferencia de recursos.

Deteccao: Identificar se o teste utiliza recursos externos e se tais recursos sao usadospor outros.

24 REFERENCIAL TEORICO

Refatoracao: Uma solucao e tornar o recurso exclusivo (Refatoracao Make Re-source Unique). O Codigo 2.6 mostra uma possıvel solucao de refatoracao para o testsmell Test Run War.

1 @Test

2 public void testReadImageFromCache() {

3 Image expectedImage = new Image(readBitmapFromAssets(PRODUCT_IMG));

4

5 Image image = cache.readImage("productTestReadImageFromCache.png");

6

7 assertEquals("Read image from cache", expectedImage, image);

8 }

9

10 @Test

11 public void testDeleteImageFromCache() {

12

13 boolean deleteSuccess = cache.deleteImage("productTestDeleteImageFromCache.png");

14

15 assertTrue(deleteSuccess);

16 }

Codigo 2.6 Exemplo - Test Run War Refatorado

2.4.4 General Fixture

Um test fixture tem o papel de configurar um sistema para o processo de teste de software,inicializando-o, satisfazendo assim todas as condicoes previas que o sistema possa ter.Contudo, quando o test fixture do teste e muito generico ocorre o test smell GeneralFixture. Com a presenca de General Fixture, os metodos de teste que serao executadosso acessam uma parte dele, i.e., contem atributos nao usados por todos os comandos deteste.

Exemplo: O Codigo 2.7 mostra um exemplo de General Fixture. Ao todo, no metodosetUp() foram inicializadas 6 variaveis (linhas 2, 3, 5, 6, 7 e 9). Contudo, o metodo deteste testIsCA() testa apenas 4 variaveis (linhas 13, 14, 15 e 17). Esse metodo de testepertence a classe CertificateInfoTest.java, do projeto Cadroid14.

1 protected void setUp() throws Exception {

2 assetManager = getInstrumentation().getContext().getAssets();

3 certificateFactory = CertificateFactory.getInstance("X.509");

4

5 infoDebianTestCA = loadCertificateInfo("DebianTestCA.pem");

6 infoDebianTestNoCA = loadCertificateInfo("DebianTestNoCA.pem");

7 infoGTECyberTrust = loadCertificateInfo("GTECyberTrustGlobalRoot.pem");

8 // user-submitted test cases

9 infoMehlMX = loadCertificateInfo("mehl.mx.pem");

10 }

11

12 public void testIsCA() {

13 assertTrue(infoDebianTestCA.isCA());

14 assertFalse(infoDebianTestNoCA.isCA());

15 assertNull(infoGTECyberTrust.isCA());

16

17 assertFalse(infoMehlMX.isCA());

18 }

Codigo 2.7 Exemplo - General Fixture

14Disponıvel em 〈https://github.com/bitfireAT/cadroid/〉

2.4 TEST SMELLS 25

Possıvel efeito: uma causa negativa desse test smell e o trabalho desnecessario quee feito quando um metodo de teste e executado.

Deteccao: verificar se ha um ou mais campos que estao sendo instanciados no metodosetUp() e que nao sao testados no metodo de teste a ser executado.

Refatoracao: uma forma de corrigir e usar setUp() somente para aquela parte doambiente que e compartilhada por todos os testes usando o metodo de extracao e colocaro restante no metodo que o utiliza. Se dois grupos diferentes de testes exigirem fixturesdiferentes, e importante que esses testes sejam configurados em metodos separados quesao invocados explicitamente para cada teste ou divida duas classes de teste separadas,extraindo a classe. O Codigo 2.8 mostra um exemplo de refatoracao do General Fixture.Removemos as linhas 2 e 3 do codigo original e extraımos para um novo metodo, umavez que todas variaveis do metodo setUp() devem ser testadas por todos os metodos.

1 protected void setUp() throws Exception {

2 infoDebianTestCA = loadCertificateInfo("DebianTestCA.pem");

3 infoDebianTestNoCA = loadCertificateInfo("DebianTestNoCA.pem");

4 infoGTECyberTrust = loadCertificateInfo("GTECyberTrustGlobalRoot.pem");

5 // user-submitted test cases

6 infoMehlMX = loadCertificateInfo("mehl.mx.pem");

7 }

8

9 /* Extracted Method */

10 protected void setUpExtracted() throws Exception {

11 assetManager = getInstrumentation().getContext().getAssets();

12 certificateFactory = CertificateFactory.getInstance("X.509");

13 }

14

15 public void testIsCA() {

16 assertTrue(infoDebianTestCA.isCA());

17 assertFalse(infoDebianTestNoCA.isCA());

18 assertNull(infoGTECyberTrust.isCA());

19 assertFalse(infoMehlMX.isCA());

20 }

Codigo 2.8 Exemplo - General Fixture Refatorado

2.4.5 Eager Test

O test smell Eager Test ocorre quando um metodo de teste verifica varios metodos doobjeto testado.

Exemplo: O Codigo 2.9 mostra o metodo de testeNmeaSentence GPGSA ReadValidValues(). Esse metodo testa tres metodos diferentesdo objeto nmeaSentence (linhas 5, 6 e 7). Esse metodo de teste pertence a classeNmeaSentenceTest.java, do projeto GPSLogger15.

1 @Test

2 public void NmeaSentence_GPGSA_ReadValidValues(){

3 NmeaSentence nmeaSentence = new NmeaSentence("$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39");4 assertThat("GPGSA - read PDOP", nmeaSentence.getLatestPdop(), is("2.5"));

5 assertThat("GPGSA - read HDOP", nmeaSentence.getLatestHdop(), is("1.3"));

6 assertThat("GPGSA - read VDOP", nmeaSentence.getLatestVdop(), is("2.1"));

7 }

Codigo 2.9 Exemplo - Eager Test

15Disponıvel em 〈https://github.com/mendhak/gpslogger〉

26 REFERENCIAL TEORICO

Possıvel efeito: Dificuldades na compreensao e manutencao de testes.Deteccao: Um metodo de teste contem varias chamadas para varios metodos de

producao.Refatoracao: Extrair o metodo separando os assertions em metodos de teste distin-

tos. O Codigo 2.10 mostra o Codigo 2.9 refatorado. No Codigo 2.10 foi feita a extracaodo segundo e do terceiro assert para novos metodos. Apenas a declaracao do objeto emantida nos metodos extraıdos.

1 @Test

2 public void NmeaSentence_GPGSA_ReadValidValues(){

3 NmeaSentence nmeaSentence = new NmeaSentence("$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39");4

5 assertThat("GPGSA - read PDOP", nmeaSentence.getLatestPdop(), is("2.5"));

6 }

7

8 /* Extracted Method */

9 @Test

10 public void NmeaSentence_GPGSA_ReadValidValues_getLatestHdop(){

11 NmeaSentence nmeaSentence = new NmeaSentence("$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39");12

13 assertThat("GPGSA - read HDOP", nmeaSentence.getLatestHdop(), is("1.3"));

14 }

15

16 /* Extracted Method */

17 @Test

18 public void NmeaSentence_GPGSA_ReadValidValues_getLatestVdop(){

19 NmeaSentence nmeaSentence = new NmeaSentence("$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39");20

21 assertThat("GPGSA - read VDOP", nmeaSentence.getLatestVdop(), is("2.1"));

22 }

Codigo 2.10 Exemplo - Eager Test Refatorado

2.4.6 Lazy Test

Oposto do Eager Test, o Lazy Test ocorre quando varios metodos de teste chamam omesmo metodo do objeto de producao.

Exemplo: O Codigo 2.11 mostra um exemplo de Lazy Test. Os metodos testDecrypt()e testEncrypt() chamam o metodo decrypt() (linhas 12 e 19). Esses metodos de testepertencem a classe CryptographerTest.java do projeto aRevelation16.

16Disponıvel em 〈https://github.com/MarmaladeSky/aRevelation〉

2.4 TEST SMELLS 27

1 @Test

2 public void testDecrypt() throws Exception {

3 FileInputStream file = new FileInputStream(ENCRYPTED_DATA_FILE_4_14);

4 byte[] enfileData = new byte[file.available()];

5 FileInputStream input = new FileInputStream(DECRYPTED_DATA_FILE_4_14);

6 byte[] fileData = new byte[input.available()];

7 input.read(fileData);

8 input.close();

9 file.read(enfileData);

10 file.close();

11 String expectedResult = new String(fileData, "UTF-8");

12 assertEquals("Testing simple decrypt",expectedResult, Cryptographer.decrypt(enfileData, "test"));

13 }

14

15 @Test

16 public void testEncrypt() throws Exception {

17 String xml = readFileAsString(DECRYPTED_DATA_FILE_4_14);

18 byte[] encrypted = Cryptographer.encrypt(xml, "test");

19 String decrypt = Cryptographer.decrypt(encrypted, "test");

20 assertEquals(xml, decrypt);

21 }

Codigo 2.11 Exemplo - Lazy Test

Possıvel efeito: Dificuldade em manter a consistencia durante a manutencao doteste.

Deteccao: verificar se mais de um metodo de teste chama o mesmo metodo deproducao.

Refatoracao: esse test smell pode ser removido com o metodo Inline (RefatoracaoInline Resource) para organizar todos os metodos envolvidos em um unico metodo. OCodigo 2.12 mostra o Codigo 2.11 com uma possıvel forma de refatoracao.

1 @Test

2 public void testDecrypt() throws Exception {

3 FileInputStream file = new FileInputStream(ENCRYPTED_DATA_FILE_4_14);

4 byte[] enfileData = new byte[file.available()];

5 FileInputStream input = new FileInputStream(DECRYPTED_DATA_FILE_4_14);

6 byte[] fileData = new byte[input.available()];

7 input.read(fileData);

8 input.close();

9 file.read(enfileData);

10 file.close();

11 String expectedResult = new String(fileData, "UTF-8");

12 assertEquals("Testing simple decrypt",expectedResult, Cryptographer.decrypt(enfileData, "test"));

13

14 byte[] encryptedXml = readEncryptedXml(ENCRYPTED_XML_FILE);

15 String expectedDecryptedXml = readDecryptedXmlAsString(DECRYPTED_XML_FILE);

16 String decrypt = Cryptographer.decrypt(encryptedXml, "test");

17 assertEquals("Testing XML decrypt", expectedDecryptedXML, decrypt);

18 }

Codigo 2.12 Exemplo - Lazy Test Refatorado

2.4.7 Assertion Roulette

O Assertion Roulette ocorre quando um metodo de teste possui varios assertions naodocumentados. No JUnit, assertions possuem um primeiro argumento opcional paraadicionar uma mensagem que deve explicar o que cada assertion verifica. Isso facilitaa compreensao dos diferentes assertions que ocorrem no mesmo teste. A ausencia desse

28 REFERENCIAL TEORICO

parametro na estrutura do assertion pode dificultar o entendimento durante a manu-tencao e a identificacao do assertion se o metodo falhar.

Exemplo: O Codigo 2.13 apresenta um metodo de teste com multiplos assertionssem uma mensagem (linhas 4 a 6). O exemplo apresenta um metodo da classe de testeTestAbstractPartial.java do projeto Joda-Time17.

1 public void testGetValues() throws Throwable {

2 MockPartial mock = new MockPartial();

3 int[] vals = mock.getValues();

4 assertEquals(2, vals.length);

5 assertEquals(1970, vals[0]);

6 assertEquals(1, vals[1]);

7 }

Codigo 2.13 Exemplo - Assertion Roulette

Possıvel efeito: Varias declaracoes assertion em um metodo de teste sem umamensagem descritiva podem afetar a legibilidade, a compreensibilidade e a manutencaodo teste. Multiplos assertions dificultam a identificacao de qual assertion causou um erroquando um teste falha.

Deteccao: Um metodo de teste com mais de uma instrucao assertion sem ex-plicacao/mensagem (parametro no metodo de assercao).

Refatoracao: Incluir explicacao para cada assertion (Refatoracao Add AssertionExplanation). O Codigo 2.14 mostra o Codigo 2.13 refatorado com as explicacoesapropriadas para cada assertion.

1 public void testGetValues() throws Throwable {

2 MockPartial mock = new MockPartial();

3 int[] vals = mock.getValues();

4 assertEquals("Vals size 2", 2, vals.length);

5 assertEquals("Year Equal 1970", 1970, vals[0]);

6 assertEquals("Month 1", 1, vals[1]);

7 }

Codigo 2.14 Exemplo - Assertion Roulette Refatorado

2.4.8 Indirect Testing

O test smell Indirect Testing ocorre quando o metodo de teste testa um objeto indireta-mente por meio de outro objeto.

Exemplo: O Codigo 2.15 mostra um metodo de teste com o test smell IndirectTesting. A classe de producao Employee herda da classe Person (linha 10) e o metodode teste testEmployeeAge() testa um metodo da classe herdada (linha 30).

17Disponıvel em https://github.com/JodaOrg/joda-time

2.4 TEST SMELLS 29

1 class Person {

2 private String name;

3 private Date birthDate;

4 ...

5 public Person(String name, Date birthDate, ...) {...}

6

7 final String getAgeFromBirthDate() {...}

8 }

9

10 class Employee extends Person {

11

12 private Double salary;

13 ...

14

15 public Employee(String name, Date birthDate, Double salary, ...) {

16 super(name, birthDate, ...)

17 }

18

19 ...

20 }

21

22 class EmployeeTest {

23 ...

24 @Test

25 public void testEmployeeAge() {

26 Employee employee = new Employee("John", new Date(1970, 8, 12), 9887.45, ...);

27

28 String expectedAge = 49;

29

30 assertEquals(expectedAge, employee.getAgeFromBirthDate());

31 }

32 }

Codigo 2.15 Exemplo - Indirect Testing

Possıvel efeito: pode haver problemas com a ocultacao de dados no codigo deproducao. A compreensao e a depuracao se torna uma tarefa mais complexa.

Deteccao: se uma classe de teste e composta por metodos que realizam testes emoutros objetos, e considerado um teste indireto.

Refatoracao: o test smell pode ser movido para a classe de teste apropriada aplicando-se a extracao do metodo, e logo em seguida movendo-o. O Codigo 2.16 mostra umapossıvel refatoracao para o Codigo 2.15. O metodo testEmployeeAge() foi extraıdopara a classe de teste PersonTest (linha 1).

1 class PersonTest {

2 ...

3 @Test

4 public void testPersonAge() {

5 Person person = new Person("John", new Date(1970, 8, 12), ...);

6

7 String expectedAge = 49;

8

9 assertEquals(expectedAge, person.getAgeFromBirthDate());

10 }

11 }

Codigo 2.16 Exemplo - Indirect Testing Refatorado

30 REFERENCIAL TEORICO

2.4.9 For Testers Only

O codigo de producao e o codigo de teste, por padrao, devem ser mantidos separados.Quando uma classe de producao contem metodos usados apenas por metodos de teste, econsiderado um test smell.

Exemplo: O Codigo 2.17 mostra a classe de producao Balance que contem o metodotestBalanceValue (linhas 15-19), usado apenas para teste.

1 class Balance {

2

3 private BigDecimal value;

4

5 public Balance(String value) {

6 this.value = clearCurrencyChars(value);

7 }

8

9 public BigDecimal getValue() {

10 return value;

11 }

12

13 private BigDecimal clearCurrencyChars(String value) {...}

14

15 public static void testBalanceValue() {

16 Balance balance = new Balance("$ 1,234.56");

17 BigDecimal expected = new BigDecimal("1234.56");

18 assertEquals("Verify value", expected, balance.getValue());

19 }

20 }

Codigo 2.17 Exemplo - For Testers Only

Possıvel efeito: Necessita de um esforco extra para compreender e modificar o codigode producao.

Deteccao: O codigo de producao contem trechos que sao reservados para testes.Refatoracao: Extrair o trecho do codigo que se refere ao teste, move-lo para uma

subclasse do codigo de teste e usar essa subclasse para executar os testes. O Codigo 2.18mostra a extracao do metodo testBalanceValue() (do Codigo 2.17) para a classe deteste BalanceTest (Codigo 2.18).

1 class BalanceTest {

2

3 @Test

4 public void testBalanceValue() {

5 Balance balance = new Balance("$ 1,234.56");

6 BigDecimal expected = new BigDecimal("1234.56");

7 assertEquals("Verify value", expected, balance.getValue());

8 }

9

10 }

Codigo 2.18 Exemplo - For Testers Only Refatorado

2.4.10 Sensitive Equality

O test smell Sensitive Equality ocorre quando um metodo de teste possui verificacoesde igualdade usando o metodo toString(). Geralmente, o resultado real e calculado econvertido em uma string, a qual e comparada com o valor de uma outra string, querepresenta o valor real.

2.4 TEST SMELLS 31

Exemplo: O Codigo 2.19 apresenta o metodo test1(). Ha Sensitive Equality nalinha 15. Esse metodo de teste pertence a classe RLPTest.java, do projeto UFP18.

1 @Test

2 public void test1() throws UnknownHostException {

3

4 String peersPacket = "F8 4E 11 F8 4B C5 36 81 " +

5 "CC 0A 29 82 76 5F B8 40 D8 D6 0C 25 80 FA 79 5C " +

6 "FC 03 13 EF DE BA 86 9D 21 94 E7 9E 7C B2 B5 22 " +

7 "F7 82 FF A0 39 2C BB AB 8D 1B AC 30 12 08 B1 37 " +

8 "E0 DE 49 98 33 4F 3B CF 73 FA 11 7E F2 13 F8 74 " +

9 "17 08 9F EA F8 4C 21 B0";

10

11 byte[] payload = Hex.decode(peersPacket);

12

13 byte[] ip = decodeIP4Bytes(payload, 5);

14

15 assertEquals(InetAddress.getByAddress(ip).toString(), ("/54.204.10.41"));

16 }

Codigo 2.19 Exemplo - Sensitive Equality

Possıvel efeito: Verificacoes de igualdade usando toString() depende de detalhesirrelevantes, e.g. vırgulas, aspas, espacos, que podem interferir no resultado do teste.Nesse sentido, e comum que os testes comecam a falhar quando o metodo toString()

de um objeto e alterado.

Deteccao: Um metodo de teste comparando um objeto com um resultado esperadoatraves do metodo toString().

Refatoracao: Adicionar uma implementacao para o metodo equals() para a classedo objeto e reescrever os testes que usam toString() para usar o metodo equals()

(Refatoracao Introduce Equality Method). Dessa forma, as verificacoes de igualdadede toString() sao substituıdas por verificacoes de igualdade reais. O Codigo 2.20 mostrauma possıvel refatoracao para o Codigo 2.19.

1 @Test

2 public void test1() throws UnknownHostException {

3

4 String peersPacket = "F8 4E 11 F8 4B C5 36 81 " +

5 "CC 0A 29 82 76 5F B8 40 D8 D6 0C 25 80 FA 79 5C " +

6 "FC 03 13 EF DE BA 86 9D 21 94 E7 9E 7C B2 B5 22 " +

7 "F7 82 FF A0 39 2C BB AB 8D 1B AC 30 12 08 B1 37 " +

8 "E0 DE 49 98 33 4F 3B CF 73 FA 11 7E F2 13 F8 74 " +

9 "17 08 9F EA F8 4C 21 B0";

10

11 byte[] payload = Hex.decode(peersPacket);

12

13 byte[] ip = decodeIP4Bytes(payload, 5);

14

15 assertEquals(InetAddress.getByAddress(ip), InetAddress.getByName("54.204.10.41"));

16 }

Codigo 2.20 Exemplo - Sensitive Equality Refatorado

18Disponıvel em 〈https://github.com/liveplayergames/UFP〉

32 REFERENCIAL TEORICO

2.4.11 Test Code Duplication

Assim como o codigo de producao, o codigo de teste pode conter duplicacoes indesejaveis.Quando isso ocorre no metodo de teste, denomina-se como Test Code Duplication. Ge-ralmente, os test fixtures sao suscetıveis a esse problema.

Exemplo: O Codigo 2.21 apresenta o metodo testInvoice addTwoLineItems -

sameProduct(), exemplo apresentado por Meszaros (2007). As linhas 19-21 sao du-plicacoes das linhas 14-16.

1 @Test

2 public void testInvoice_addTwoLineItems_sameProduct() {

3 Invoice inv = createAnonInvoice();

4 LineItem expItem1 = new LineItem(inv, product, QUANTITY1);

5 LineItem expItem2 = new LineItem(inv, product, QUANTITY2);

6 // Exercise

7 inv.addItemQuantity(product, QUANTITY1);

8 inv.addItemQuantity(product, QUANTITY2);

9 // Verify

10 List lineItems = inv.getLineItems();

11 assertEquals("number of items", lineItems.size(), 2);

12 // verify first item

13 LineItem actual = (LineItem)lineItems.get(0);

14 assertEquals(expItem1.getInv(), actual.getInv());

15 assertEquals(expItem1.getProd(), actual.getProd());

16 assertEquals(expItem1.getQuantity(), actual.getQuantity());

17 // verify second item

18 actual = (LineItem)lineItems.get(1);

19 assertEquals(expItem2.getInv(), actual.getInv());

20 assertEquals(expItem2.getProd(), actual.getProd());

21 assertEquals(expItem2.getQuantity(), actual.getQuantity());

22 }

Codigo 2.21 Exemplo - Test Code Duplication

Possıvel efeito: Copias de codigo tem efeitos negativos na manutencao.Deteccao: Trechos de codigo duplicados no codigo de teste.Refatoracao: Uma solucao e utilizar Extract Method, semelhante as da duplicacao

de codigo de producao, conforme descrito por Fowler (1999). O Codigo 2.22 apresentauma possıvel solucao para refatorar o Codigo 2.21. O trecho duplicado foi extraıdo parao novo metodo assertLineItem() (Codigo 2.22, linhas 18-22) e esta sendo chamado naslinhas 13 e 15 (Codigo 2.22).

2.4 TEST SMELLS 33

1 @Test

2 public void testInvoice_addTwoLineItems_sameProduct() {

3 Invoice inv = createAnonInvoice();

4 LineItem expItem1 = new LineItem(inv, product, QUANTITY1);

5 LineItem expItem2 = new LineItem(inv, product, QUANTITY2);

6 // Exercise

7 inv.addItemQuantity(product, QUANTITY1);

8 inv.addItemQuantity(product, QUANTITY2);

9 // Verify

10 List lineItems = inv.getLineItems();

11 assertEquals("number of items", lineItems.size(), 2);

12 // verify first item

13 assertLineItem("First Item", expItem2, (LineItem)lineItems.get(0));

14 // verify second item

15 assertLineItem("Second Item", expItem2, (LineItem)lineItems.get(1));

16 }

17

18 public void assertLineItem(String message, LineItem expected, LineItem actual) {

19 assertEquals(message + ":getInv", expected.getInv(), actual.getInv());

20 assertEquals(message + ":getProd", expected.getProd(), actual.getProd());

21 assertEquals(message + ":getQuantity", expected.getQuantity(), actual.getQuantity());

22 }

Codigo 2.22 Exemplo - Test Code Duplication Refatorado

2.4.12 Condicional Test Logic

Codigos de testes devem ser simples e capazes de executar todas as instrucoes do metodode producao. O test smell Condicional Test Logic ocorre quando dentro do metodo deteste, utiliza-se expressoes condicionais.

Exemplo: O Codigo 2.23 apresenta o metodo de teste testSpinner(), da classeEventsScraperTest.java, do projeto TuCanMobile19. O metodo testSpinner() possuiestruturas de controle nas linhas 3, 7, 9 e 14.

1 @Test

2 public void testSpinner() {

3 for (Map.Entry entry : sourcesMap.entrySet()) {

4

5 String id = entry.getKey();

6 Object resultObject = resultsMap.get(id);

7 if (resultObject instanceof EventsModel) {

8 EventsModel result = (EventsModel) resultObject;

9 if (result.testSpinner.runTest) {

10 AnswerObject answer = new AnswerObject(entry.getValue(), "", new CookieManager(), "");

11 EventsScraper scraper = new EventsScraper(RuntimeEnvironment.application, answer);

12 SpinnerAdapter spinnerAdapter = scraper.spinnerAdapter();

13 assertEquals(spinnerAdapter.getCount(), result.testSpinner.data.size());

14 for (int i = 0; i < spinnerAdapter.getCount(); i++) {

15 assertEquals(spinnerAdapter.getItem(i), result.testSpinner.data.get(i));

16 }

17 }

18 }

19 }

20 }

Codigo 2.23 Exemplo - Condicional Test Logic

19Disponıvel em 〈https://github.com/Tyde/TuCanMobile〉

34 REFERENCIAL TEORICO

Possıvel efeito: Quando um metodo possui estruturas condicionais, o comporta-mento do teste pode ser alterado, o teste pode nao conseguir identificar defeitos nometodo de producao, pois as instrucoes de teste nao sao executadas quando uma condicaonao e atendida. Alem disso, estruturas condicionais podem dificultar a legibilidade e acompreensao do codigo.

Deteccao: Verificar se o metodo de teste utiliza uma ou mais expressoes condicionais(e.g. if(), else if(), else(), switch(), for(), foreach() e while()) no seu escopo.

Refatoracao: Reescrever o metodo de teste de modo que as estruturas sejam remo-vidas. O Codigo 2.24 apresenta uma possıvel forma de corrigir o test smell CondicionalTest Logic do Codigo 2.23, utilizando o test fixture.

1 @Test

2 public void testSpinner() {

3 AnswerObject answer = createAnswerObject();

4 EventsScraper scraper = createEventsScraper(answer);

5 SpinnerAdapter spinnerAdapter = scraper.spinnerAdapter();

6

7 EventsModel result = createEventsModel();

8

9 assertEquals(spinnerAdapter.getCount(), result.testSpinner.data.size());

10 assertEquals(result.testSpinner.data, getListFromAdapter(spinnerAdapter));

11 }

Codigo 2.24 Exemplo - Condicional Test Logic Refatorado

2.4.13 Constructor Initialization

O test smell Constructor Initialization ocorre quando se utiliza um metodo construtorpara a classe de teste. Todas as dependencias do teste devem ser configuradas utilizandoum metodo com a anotacao @Before.

Exemplo: O Codigo 2.25 apresenta um trecho da classe de teste TagEncodingTest,extraıda do projeto Briar20. Essa classe possui um metodo construtor (linhas 5-8).

1 public class TagEncodingTest extends BrambleTestCase {

2 private final CryptoComponent crypto;

3 private final SecretKey tagKey;

4

5 public TagEncodingTest() {

6 crypto = new CryptoComponentImpl(new TestSecureRandomProvider());

7 tagKey = TestUtils.getSecretKey();

8 }

9

10 @Test

11 public void testKeyAffectsTag() throws Exception {

12 for (int i = 0; i < 100; i++) {

13 ...

14 crypto.encodeTag(tag, tagKey, PROTOCOL_VERSION, streamNumber);

15 assertTrue(set.add(new Bytes(tag)));

16 }

17 }

18 ...

19 }

Codigo 2.25 Exemplo - Constructor Initialization

20Disponıvel em 〈https://code.briarproject.org/briar/briar〉

2.4 TEST SMELLS 35

Possıvel efeito: Metodos construtores sao executados apenas uma vez, diferente-mente do metodo de configuracao (anotado com @Before), que e executado antes decada teste. Dessa forma, quando utiliza-se a inicializacao atraves de construtores, asdependencias dos testes podem apresentar estados nao esperados.

Deteccao: Verificar se a classe de teste possui um metodo construtor e se este metodoinicializa as dependencias dos testes.

Refatoracao: Alocar a inicializacao das dependencias para o metodo de configuracaousando a anotacao @Before (Refatoracao Setup External Resource). O Codigo 2.26apresenta uma possıvel forma de remover o Constructor Inicialization do Codigo 2.25.

1 public class TagEncodingTest extends BrambleTestCase {

2 private CryptoComponent crypto;

3 private SecretKey tagKey;

4

5 @Before

6 public void setUp() {

7 crypto = new CryptoComponentImpl(new TestSecureRandomProvider());

8 tagKey = TestUtils.getSecretKey();

9 }

10

11 @Test

12 public void testKeyAffectsTag() throws Exception {

13 for (int i = 0; i < 100; i++) {

14 ...

15 crypto.encodeTag(tag, tagKey, PROTOCOL_VERSION, streamNumber);

16 assertTrue(set.add(new Bytes(tag)));

17 }

18 }

19 ...

20 }

Codigo 2.26 Exemplo - Constructor Initialization Refatorado

2.4.14 Default Test

Algumas IDEs criam classes de teste default ao criar o projeto. O Android Studio, porexemplo, cria a classe ExampleUnitTest com o metodo addition isCorrect(). Classesde teste default sao fornecidas apenas para os desenvolvedores a utilizarem como exemplopara a escrita de teste. Apos ser utilizada como modelo para auxiliar durante a escritados testes, a classe default deve ser renomeada ou removida. A presenca de classesde teste default indica a presenca do test smell Default Test. Alem disso, a pratica demanter classes e metodos default pode dificultar a manutencao quando essas classes foremrenomeadas no futuro.

Exemplo: O Codigo 2.27 apresenta uma classe de teste default. Alem da classeapresentar o metodo default (linhas 3-5), outros metodos foram inseridos nessa classe,como o metodo shareProblem() (linhas 8-15). Esse metodo de teste pertence a classeExampleUnitTest.java, do projeto Missed Notifications Reminder21.

21Disponıvel em 〈https://github.com/httpdispatch/MissedNotificationsReminder〉

36 REFERENCIAL TEORICO

1 public class ExampleUnitTest {

2 @Test

3 public void addition_isCorrect() throws Exception {

4 assertEquals(4, 2 + 2);

5 }

6

7 @Test

8 public void shareProblem() throws InterruptedException {

9 .....

10 Observable.just(200).subscribeOn(Schedulers.newThread()).subscribe(begin.asAction());

11 begin.set(200);

12 Thread.sleep(1000);

13 assertEquals(beginTime.get(), "200");

14 .....

15 }

16 .....

17 }

Codigo 2.27 Exemplo - Default Test

Possıvel efeito: Quando uma classe default nao e removida ou nao e renomeada,os desenvolvedores poderao comecar a adicionar metodos de teste a essas classes default.Isso pode fazer com que esta classe se torne um “conteiner” de todos os metodos de teste,e consequentemente estara violando boas praticas do desenvolvimento de teste.

Deteccao: Verificar a existencia da classe ExampleUnitTest.Refatoracao: A classe de teste default deve ser renomeada, assim como o metodo

default. O Codigo 2.28 apresenta uma forma de solucionar o test smell Default Test.

1 public class ShareProblemClassTest { // renamed from ExampleUnitTest

2

3 @Test

4 public void shareProblem() throws InterruptedException {

5 .....

6 Observable.just(200).subscribeOn(Schedulers.newThread()).subscribe(begin.asAction());

7 begin.set(200);

8 Thread.sleep(1000);

9 assertEquals(beginTime.get(), "200");

10 .....

11 }

12 .....

13 }

Codigo 2.28 Exemplo - Default Test Refatorado

2.4.15 Duplicate Assert

O Duplicate Assert ocorre quando um metodo de teste verifica a mesma condicao maisde uma vez no mesmo metodo de teste (PERUMA et al., 2019).

Exemplo: O Codigo 2.29 mostra um metodo com dois assertions com os mes-mos parametros (linhas 6 e 8). O exemplo apresenta um metodo da classe de testeTestPeriodFormatterBuilder.java do projeto Joda-Time22.

22Disponıvel em 〈https://github.com/JodaOrg/joda-time〉

2.4 TEST SMELLS 37

1 public void testPluralAffixParseOrder() {

2 PeriodFormatter f = builder.appendDays().appendSuffix("day", "days").toFormatter();

3 String twoDays = Period.days(2).toString(f);

4

5 Period period = f.parsePeriod(twoDays);

6 assertEquals(Period.days(2), period);

7 period = f.parsePeriod(twoDays.toUpperCase(Locale.ENGLISH));

8 assertEquals(Period.days(2), period);

9 }

Codigo 2.29 Exemplo - Duplicate Assert

Possıvel efeito: Dificulta a legibilidade e a manutencao do teste, uma vez que as-sertions iguais (com os mesmos parametros) no mesmo metodo nao torna explıcito oobjetivo do metodo de teste. Em geral, o Duplicate Assert cria um cenario que viola aresponsabilidade de cada metodo cumprir um unico objetivo.

Deteccao: Um metodo de teste que contem duas ou mais instrucoes de assertioncom os mesmos parametros.

Refatoracao: Para testar a mesma condicao com valores diferentes, um novo metodode teste deve ser criado. O Codigo 2.29 mostra uma possıvel refatoracao para o Codigo2.30. A duplicacao foi extraıda para um novo metodo (linhas 10-16 no Codigo 2.29).

1 public void testPluralAffixParseOrder() {

2 PeriodFormatter f = builder.appendDays().appendSuffix("day", "days").toFormatter();

3 String twoDays = Period.days(2).toString(f);

4

5 Period period = f.parsePeriod(twoDays);

6 assertEquals(Period.days(2), period);

7 }

8

9 /* Extracted Method */

10 public void testPluralAffixParseOrderExtracted() {

11 PeriodFormatter f = builder.appendDays().appendSuffix("day", "days").toFormatter();

12 String twoDays = Period.days(2).toString(f);

13

14 Period period = f.parsePeriod(twoDays.toUpperCase(Locale.ENGLISH));

15 assertEquals(Period.days(2), period);

16 }

Codigo 2.30 Exemplo - Duplicate Assert Refatorado

2.4.16 Empty Test

O test smell Empty Test ocorre quando um metodo de teste nao possui instrucoes exe-cutaveis. Geralmente, isso ocorre quando metodos sem instrucoes executaveis sao criadoscom o objetivo de depurar, ou os metodos possuem instrucoes executaveis, mas estaocomentadas.

Exemplo: O Codigo 2.31 apresenta o metodo de teste testCredGetFullSampleV1()com instrucoes comentadas (linhas 13-17).

38 REFERENCIAL TEORICO

1 class Lending { // production class

2 ...

3 public BigDecimal getValue() {...}

4

5 public BigDecimal getTaxes() {...}

6

7 @Deprecated // Wrong calc for taxes. Use ‘getValue().add(getTaxes())‘ instead.

8 public Double getValueWithTaxes() {...}

9 }

10

11 @Test

12 public void testGetLendingValueWithTaxes() {

13 // Lending lending = new Lending(CONDITION);

14 // Double expectedLendingValue = 10000.90D;

15 /* remove deprecated usage */

16 // Double value = lending.getValueWithTaxes();

17 // assertEquals(expectedLendingValue, value);

18 }

Codigo 2.31 Exemplo - Empty Test

Possıvel efeito: Quando uma classe de teste possui um metodo vazio, o JUnit sempreindicara que o teste e aprovado. Assim, os desenvolvedores terao a falsa impressao sobreos resultados dessa classe, principalmente quando novas modificacoes forem introduzidas.

Deteccao: Verificar se ha algum teste sem instrucoes executaveis.Refatoracao: Se houver instrucoes comentadas, e importante checar se tais ins-

trucoes se aplicam e se podem ser utilizadas. Se as instrucoes comentadas nao puderemser utilizadas, ou ate mesmo o metodo for vazio, sera necessario escrever o corpo dometodo de teste de modo que tenha instrucoes executaveis validando o comportamentoda classe de producao. O Codigo 2.32 apresenta uma possıvel forma de corrigir o EmptyTest do Codigo 2.31.

1 @Test

2 public void testGetLendingValueWithTaxes() {

3 Lending lending = new Lending(CONDITION);

4 BigDecimal expectedLendingValue = new BigDecimal("10000.90");

5

6 BigDecimal value = lending.getValue().add(lending.getTaxes());

7 assertEquals(expectedLendingValue, value);

8 }

Codigo 2.32 Exemplo - Empty Test Refatorado

2.4.17 Exception Handling

O test smell Exception Handling ocorre quando a aprovacao ou reprovacao de um metodode teste depende explicitamente do metodo de producao que gera uma excecao.

Exemplo: O Codigo 2.33 apresenta um try/catch (linhas 6-10) para tratar o resul-tado retornado pelo metodo de producao.

2.4 TEST SMELLS 39

1 @Test

2 public void testParseStringToDate() {

3 long expectedTime = 1266710400L;

4 Date date;

5

6 try {

7 date = DateUtils.parseToDate("2010-02-21", "yyyy-MM-dd");

8 } catch(ParseException e) {

9 fail(e.getMessage());

10 }

11

12 assertEquals(expectedTime, date.getTime());

13 }

Codigo 2.33 Exemplo - Exception Handling

Possıvel efeito: O resultado do teste pode ser influenciado pelo bloco do try/catch.Deteccao: Verificar se o metodo apresenta alguma estrutura try/catch.Refatoracao: Reescrever o metodo de teste de modo que o teste nao dependa do

try/catch.

1 @Test

2 public void testParseStringToDate() {

3 long expectedTime = 1266710400L;

4 Date date = DateUtils.parseToDate("2010-02-21", "yyyy-MM-dd");

5

6 assertEquals(expectedTime, date.getTime());

7 }

8

9 @Test(expected = ParseException.class)

10 public void testParseInvalidStringToDateShouldThrowsException() {

11 String invalidDate = "2010-21-02";

12 DateUtils.parseToDate(invalidDate, "yyyy-MM-dd");

13 }

Codigo 2.34 Exemplo - Exception Handling Refatorado

2.4.18 Ignored Test

O test smell Ignored Test ocorre quando um metodo de teste implementado nao e exe-cutado, devido a utilizacao da anotacao @Ignore(), recurso disponibilizado pelo JUnit

4. Contudo, metodos que utilizam essa anotacao podem sobrecarregar os testes.Exemplo: O Codigo 2.35 apresenta o metodo de teste testGetLendingValueWithTaxes().

O metodo testGetLendingValueWithTaxes() nao e executado devido a anotacao @Ignore()(linha 12) presente antes da sua assinatura do metodo.

40 REFERENCIAL TEORICO

1 class Lending { // production class

2 ...

3 public BigDecimal getValue() {...}

4

5 public BigDecimal getTaxes() {...}

6

7 @Deprecated // Wrong calc for taxes. Use ‘getValue().add(getTaxes())‘ instead.

8 public Double getValueWithTaxes() {...}

9 }

10

11 @Test

12 @Ignore("Remove deprecated usage and apply BigDecimal to values.")

13 public void testGetLendingValueWithTaxes() {

14 Lending lending = new Lending(CONDITION);

15 Double expectedLendingValue = 12000.00D;

16

17 Double value = lending.getValueWithTaxes();

18 assertEquals(expectedLendingValue, value);

19 }

Codigo 2.35 Exemplo - Ignored Test

Possıvel efeito: A pratica de ignorar testes pode resultar em sobrecarga no tempode compilacao, aumento na complexidade da classe de teste e dificuldade da compreensaodo codigo.

Deteccao: Verificar se o codigo de teste utiliza a anotacao @Ignore() antes da suaassinatura.

Refatoracao: A primeira fase da refatoracao do Ignored Test e remover a anotacao@Ignore(). A segunda etapa e semelhante a correcao do Empty Test : deve-se analisarse as instrucoes presentes no metodo de teste se aplicam e se podem ser utilizadas; casoas instrucoes no metodo nao se apliquem, sera necessario reescrever o corpo do metodode teste de modo que as instrucoes validem o comportamento da classe de producao. OCodigo 2.36 apresenta uma possıvel forma de refatorar o Codigo 2.35.

1 @Test

2 public void testGetLendingValueWithTaxes() {

3 Lending lending = new Lending(CONDITION);

4 BigDecimal expectedLendingValue = new BigDecimal("12000.00");

5 BigDecimal value = lending.getValue().add(lending.getTaxes());

6 assertEquals(expectedLendingValue, value);

7 }

Codigo 2.36 Exemplo - Ignored Test Refatorado

2.4.19 Magic Number Test

O test smell Magic Number Test ocorre quando um metodo de teste contem literaisnumericos inexplicaveis e nao documentados como parametros ou como valores para iden-tificadores.

Exemplo: O Codigo 2.37 apresenta o metodo testGetLocalTimeAsCalendar(), comMagic Number Test em sua estrutura (linhas 3-5). Esse metodo de teste pertence a classeSolarEventCalculatorTest.java, do projeto PressureNet23.

23Disponıvel em 〈https://github.com/Cbsoftware/PressureNet〉

2.4 TEST SMELLS 41

1 @Test

2 public void testGetLocalTimeAsCalendar() {

3 Calendar localTime = calc.getLocalTimeAsCalendar(BigDecimal.valueOf(15.5D), Calendar.getInstance());

4 assertEquals(15, localTime.get(Calendar.HOUR_OF_DAY));

5 assertEquals(30, localTime.get(Calendar.MINUTE));

6 }

Codigo 2.37 Exemplo - Magic Number Test

Possıvel efeito: Similarmente ao codigo de producao, o uso de literais numericossem documentacao pode afetar o metodo negativamente, dificultando a compreensao e aevolucao dos testes.

Deteccao: Verificar se no corpo do metodo ha literais numericos sendo utilizadoscomo parametros ou como valores para identificadores.

Refatoracao: Os literais numericos devem ser substituıdos por constantes ou variaveis,fornecendo assim um nome descritivo para o valor. O Codigo 2.38 apresenta uma possıvelsolucao de refatoracao para o Codigo 2.37.

1 @Test

2 public void testGetLocalTimeAsCalendar() {

3 Double decimalTime = 15.5D;

4 int expectedHourOfDay = 15;

5 int expectedMinute = 30;

6

7 Calendar localTime = calc.getLocalTimeAsCalendar(BigDecimal.valueOf(decimalTime), Calendar.getInstance

↪→ ());

8 assertEquals(expectedHourOfDay, localTime.get(Calendar.HOUR_OF_DAY));

9 assertEquals(expectedMinute, localTime.get(Calendar.MINUTE));

10 }

Codigo 2.38 Exemplo - Magic Number Test Refatorado

2.4.20 Redundant Print

O test smell Redundant Print ocorre quando um metodo possui instrucoes de impressaonos testes de unidade. A pratica de utilizar instrucoes de impressao nos testes e consi-derada redundante, pois os testes sao executados de forma automatizada e as impressoesnao tem utilidade nesse cenario.

Exemplo: O Codigo 2.39 apresenta um metodo de teste testTransform10mNEUAndBack()com uma instrucao de impressao (linha 5). Esse metodo de teste pertence a classeSpace3DTransformerTest.java, do projeto SexyTopo24.

1 @Test

2 public void testTransform10mNEUAndBack() {

3 Leg northEastAndUp10M = new Leg(10, 45, 45);

4 Coord3D result = transformer.transform(Coord3D.ORIGIN, northEastAndUp10M);

5 System.out.println("result = " + result);

6 Leg reverse = new Leg(10, 225, -45);

7 result = transformer.transform(result, reverse);

8 assertEquals(Coord3D.ORIGIN, result);

9 }

Codigo 2.39 Exemplo - Redundant Print

24Disponıvel em 〈https://github.com/richsmith/sexytopo〉

42 REFERENCIAL TEORICO

Possıvel efeito: Alem das instrucoes de impressao serem um recurso desnecessarioaos metodos de teste, elas podem consumir recursos de computacao ou aumentar o tempode execucao se o desenvolvedor invocar um metodo de longa execucao a partir do metodode impressao (i.e., como parametro).

Deteccao: Verificar se no corpo do metodo de teste ha instrucoes de impressao, comopor exemplo, o System.out.println() de Java.

Refatoracao: Se a instrucao de impressao estiver utilizando uma variavel calculadaanteriormente, e possıvel remover essa instrucao do corpo do metodo. Contudo, se ins-trucao de impressao estiver chamando outro metodo como parametro, sera necessarioreescrever o teste removendo a dependencia da instrucao de impressao. O Codigo 2.40apresenta uma possıvel forma de refatorar o Codigo 2.39.

1 @Test

2 public void testTransform10mNEUAndBack() {

3 Leg northEastAndUp10M = new Leg(10, 45, 45);

4 Coord3D result = transformer.transform(Coord3D.ORIGIN, northEastAndUp10M);

5

6 Leg reverse = new Leg(10, 225, -45);

7 result = transformer.transform(result, reverse);

8 assertEquals(Coord3D.ORIGIN, result);

9 }

Codigo 2.40 Exemplo - Redundant Print Refatorado

2.4.21 Redundant Assertion

O test smell Redundant Assertion ocorre quando os metodos de teste contem assertionsque forcam o retorno true ou false. Esse test smell costuma ser introduzido pelosdesenvolvedores para fins de depuracao, e sao posteriormente esquecidos.

Exemplo: O Codigo 2.41 apresenta o metodo testTrue(), no qual o parametrodo valor calculado foi forcado para ser igual o retorno esperado do assertEquals()

(linha3). Esse metodo de teste pertence a classe LoginActivityTest.java, do projetoWorldScope25.

1 @Test

2 public void testTrue() {

3 assertEquals(true, true);

4 }

Codigo 2.41 Exemplo - Redundant Assertion

Possıvel efeito: Independente do metodo do teste estar correto ou nao, utilizar umparametro atual igual ao parametro esperado na estrutura de um assertion faz com queresultado do teste seja forcado. Alem disso, a execucao do teste pode ser prejudicadacom esse tipo de teste desnecessario.

Deteccao: Verificar se o parametro do assertion que esta sendo verificado e igual aovalor esperado.

Refatoracao: Se caso o metodo de teste tiver sido criado apenas para fins de de-puracao, e possıvel remover o metodo e tornar a classe de teste mais compreensıvel.

25Disponıvel em 〈https://github.com/nus-mtp/worldscope〉

2.4 TEST SMELLS 43

2.4.22 Sleepy Test

O test smell Sleepy Test e introduzido quando ha necessidade de pausar a execucao deinstrucoes em um metodo de teste por um certo perıodo simulando ou aguardando umevento externo, e em seguida, continuar com a execucao.

Exemplo: O Codigo 2.42 apresenta o metodo de teste testGetContracts() que forcaum delay artificial (linha 8).

1 @Test

2 public void testGetContracts() {

3 ApiService apiService = new ApiService();

4 ConsumerDataSource consumerDataSource = new ConsumerDataSource(apiService);

5 List<Contract> contracts = consumerDataSource.getContracts(CLIENT_ID);

6

7 Thread.sleep(500); // wait for apiService

8 assertEquals(expectedContracts, contracts);

9 }

Codigo 2.42 Exemplo - Sleepy Test

Possıvel efeito: A pratica de introduzir pausa na execucao do teste de forma explıcitapode levar a resultados inesperados, pois o tempo de processamento de uma tarefa variaquando executado em varios ambientes e configuracoes.

Deteccao: Verificar se no corpo do metodo de teste ha chamada para o metodoThread.sleep().

Refatoracao: O metodo do teste deve ser reescrito de modo que o teste nao dependado Thread.sleep(). O Codigo 2.43 apresenta uma possıvel solucao para o Codigo 2.42.O Sleepy Test foi corrigido utilizando Mock (linha 3). Mock Objects sao objetos queimitam objetos reais para teste, podem ser utilizados para simular o comportamento deobjetos reais complexos.

1 @Test

2 public void testGetContracts() {

3 ApiService mockApiService = createMock<ApiService>();

4 ConsumerDataSource consumerDataSource = new ConsumerDataSource(mockApiService);

5

6 List<Contract> contracts = consumerDataSource.getContracts(CLIENT_ID);

7 assertEquals(expectedContracts, contracts);

8 }

Codigo 2.43 Exemplo - Sleepy Test Refatorado

2.4.23 Unknown Test

O test smell Unknown Test ocorre quando um metodo de teste e codificado sem conterum assertion. Por padrao, as instrucoes de assertions descrevem uma condicao esperadapara um metodo de teste. Ao examinar o assertion, e possıvel compreender o objetivodo teste.

Exemplo: O Codigo 2.44 apresenta o metodo de teste hitGetPOICategoriesApi(),o qual nao possui nenhuma estrutura de assertion. Esse metodo de teste pertence a classeRetrofitApiClientIntegrationTest.java, do projeto Cyclestreets Android App26.

26Disponıvel em 〈https://github.com/cyclestreets/android〉

44 REFERENCIAL TEORICO

1 /* ** Test method without an assertion statement and non-descriptive name ** */

2 @Test

3 public void hitGetPOICategoriesApi() throws Exception {

4 POICategories poiCategories = apiClient.getPOICategories(16);

5 for (POICategory category : poiCategories) {

6 System.out.println(category.name() + ": " + category);

7 }

8 }

Codigo 2.44 Exemplo - Unknown Test

Possıvel efeito: Quando um metodo de teste nao possui estrutura de assertion, oJUnit aprovara esse metodo teste. Essa pratica de programacao dificulta a compreensi-bilidade do teste.

Deteccao: Verificar se a estrutura de assertion esta ausente no corpo do metodo.Refatoracao: Introduzir a estrutura de assertion para validar corretamente o metodo

de producao. O Codigo 2.45 apresenta uma possıvel solucao de refatoracao para o Codigo2.44.

1 @Test

2 public void hitGetPOICategoriesApi() throws Exception {

3 POICategories expectedCategories = createPOICategories(ICON_SIZE);

4 POICategories poiCategories = apiClient.getPOICategories(ICON_SIZE);

5 assertEquals(expectedCategories, poiCategories);

6 }

Codigo 2.45 Exemplo - Unknown Test Refatorado

2.5 TECNICAS DE REFATORACAO

Reconhecendo os malefıcios que os smells podem causar, a refatoracao se torna uma ta-refa importante para as fases de desenvolvimento e teste. A refatoracao consiste em umatecnica disciplinada para reestruturar um corpo de codigo existente, alterando sua estru-tura interna sem alterar seu comportamento externo. Seu coracao e uma serie de pequenastransformacoes que preservam comportamentos. Individualmente, cada transformacao(chamada de “refatoracao”) altera uma parte do codigo e, quando uma sequencia dessastransformacoes sao executadas, pode-se produzir uma reestruturacao significativa. Comocada refatoracao e pequena, e pouco provavel que essa reestruturacao cause novos proble-mas. O sistema e mantido em funcionamento apos cada refatoracao, reduzindo as chancesde um sistema ser seriamente quebrado durante a reestruturacao (FOWLER, 1999).

A refatoracao deve ser feita de forma sistematizada. Fowler (1999) e Deursen et al.(2001) apresentam diversas estrategias eficientes para refatorar. Tendo em vista que apresente investigacao visa explorar smells em codigo de testes, a seguir sao apresentadastecnicas de refatoracao propostas por Deursen et al. (2001) que buscam implementaralteracoes no codigo de teste, para que esse possa estar aderente as boas praticas:

1. Inline Resource : Para remover a dependencia entre um metodo de teste e algumrecurso externo, deve ser incorporado esse recurso no codigo de teste, configurandoum fixture no codigo de teste que contem o mesmo conteudo do recurso. Este fixturee entao usado em vez do recurso para executar o teste.

2.6 SINTESE DO CAPITULO 45

2. Setup External Resource : Caso seja necessario que um teste dependa de re-cursos externos, como diretorios, bancos de dados ou arquivos, deve ser verificadose o teste que os utilizam criam ou alocam esses recursos explicitamente antes detesta-los e os liberem ao finalizar.

3. Make Resource Unique : Muitos problemas se originam do uso de nomes derecursos sobrepostos, seja entre testes diferentes executados pelo mesmo usuario ouentre execucoes de teste simultaneas feitas por usuarios diferentes. Esses problemaspodem ser evitados ou corrigidos a partir da utilizacao de identificadores exclusivospara todos os recursos alocados, por exemplo, incluindo um registro de data e hora.Uma boa pratica e incluir o nome do teste responsavel por alocar o recurso nesseidentificador, assim, havera menos problemas ao encontrar testes que nao liberemadequadamente seus recursos.

4. Reduce Data : Esse tipo de refatoracao consiste em minimizar os dados confi-gurados em fixtures para apenas o que for essencial, pois essa alteracao resultaraem dados mais adequados a documentacao e seus testes serao menos sensıveis amudancas.

5. Add Assertion Explanation : Os assertions do framework JUnit possuem umprimeiro argumento opcional para fornecer uma mensagem explicativa ao usuarioquando o assertion falha. Logo, uma forma de tornar o teste mais compreensıvele utilizando essa mensagem para distinguir entre diferentes assertions que ocorremno mesmo teste.

6. Introduce Equality Method : Se uma estrutura de objeto precisar ser verifi-cada quanto a igualdade nos testes, adicione uma implementacao para o metodo“equals” para a classe do objeto. Dessa forma, os testes podem ser reescritos parausar este metodo. Se um teste retorna apenas uma string, construa explicitamenteum objeto contendo o valor esperado e use o novo metodo equals para compara-loao objeto realmente calculado.

2.6 SINTESE DO CAPITULO

Este capıtulo abordou os fundamentos conceituais necessarios a compreensao desta pes-quisa. O tema qualidade foi abordado nas dimensoes de processo e produto. Foramtambem apresentadas diferentes estrategias de teste. Logo em seguida, foram aborda-dos os conceitos de bad smells de codigo e testes, com suas respectivas categorizacoes, etecnicas de refatoracao aplicadas ao codigo de teste.

Reconhecendo a importancia dos assuntos discutidos e a necessidade de identificar ecorrigir anti-padroes, o proximo capıtulo apresenta uma variedade de ferramentas ana-lisadoras de anti-padroes especificamente para codigo de producao (code smells) e teste(test smells) presentes na literatura.

Capıtulo

3IDENTIFICACAO E REFATORACAO AUTOMATIZADA

DE SMELLS

Os smells sao fragmentos de codigo que podem dificultar a evolucao e a manutencao dosartefatos de software, sejam eles no codigo-fonte do software (code smells) ou nos arquivosde teste (test smells). A analise de smells pode ser um desafio no processo de busca pelaqualidade do software, e isso tem motivado um crescente esforco, por parte da comuni-dade cientıfica, de implementar tecnicas de deteccao automatizada de smells (PAIVA etal., 2015; FONTANA; BRAIONE; ZANONI, 2012; VETRO; MORISIO; TORCHIANO,2011).

Prevenir, detectar e corrigir manualmente smells nao sao praticas aplicaveis a umgrande conjunto de testes (GAROUSI; KUCUK; FELDERER, 2018). Neste sentido, apopularidade de ferramentas para analise de qualidade do software tem crescido cadavez mais (SAARIMAKI et al., 2019). Dentre as ferramentas existentes que visam me-lhorar a qualidade dos artefatos de software, destacam-se as abordagens relacionadas amanutenibilidade do produto de software.

Garousi, Kucuk e Felderer (2018) realizaram uma revisao da literatura sobre testsmells a qual teve a finalidade de apresentar um catalogo de test smells juntamentecom um resumo de diretrizes, tecnicas e ferramentas usadas para lidar com os codigo deteste. Das 166 fontes analisadas, Garousi, Kucuk e Felderer (2018) encontraram 24 fontes(14,4%) que apresentam ferramentas para lidar com qualidade de testes. Contudo, apenasalgumas ferramentas estao disponıveis para download: TRex, TeReDetect, TestLint,TestHound, OraclePolish, TeCReVis, Similar Test Method Detector e TestQ.

Neste capıtulo, alem das ferramentas mencionadas por Garousi, Kucuk e Felderer(2018), serao abordadas outras ferramentas que tambem visam melhorar a qualidade dosoftware atraves do calculo de metricas e da analise de anti-padroes. As ferramentas aquiapresentadas dao suporte a codigo de producao e codigo de teste. O capıtulo esta divididoconforme a distribuicao apresentada a seguir:

47

48 IDENTIFICACAO E REFATORACAO AUTOMATIZADA DE SMELLS

Secao 3.1 apresenta as ferramentas de analise do codigo de producao;

Secao 3.2 apresenta as ferramentas de analise do codigo de teste; e

Secao 3.3 apresenta uma sıntese geral sobre as ferramentas discutidas.

3.1 FERRAMENTAS PARA CODIGO DE PRODUCAO

PTIDEJ. O projeto PTIDEJ1 (Pattern Trace Identification, Detection, and Enhance-ment in Java) foi desenvolvido em 2001 e e composto por ferramentas que auxiliam noprocesso da garantia da qualidade de softwares orientados a objetos (GUEHENEUC,2005).

Atraves da interface do usuario do conjunto de ferramentas e possıvel criar um modelode programa e identificar micro-arquiteturas semelhantes a um padrao de design, alem dechamar varios geradores, analises e ferramentas externas no modelo de programa. Atu-almente, ele e considerado um conjunto completo de ferramentas de engenharia reversaque inclui varios algoritmos de identificacao, os quais visam facilitar o desenvolvimentode novos algoritmos de identificacao e analise.

O PTIDEJ faz parte do modulo do DECOR e de acordo com Moha e Gueheneuc (2007)e Moha et al. (2009), este modulo permite a deteccao de defeitos de design. Atual-mente, o DECOR detecta dezoito tipos de code smells, sao eles: Anti Singleton, Base ClassKnows Derived Class, Base Class Should Be Abstract, Blob, Class Data Should Be Pri-vate, Complex Class, Functional Decomposition, Large Class, Lazy Class, Long Method,Long Parameter List, Many Field Attributes But Not Complex, Message Chains, RefusedParent Bequest, Spaghetti Code, Speculative Generality, Swiss Army Knife e TraditionBreaker.

PMD. O PMD (Programming Mistake Detector)2 e uma ferramenta open-souce paraanalise de problemas em codigos escritos na linguagem Java, e em outras seis linguagensde programacao. O PMD encontra falhas de programacao comuns, como variaveis naoutilizadas, blocos de metodos vazios, criacao desnecessaria de objetos, por exemplo. Aferramenta e instalada como um plugin do Eclipse IDE e conforme Paiva et al. (2015)a ferramenta da suporte a uma grande lista de code smells : Abstract Class Without AnyMethod, Avoid Catching Generic Exception, Avoid Deeply Nested If Stmts, Avoid Reth-rowing Exception, Avoid Throwing New Instance Of Same Exception, Avoid ThrowingNull Pointer Exception, Avoid Throwing Raw Exception Types, Avoid Unchecked Excep-tions In Signatures, Class With Only Private Constructors Should Be Final, CollapsibleIf Statements, Coupling Between Objects, Cyclomatic Complexity, Data Class, Do NotExtend Java Lang Error, Exception As Flow Control, Excessive Class Length, ExcessiveImports, Excessive Method Length, Excessive Parameter List, Excessive Public Count,Final Field Could Be Static, God Class, Immutable Field, Law Of Demeter, Logic Inver-

1Disponıvel em 〈http://www.ptidej.net/〉2Disponıvel em 〈https://pmd.github.io/〉

3.1 FERRAMENTAS PARA CODIGO DE PRODUCAO 49

sion, Loose Package Coupling, Modified Cyclomatic Complexity, Ncss Constructor Count,Ncss Count, Ncss Method Count, Ncss Type Count, N Path Complexity, Signature DeclareThrows Exception, Simplified Ternary, Simplify Boolean Assertion, Simplify Boolean Ex-pressions, Simplify Boolean Returns, Simplify Conditional, Singular Field, Std CyclomaticComplexity, Switch Density, Too Many Fields, Too Many Methods, Useless OverridingMethod, Use Object For Clearer API e Use Utility Class.

Figura 3.1 Visualizacao de problemas detectados com PMD no Eclipse IDE - Code SmellOverrideBothEqualsAndHashcode

As Figuras 3.1 e 3.2 apresentam as violacoes dos code smellsOverrideBothEqualsAndHashcode e LawOfDemeter detectados pelo plugin PMD, respec-tivamente.

Checkstyle. O Checkstyle3 e uma ferramenta de desenvolvimento para auxiliar aescrita de codigo Java seguindo um padrao de codificacao (FONTANA; BRAIONE; ZA-NONI, 2012). A ferramenta foi desenvolvida inicialmente por Oliver Burn em 2001, e

3Disponıvel em 〈https://checkstyle.sourceforge.io/〉

50 IDENTIFICACAO E REFATORACAO AUTOMATIZADA DE SMELLS

Figura 3.2 Visualizacao de problemas detectados com PMD no Eclipse IDE - Code SmellLawOfDemeter

atualmente, o projeto e mantido por uma equipe global de desenvolvedores. Ela e capazde detectar os seguintes code smells: Large Class, Long Method, Long Parameter List, eDuplicated Code.

Checkstyle automatiza o processo de verificacao do codigo Java. Alem de veri-ficar muitos aspectos do codigo fonte (ex. encontrar problemas de design de classe emetodo), a ferramenta tambem verifica o layout do codigo e os problemas de formatacao(CHECKSTYLE, 2020).

O Checkstyle pode ser utilizado em diferentes ambientes de desenvolvimento, e custo-mizavel e suporta diferentes padroes de codificacao. Para tanto, um exemplo de arquivosde configuracao e fornecido com suporte para as convencoes de codigo da Sun, GoogleJava Style, conforme descrito em Checkstyle (2020).

A Figura 3.34 mostra os problemas de design identificados pelo plugin Checkstyle.Os problemas relatados estao relacionados principalmente a convencoes e padroes decodigo Java (ausencia do Javadoc, por exemplo) e relacionado a estrutura do codigo,

4〈http://tirthalpatel.blogspot.com/2014/01/static-code-analyzers-checkstyle-pmd-findbugs.html〉

3.1 FERRAMENTAS PARA CODIGO DE PRODUCAO 51

como a declaracao do campo como final. A correcao desses anti-padroes pode melhorarsignificativamente a manutencao do codigo.

Figura 3.3 Problemas detectados com Checkstyle no Eclipse IDE

FindBugs. O FindBugs5 e uma ferramenta de analise estatica de codigo aberto queanalisa arquivos de classe Java em busca de defeitos de programacao (AYEWAH etal., 2008; AYEWAH et al., 2007). O FindBugs possui uma arquitetura de plugins, naqual detectores podem ser definidos. Cada detector pode relatar varios padroes de errosdiferentes (AYEWAH et al., 2007).

Como descrito em Ayewah et al. (2007), o FindBugs pode ser executado a partir dalinha de comando, Ant ou Maven, ou em uma GUI, como por exemplo o Eclipse IDE

ou NetBeans. Os resultados da analise podem ser salvos em arquivos .xml, que podemser posteriormente filtrados, transformados ou importados para um banco de dados.

5Disponıvel em 〈http://findbugs.sourceforge.net/〉

52 IDENTIFICACAO E REFATORACAO AUTOMATIZADA DE SMELLS

SonarQube. O SonarQube6 consiste em uma aplicacao de codigo aberto com o objetivode avaliar a qualidade de projetos de software (GARCIA-MUNOZ; GARCIA-VALLS;ESCRIBANO-BARRENO, 2016; FERENC et al., 2014).

O SonarQube pode ser utilizado de modo integrado ao fluxo de trabalho existentepara permitir a inspecao contınua de codigo nas ramificacoes do projeto. Seus recursosautomaticos sao redirecionados de modo a revisar codigo, detectar erros, vulnerabilida-des e code smells. O SonarQube segue sete pilares de qualidade: design/arquitetura,duplicacoes, comentarios, testes de unidade, complexidade, possıveis bugs e regras decodificacao.

O SonarQube da suporte as seguintes linguagens de programacao: Java, C#, PHP,JavaScript, TypeScript, C/C++, Ruby, Kotlin, Go, COBOL, PL/SQL, PL/I, ABAP, VB.NET,VB6, Python, RPG, Flex, Objective-C, Swift, CSS, HTML e XML. Para sua execucao, enecessario o Java (Oracle JRE 11 ou OpenJDK 11) instalado.

A Figura 3.4 mostra a tela inicial do SonarQube com o resultado do projeto deexemplo, Calculadora de Impostos; e a Figura 3.5 exibe os code smells apontados peloSonarQube de forma mais detalhada no codigo de producao. As metricas dos problemasanalisados podem ser customizadas pelo usuario, facilitando assim a criteriosidade paradiferentes projetos.

Figura 3.4 Tela inicial do SonarQube com o resultado do projeto.

6Disponıvel em 〈https://www.sonarqube.org/〉

3.1 FERRAMENTAS PARA CODIGO DE PRODUCAO 53

Figura 3.5 Detalhamento dos code smells identificados pelo SonarQube.

JDeodorant. O JDeodorant7 e um plugin do Eclipse IDE que identifica code smellsem projetos Java e os resolve aplicando as refatoracoes apropriadas. A primeira versaoda ferramenta dava suporte apenas a um smell, o Feature Envy (FOKAEFS; TSANTA-LIS; CHATZIGEORGIOU, 2007; TSANTALIS; CHATZIGEORGIOU, 2009b). Porem,durante sua evolucao, novos tipos de code smells foram integrados, assim como novastecnicas de refatoracao. Atualmente, a ferramenta da suporte a cinco tipos de codesmells, sao eles:

1. Feature Envy (FOKAEFS; TSANTALIS; CHATZIGEORGIOU, 2007; TSANTA-LIS; CHATZIGEORGIOU, 2009b);

2. Type/State Checking (TSANTALIS; CHAIKALIS; CHATZIGEORGIOU, 2008; TSAN-TALIS; CHATZIGEORGIOU, 2010);

3. Long Method (TSANTALIS; CHATZIGEORGIOU, 2009a; TSANTALIS; CHAT-ZIGEORGIOU, 2011);

4. God Class (FOKAEFS et al., 2009; FOKAEFS et al., 2011; FOKAEFS et al., 2012)

5. Duplicated Code (Krishnan; Tsantalis, 2013; KRISHNAN; TSANTALIS, 2014; TSAN-TALIS; MAZINANIAN; KRISHNAN, 2015; MAZINANIAN et al., 2016; TSANTA-LIS; MAZINANIAN; ROSTAMI, 2017).

7Disponıvel em 〈https://github.com/tsantalis/JDeodorant〉

54 IDENTIFICACAO E REFATORACAO AUTOMATIZADA DE SMELLS

Para cada tipo de code smell, ha uma refatoracao indicada, a qual e feita de formaautomatizada pelo JDeodorant. A lista das refatoracoes fornecidas pela aplicacao eapresentada a seguir:

• Os problemas de Feature Envy podem ser resolvidos por refatoracoes apropriadascom Move Method.

• Os problemas de Type Checking podem ser resolvidos por refatoracoes apropriadascom Replace Conditional with Polymorphism.

• Os problemas de State Checking podem ser resolvidos por refatoracoes apropriadascom Replace Type code with State/Strategy.

• Os problemas de Long Method podem ser resolvidos por refatoracoes apropriadascom Extract Method.

• Os problemas de God Class podem ser resolvidos por refatoracoes apropriadas comExtract Class.

• Os problemas de God Class podem ser resolvidos por refatoracoes apropriadas comExtract Clone.

Na ferramenta JDeodorant, a deteccao de code smells e feita atraves da API AST-Parser para identificar as declaracoes switch/if. Para aplicar as refatoracoes, o pluginutiliza a API ASTRewrite. De acordo com a avaliacao feita por Tsantalis, Chaikalis eChatzigeorgiou (2008)8, a ferramenta identifica os code smells corretamente e tambemaplica as refatoracoes conforme descrito na literatura.

As oportunidades de refatoracao identificadas para a refatoracao de Extract Class,por exemplo, sao virtualmente realizadas para calcular o valor da metrica resultante doposicionamento da entidade sem causar alteracoes no codigo-fonte. As sugestoes resul-tantes sao agrupadas pela classe de origem e apresentadas em um formato de tabela emarvore, como apresentado na Figura 3.6. A Figura 3.6 apresenta uma visao geral doplugin JDeodorant: 1) O menu “Bad Smells”; 2) A visao “God Class”; 3) O Exploradorde Projetos; 4) O botao de identificacao; 5) O ıcone de expansao e o formato da tabelaem arvore; 6) O editor destacado; 7) O botao aplicar; e 8) O assistente de visualizacao(FOKAEFS et al., 2011).

Apesar da proposta do RefActorIng test Design Errors (RAIDE) ser similar aferramenta JDeodorant, o JDeodorant tem o objetivo de melhorar a qualidade do codigo-fonte de producao, enquanto a ferramenta RAIDE tem como foco a qualidade dos testes.

8O trabalho de Tsantalis, Chaikalis e Chatzigeorgiou (2008) foi resultado de uma pesquisa realizadano Laboratorio de Refatoracao de Software do Departamento de Ciencia da Computacao e Engenha-ria de Software da Universidade de Concordia (Canada) e do Grupo de Engenharia de Software doDepartamento de Informatica Aplicada da Universidade da Macedonia, Thessaloniki, Grecia.

3.2 FERRAMENTAS PARA CODIGO DE TESTE 55

Figura 3.6 Visao geral do plugin JDeodorant (FOKAEFS et al., 2011)

3.2 FERRAMENTAS PARA CODIGO DE TESTE

TRex. Codigos de teste escritos utilizando a notacao principal do Testing and Test

Control Notation (TTCN-3) sao suscetıveis a mas praticas de design assim como codigode producao e codigo escritos em Java com JUnit. Embora haja esforco por parte dosdesenvolvedores para escrever codigos de teste com a notacao TTCN-3 com qualidade, ecomum que anti-padroes sejam inseridos. Segundo Zeiß (2006), os conjuntos de testespadronizados geralmente possuem poucos arquivos, limitados a dez mil linhas de codigo.

A ferramenta TRex9 foi desenvolvida como um plugin do Eclipse IDE, e fornece ainfraestrutura para auxiliar refatoracoes de anti-padroes especıficos do TTCN-3. A TRex

calcula metricas TTCN-3 e sugere refatoracoes para o teste TTCN-3 com base nas metricascalculadas. A TRex contempla as refatoracoes Rename , Inline Template , InlineTemplate Parameter e Merge Template .

A Figura 3.7 apresenta uma visualizacao geral do plugin TRex. Na perspectivaProblems view, os smells coletados pelo TRex sao identificados e apresentados ao usuariode forma detalhada indicando a classe e a localizacao. A Figura 3.8 demonstra a refa-toracao Inline Template feita atraves de um assistente para a visualizacao.

9Disponıvel em 〈http://www.trex.informatik.uni-goettingen.de/trac〉

56 IDENTIFICACAO E REFATORACAO AUTOMATIZADA DE SMELLS

Figura 3.7 Visao geral do plugin TRex

Figura 3.8 Assistente para a visualizacao da refatoracao com TRex

3.2 FERRAMENTAS PARA CODIGO DE TESTE 57

TeReDetect. Ferramenta que adaptou os recursos do CodeCover10, um plugin doEclipse IDE que mede a cobertura e outras metricas de teste. O objetivo de TeReDetecte medir metricas de teste e consequentemente detectar redundancia de teste. O TeReDetect

e um projeto de codigo aberto que foi integrado ao CodeCover, logo o TeReDetect nao eum plugin independente (KOOCHAKZADEH; GAROUSI, 2010b).

O TeReDetect apresenta uma lista de classes e as metricas calculadas de cada classe,o que permite ao desenvolvedor classificar artefatos de teste atraves das metricas. AFigura 3.9 apresenta uma visao da ferramenta TeReDetect durante a analise do projetoAllelogram (KOOCHAKZADEH; GAROUSI, 2010b).

Figura 3.9 Visao geral do TeReDetect

TestLint. O TestLint11 e uma abordagem para detectar falhas de projeto nos testesde forma automatizada. O TestLint analisa o codigo de teste escrito com a linguagemSmalltalk e contem um mecanismo baseado em regras, semelhante ao Smalllint12 (fer-ramenta que analisa mais de 60 tipos comuns de erros) e, por isso, foram reutilizadasalgumas ideias conceituais do Smalllint para analise dos testes (REICHHART, 2007;REICHHART; GIRBA; DUCASSE, 2007).

As regras implementadas no TestLint permitem que um test smell seja identificadoem todas as classes ou que apenas algumas metricas relacionadas aos testes sejam cole-tadas. Alem disso, as regras podem ser aplicada aos metodos de teste ou as classes deteste (REICHHART; GIRBA; DUCASSE, 2007).

10Disponıvel em〈http://codecover.org/〉11Disponıvel em 〈http://scg.unibe.ch/wiki/alumni/stefanreichhart/testsmells〉12Disponıvel em 〈https://refactory.com/smalllint-2/〉

58 IDENTIFICACAO E REFATORACAO AUTOMATIZADA DE SMELLS

O TestLint contempla a identificacao de test smells estaticos, procurando padroesespecıficos. Suas regras analisam a arvore de origem para detectar itens especıficos do noe tambem calcula metricas no codigo de teste. Essa analise permite que o codigo de testeseja analisado sem executar ou instrumentar o teste. O TestLint da suporte aos seguintestipos de test smells : Guarded Test, Overreferencing, Assertionless Test, Proper Organi-zation, Test-MethodCategory Name, Anonymous Test, Long Test, Mixed Selectors, Likelyineffective Object-Comparison, Unclassified MethodCategory, Test-Class Name, UnusedShared-Fixture Variables, Early Returning Test, Unusual Test Order, Under-the-carpetAssertion, Comments Only Test, Overcommented Test, Under-the-carpet failing Asser-tion, Control Logic, Max Instance Variables, Teardown Only Test, Abnormal UTF-Use,Empty Shared-Fixture, Transcripting Test, Empty MethodCategory, Returning Assertione Empty Test-MethodCategory (REICHHART; GIRBA; DUCASSE, 2007).

TestHound. O TestHound13 e uma tecnica de analise estatica para identificar testsmells relacionados a fixture (Greiler; van Deursen; Storey, 2013). A ferramenta contem-pla a analise dos seguintes test smells : General Fixture, Test Maverick, Dead Fields, Lackof Cohesion of Test Methods, Obscure In-Line Setup e Vague Header Setup. O TestHound

fornece relatorios sobre os test smells e orienta as atividades de melhoria para o codigode teste.

O TestHound e implementado em Java e suporta linguagens que sao compiladas parao bytecode Java e o TestHound utiliza a biblioteca Apache BCEL para extrair informacoesdos testes. O TestHound analisa o codigo de teste em Java estruturados com JUnit eTestNG (Greiler; van Deursen; Storey, 2013). O TestHound esta disponıvel para down-load, mas nao possui codigo aberto.

A Figura 3.10 apresenta a visao geral do executavel TestHound antes de executar aanalise dos test smells. A Figura 3.11 apresenta um trecho de relatorio de test smellsidentificados no projeto eGit. A Figura 3.12 apresenta um relatorio aprimorado de de-talhes sobre a classe de teste BlobStorageTest e sugere possıveis tecnicas para refatoraro General Fixture.

OraclePolish. Embora os testes de software sejam conceitualmente simples, geralmentesao difıceis de escrever na pratica. Casos de teste sao compostos de duas partes, asentradas usadas para executar o programa em teste e um oraculo utilizado para verificarse a execucao induzida pelas entradas produz os resultados esperados (HUO; CLAUSE,2014). Contudo, e comum que essas caracterısticas produzem uma situacao em que osdesenvolvedores tem um entendimento incompleto de quais entradas um programa podereceber e a forma como o programa deve se comportar e de quais saıdas deve produzir.Sendo assim, escrever oraculos e um desafio constante da producao de codigo de teste.Como resultado, os desenvolvedores geralmente criam oraculos que verificam muito pouco,resultando em testes incapazes de detectar falhas ou verificam demais, resultando emtestes que sao frageis e difıceis de manter (HUO; CLAUSE, 2014).

Buscando solucionar esse problema, foi criada uma tecnica para analisar automati-

13Disponıvel em 〈https://github.com/SERG-Delft/TestHound〉

3.2 FERRAMENTAS PARA CODIGO DE TESTE 59

Figura 3.10 Visao geral do TestHound

Figura 3.11 TestHound - Relatorio de test smells para o projeto eGit (Greiler; van Deursen;Storey, 2013)

camente os oraculos de teste e consequentemente identificar assertions frageis (asser-tions que dependem de valores derivados de entradas nao controladas) e entradas naoutilizadas (entradas fornecidas pelo teste que nao sao verificadas por um assertions). O

60 IDENTIFICACAO E REFATORACAO AUTOMATIZADA DE SMELLS

Figura 3.12 TestHound - Relatorio detalhado de test smells para o projeto eGit (Greiler; vanDeursen; Storey, 2013)

OraclePolish14 consiste na implementacao dessa tecnica que pode analisar testes escritosem Java e usar a estrutura de teste JUnit. De modo geral, a ferramenta OraclePolish

busca melhorar a qualidade dos oraculos detectando assertions frageis e entradas naoutilizadas (HUO; CLAUSE, 2014).

TeCReVis. A ferramenta Test Coverage and Test Redundancy Visualization(TeCReVis)15

e um plugin do Eclipse IDE para visualizacao de cobertura e redundancia de testes in-tegrado ao CodeCover. Conforme mencionado em Koochakzadeh e Garousi (2010a), oTeCReVis da suporte a testes escritos em Java com JUnit, ajudando os testadores aanalisar as informacoes de cobertura de maneira mais eficiente de maneira visual emcomparacao com as ferramentas de cobertura tradicionais baseadas em texto.

TeCReVis gera um grafo com informacoes de cobertura de teste, denominado TestCoverage Graph (TCG) e outro grafo denominado Test Redundancy Graph (TRG), pararedundancias identificadas no codigo de teste. As Figuras 3.13 e 3.14 demonstram asvisualizacoes dos grafos TCG e TRG, respectivamente (KOOCHAKZADEH; GAROUSI,2010a).

Na Figura 3.13, o lado esquerdo representa itens de teste e o lado direito do graficorepresenta itens de SUT. Na Figura 3.14, os metodos de teste sao representados por cadano, as arestas de um no para outro no representam artefatos de codigo em comum entredois metodos de teste, e os valores representam a proporcao entre o numero de itens doSUT cobertos pelos dois metodos de teste e o numero de itens do SUT cobertos peloprimeiro caso de teste (KOOCHAKZADEH; GAROUSI, 2010a).

Atraves da ferramenta TeCReVis e possıvel modificar os criterios de cobertura e agranularidade do SUT (e.g. declaracao, decisao, classe ou pacote) e tambem artefatos deteste (e.g. pacote de teste, classe e metodo no xUnit) Koochakzadeh e Garousi (2010a).

14Disponıvel em 〈https://bitbucket.org/udse/〉15Disponıvel em 〈http://www.codecover.org/〉

3.2 FERRAMENTAS PARA CODIGO DE TESTE 61

Figura 3.13 TeCReVis - Test Coverage Graph (KOOCHAKZADEH; GAROUSI, 2010a)

Figura 3.14 TeCReVis - Test Redundancy Graph (KOOCHAKZADEH; GAROUSI, 2010a)

Similar Test Method Detector. A ferramenta Similar Test Method Detector16

e uma abordagem baseada na tecnica assertion fingerprints, proposta por Fang (2014),para identificar codigo de teste clonado em projetos Java com JUnit. Similar Test

Method Detector e uma ferramenta utilizada via linha de comando e utiliza estruturasdo framework Soot17. A tecnica assertion fingerprints se concentra na estrutura dosmetodos de teste e nao na estrutura dos assertions especificamente. Essa abordagemproporciona ao usuario uma analise do conjunto de testes e tambem exibe conjuntosde metodos de teste provavelmente clonados, juntamente com as evidencias, que podemauxiliar o desenvolvedor na tomada de decisao para extrair os clones (FANG, 2014).

TestQ. Considerando que a necessidade de encontrar defeitos no inıcio do ciclo dedesenvolvimento resultaram em um aumento no interesse em testes de unidade e que ostestes precisam co-evoluir com o sistema de producao, e essencial cuidar da qualidadedos testes de software. Nesse sentido, Breugelmans e Rompaey (2008) propuseram aferramenta TestQ, que permite aos desenvolvedores (i) explorar visualmente os conjuntosde testes e (ii) quantificar a presenca de test smells estaticos (ou seja, instancias de testsmells que podem ser identificados pela inspecao do design e do codigo-fonte de umconjunto de testes) em teste.

A ferramenta tem como objetivo avaliar a capacidade de manutencao do codigo de

16Disponıvel em 〈https://bitbucket.org/felixfangzh/similartestanalysis/src/master/〉17Disponıvel em 〈https://github.com/soot-oss/soot〉 para analise do codigo

62 IDENTIFICACAO E REFATORACAO AUTOMATIZADA DE SMELLS

teste, buscando responder a pergunta: “Qual e a capacidade de manutencao do meucodigo de teste de unidade?”(BREUGELMANS; ROMPAEY, 2008).

Figura 3.15 Grafico de visualizacao de test smells gerados com TestQ (BREUGELMANS;ROMPAEY, 2008)

A ferramenta da suporte aos seguintes test smells : Assertionless, Assertion Roulette,Duplicated Code, Eager Test, Empty Test, For Testers Only, General Fixture, IndentedTest, Indirect Test, Mystery Guest, Sensitive Equality e Verbose Test. A Figura 3.15 mos-tra um grafico de visualizacao de dados estatısticos sobre test smells, analisados atravesda ferramenta TestQ.

O TestQ contem um conjunto de visualizacoes que revela test smells no codigo. Cadatest smell e representado como um no, conectado a entidade de teste que e impactada. Aosobrepor o mouse em um no, mais informacoes detalhadas sobre cada uma das instanciasde test smell ficam disponıveis.

tsDetect. O Test Smell Detector (tsDetect) possui um sistema de deteccao queabrange 21 Test Smels. Sao eles: Assertion Roulette, Conditional Test Logic, ConstructorInitialization, Default Test, Empty Test, Exception Catching Throwing, General Fixture,

3.2 FERRAMENTAS PARA CODIGO DE TESTE 63

Figura 3.16 Processo para executar a ferramenta tsDetect

Mystery Guest, Print Statement, Redundant Assertion, Sensitive Equality, Verbose Test,Sleepy Test, Eager Test, Lazy Test, Duplicate Assert, Unknown Test, Ignored Test, Re-source Optimism, Magic Number Test e Dependent Test.

O processo de identificacao de test smells realizado pelo tsDetect consiste na execucaode 3 ferramentas18 (conforme mostra a Figura 3.16):

1. Test File Detector : detecta os arquivos de teste de unidade do projeto;

2. Test File Mapping : vincula os arquivos de teste de unidade aos arquivos deproducao que estao sendo testados;

3. Test Smell Detector : detecta test smells no codigo de teste.

Na primeira etapa, o Test File Detector e executado passando como parametro o di-retorio do projeto de software a ser analisado. Esta etapa gera o arquivo Testes.csv

(Figura 3.16), que contem os caminhos das classes de teste. Este arquivo deve ser ma-nipulado manualmente como entrada no Test File Mapping. A segunda etapa e o TestFile Mapping, que estabelece o relacionamento entre as classes de teste e as classes deproducao. Esta etapa cria o arquivo Classes.csv (Figura 3.16), que contem o nomedo aplicativo, o caminho de cada classe de teste e as classes de producao. Este arquivodeve ser manipulado manualmente como entrada no Test Smell Detector. Por fim, o TestSmell Detector e responsavel por analisar os test smells do projeto, com base no arquivoClasses.csv. A saıda e o arquivo Resultados.csv, que contem a indicacao da presencaou ausencia de test smells por classe de teste (Figura 3.16).

Alem das tres colunas do arquivo Classes.csv, o arquivo Resultados.csv tambempossui uma coluna para cada tipo de test smell. Cada coluna de tipo possui um resultado

18〈https://testsmells.github.io/〉

64 IDENTIFICACAO E REFATORACAO AUTOMATIZADA DE SMELLS

booleano, true ou false. Assim, para cada classe de teste, o arquivo mostra a presenca(true) ou ausencia (false) de cada test smells. A Tabela 3.1 lista os dados gerados pelotsDetect: metadados do projeto (linhas 1 a 6) e test smells identificaveis (linhas 7 a 27).

Tabela 3.1 Arquivo de saıda tsDetect

# Coluna Descricao Tipo de dado

1 App Nome Projeto String

2 Version Versao do Projeto String

3 TestFilePath Caminho do arquivo da classe de teste String

4 ProductionFilePath Caminho do arquivo de producao String

5 RelativeTestFilePath Caminho do arquivo de teste relativo String

6 RelativeProductionFilePath Caminho do arquivo relativo de producao String

7 Assertion Roulette Test Smell Boolean

8 Conditional Test Logic Test Smell Boolean

9 Constructor Initialization Test Smell Boolean

10 Default Test Test Smell Boolean

11 Dependent Test Test Smell Boolean

12 Duplicate Assert Test Smell Boolean

13 Eager Test Test Smell Boolean

14 EmptyTest Test Smell Boolean

15 Exception Catching Throwing Test Smell Boolean

16 General Fixture Test Smell Boolean

17 IgnoredTest Test Smell Boolean

18 Lazy Test Test Smell Boolean

19 Magic Number Test Test Smell Boolean

20 Mystery Guest Test Smell Boolean

21 Print Statement Test Smell Boolean

22 Redundant Assertion Test Smell Boolean

23 Resource Optimism Test Smell Boolean

24 Sensitive Equality Test Smell Boolean

25 Sleepy Test Test Smell Boolean

26 Unknown Test Test Smell Boolean

27 Verbose Test Test Smell Boolean

JNose Test. A ferramenta JNose Test19 foi desenvolvida com o intuito de proverdeteccao automatizada de test smells e coleta de metricas em codigo de teste desenvolvidona linguagem Java(VIRGINIO et al., 2019; VIRGINIO et al., 2020b; VIRGINIO et al.,2020a). O JNose Test e uma extensao da ferramenta tsDetect e pode ser consideradocomo uma evolucao integrada dos tres projetos utilizados pelo tsDetect, mencionadosna subsecao anterior. A ferramenta apresenta uma interface grafica web e inclui a coletaautomatizada de metricas de codigo e de cobertura. A ferramenta, alem de automatizartodo o processo de execucao, consegue executar a analise de varios projetos que estejamem um mesmo diretorio, gerando somente um arquivo de saıda.

Tambem foi acrescentado um novo conjunto de dados, tais como, Linhas de Codigo(LOC), Quantidade de Metodos de Testes (QMT) e dados de cobertura do teste, queforam utilizados no estudo Virgınio et al. (2019). A Tabela 3.2 lista os dados geradospelo JNose Test: metadados do projeto (linhas 1 a 3), os test smells identificaveis (linhas

19Disponıvel em 〈https://github.com/tassiovirginio/jnose〉

3.3 SINTESE DO CAPITULO 65

4 a 24), tamanho da classe de teste - LOC (linha 25), quantidade de metodos de testes -QMT (linha 26) e as metricas de cobertura (linhas 27 a 36).

Figura 3.17 Captura da tela principal do JNose Test

A Figura 3.17 apresenta a tela inicial da ferramenta JNose Test. Segue a descricaode cada etapa da Figura 3.17: (1) com o campo de texto para o caminho do diretorioonde se encontra os projetos a serem analisados e o botao Selecionar Diretorio. Logoabaixo (2) sao apresentados os projetos detectados automaticamente, os quais poderaoser ou nao selecionados para o processamento. Abaixo da lista de projetos encontra-se obotao Processar (3). Uma observacao necessaria e sobre o checkbox logo no inıcio da tela(4), que permite a analise de cobertura de testes. No textarea (5), sao apresentados oslogs do sistema (sem os logs de erro). No textarea (6) sao apresentados os logs de erro.Na parte inferior (7), e apresentado o botao para realizar o download dos resultados. Abarra (8) apresenta o progresso do processamento.

3.3 SINTESE DO CAPITULO

Algumas ferramentas sao desenvolvidas para melhorar a qualidade do codigo duranteo desenvolvimento de software, outras para apoiar as atividades de reengenharia e ma-nutencao. Cada ferramenta possui suas particularidades, como por exemplo os tiposde smells que a ferramenta suporta, e cabe ao desenvolvedor avaliar qual tecnologia se

66 IDENTIFICACAO E REFATORACAO AUTOMATIZADA DE SMELLS

Tabela 3.2 Retorno da execucao do JNose Test

# Parametro Descricao

1 App Nome do Projeto

2 TestFileName Nome da Classe de Teste

3 ProductionFileName Nome da Classe de Producao

4 Assertion Roulette (AR) Test Smell

5 Conditional Test Logic (CTL) Test Smell

6 Constructor Initialization (CI) Test Smell

7 Default Test (DT) Test Smell

8 EmptyTest (ET) Test Smell

9 Exception Catching Throwing/Exception Handling (ECT) Test Smell

10 General Fixture (GF) Test Smell

11 Mystery Guest (MG) Test Smell

12 Print Statement/Redundant Print (PS) Test Smell

13 Redundant Assertion (RA) Test Smell

14 Sensitive Equality (SE) Test Smell

15 Verbose Test/Complex Test (VT) Test Smell

16 Sleepy Test (ST) Test Smell

17 Eager Test (ET) Test Smell

18 Lazy Test (LT) Test Smell

19 Duplicate Assert (DA) Test Smell

20 Unknown Test (UT) Test Smell

21 IgnoredTest (IT) Test Smell

22 Resource Optimism (RO) Test Smell

23 Magic Number Test (MNT) Test Smell

24 Dependent Test/Interdependent Tests (DpT) Test Smell

25 LOC Quantidade de Linhas de Teste

26 Number of methods Quantidade de Metodos de Teste

27 Instruction Missed (Opcional) Instrucoes Perdidas

28 Instruction Covered (Opcional) Instrucoes Cobertas

29 Branch Missed (Opcional) Ramos Perdidos

30 Branch Covered (Opcional) Ramos Cobertos

31 Line Missed (Opcional) Linhas Perdidas

32 Line Covered (Opcional) Linhas Cobertas

33 Complexity Missed (Opcional) Complexidade Perdida

34 Complexity Covered (Opcional) Complexidade Coberta

35 Method Missed (Opcional) Metodos Perdidos

36 Method Covered (Opcional) Metodos Cobertos

adapta melhor a realidade do projeto. Em alguns casos, pode ser necessario a utilizacaode alguma dessas ferramentas em conjunto para obter maior exito no calculo de metricase na analise de smells.

A maioria das ferramentas nao e capaz de executar a refatoracao automatizada doscode smells detectados. O JDeodorant e a unica ferramenta que oferece opcoes de re-fatoracao e por isso, destaca-se entre as demais ferramentas. Quanto as ferramentasanalisadoras de test smells, o tsDetect e uma das ferramentas que tem sido mais difun-didas na literatura. Entretanto, a tsDetect e subdividida em etapas nao integradas, oque pode tornar nao-trivial o processo de analise.

Nesse contexto, o levantamento das ferramentas analisadoras de code smells e testsmells foram essenciais para adquirir conhecimento e construir a ferramenta RAIDE, aproposta desta dissertacao. O proximo capıtulo aborda a ferramenta RAIDE em detalhes.

Capıtulo

4RAIDE

Os test smells sao anti-padroes de codigo de teste que correspondem a mas decisoes dedesign ou implementacao, que podem afetar a compreensibilidade e a manutencao dosoftware (DEURSEN et al., 2001). A analise manual de test smells (e.g. prevencao,deteccao e correcao) pode ser uma tarefa suscetıvel a erros e impraticavel em projetosde larga escala. Apesar disso, existem poucas tecnicas e ferramentas na literatura paraoferecer suporte a analise automatizada de test smells e melhorar a qualidade do codigode teste em projetos Java com JUnit.

Deteccao e refatoracao de test smells sao tarefas desafiadoras. No entanto, as fer-ramentas existentes nao costumam implementar tais recursos. O recurso comumenteimplementado e o de indicar a quantidade de test smells existentes ou a ocorrencia de umdeterminado test smell em uma classe de teste. Porem, isso pode nao ser suficiente paratornar intuitivo o processo de refatoracao de testes. Alem disso, as ferramentas existentesnao sao integradas a IDEs e geralmente nao apresentam uma boa experiencia de usuario.

Considerando as limitacoes das ferramentas existentes bem como a carencia por fer-ramentas de suporte a identificacao e a refatoracao de test smells para projetos Java

com JUnit, esta dissertacao de mestrado propoe o RefActorIng test Design Errors

(RAIDE)1. O RAIDE e uma ferramenta baseada em Abstract Syntax Tree (AST), desen-volvida como um plugin de codigo aberto do Eclipse IDE para detectar e refatorar testsmells em codigo de unidade em projetos Java com JUnit.

O RAIDE identifica classes, metodos e linhas de teste afetados por um test smell es-pecıfico. Tal informacao pode auxiliar desenvolvedores a verificar o codigo do teste emrelacao aos padroes de teste e melhorar sua qualidade, atraves da refatoracao. Assim, oRAIDE aprimora a maneira como os test smells identificados sao apresentados aos usuariose fornece uma interface grafica amigavel, alem de fornecer refatoracao semi-automatizadado codigo de teste com test smells.

O RAIDE faz parte de um framework conceitual em desenvolvimento por uma equipede pesquisadores interinstitucionais, que consiste em prevencao, identificacao, refatoracao

1Disponıvel em 〈https://raideplugin.github.io/RAIDE/〉

67

68 RAIDE

e visualizacao de test smells para melhorar a qualidade do codigo de teste. As ferramentasJNose Test2 e TSVizzEvolution3 tambem fazem parte desse framework.

O capıtulo contempla sete secoes, conforme descricao a seguir:

Secao 4.1 apresenta as tecnologias utilizadas pelo plugin RAIDE;

Secao 4.2 apresenta os tipos de test smells que o plugin RAIDE da suporte;

Secao 4.3 apresenta detalhes do desenvolvimento do RAIDE;

Secao 4.4 detalha os processos e etapas do plugin RAIDE;

Secao 4.5 demonstra o RAIDE atraves de um exemplo de uso;

Secao 4.6 aborda o tipo de licenca adotada para o RAIDE; e

Secao 4.7 descreve as consideracoes finais do capıtulo.

4.1 TECNOLOGIAS

Conforme a TIOBE 4, em Junho de 2019, a Linguagem de Programacao Java5 foi alinguagem mais popular (15%), seguida pela linguagem C (13,3%). Em 2020 (ate omes de Junho), Java permanece como a linguagem mais popular. A TIOBE e umaempresa especializada em avaliar e rastrear a qualidade do software, que verifica maisde 1056 milhoes de linhas de codigo de software para seus clientes em todo o mundo,em tempo real, todos os dias. Com a linguagem Java, as aplicacoes se beneficiam dodesenvolvimento de codigo apenas uma vez, sem a necessidade de “portar” seus aplicativospara todas as plataformas de software e hardware (ARNOLD et al., 2000).

Para desenvolver aplicacoes em Java, existem varios Ambientes de DesenvolvimentoIntegrado (do ingles, Integrated Development Environment-IDE ) disponıveis, e.g.,Eclipse6, NetBeans7, IntelliJ IDEA8 etc. Conforme Goth (2005), Murphy, Kerstene Findlater (2006), Eclipse e uma das IDEs preferidas entre desenvolvedores para de-senvolvimento Java. Alem de ser amplamente utilizada em ambientes de ensino (JUDD;SHITTU, 2005), a Eclipse tambem se destaca na industria (CHEN; MARX, 2005; CHA-TLEY; TIMBUL, 2005).

Uma pesquisa mais recente realizada em Junho de 2020 pelo Top IDE index 9 mostrou

2Disponıvel em 〈https://github.com/tassiovirginio/jnose〉3Disponıvel em 〈https://github.com/AdrianaPriscilaSantos/TSVizzEvolution〉4Disponıvel em 〈https://www.tiobe.com/tiobe-index/〉5Disponıvel em 〈https://www.java.com/〉6Disponıvel em 〈https://www.eclipse.org/〉7Disponıvel em 〈https://netbeans.org/〉8Disponıvel em 〈https://www.jetbrains.com/idea/〉9Disponıvel em 〈http://pypl.github.io/IDE.html〉

4.2 TIPOS DE TEST SMELLS 69

que Visual Studio10, Eclipse IDE e Android Studio11 sao as tres IDEs de uso geralmais populares, com 24.8%, 17.54% e 14.3% do market share respectivamente. O rankingcalculado pelo Top IDE index e criado analisando a frequencia de pesquisa das paginasde download das IDEs no Google. Quanto mais uma IDE e pesquisada, mais ela econsiderada popular.

Para a escolha da plataforma do plugin RAIDE, levamos em consideracao a populari-dade do Eclipse IDE para desenvolvimento com a Linguagem de Programacao Java, eas suas caracterısticas: open-source, multiplataforma e estruturado como uma colecao deplugins. Consequentemente, o RAIDE e um plugin multiplataforma para analise de testsmells em codigo de unidade em projetos Java, desenvolvido com o framework JUnit.

4.2 TIPOS DE TEST SMELLS

Embora a literatura descreva muitos test smells, estudos recentes mostram que alguns saomais frequentes que outros. Palomba et al. (2016) conduziram uma investigacao empıricasobre a difusao de test smells nas classes de teste JUnit geradas automaticamente. Elesinvestigaram 110 projetos de software de codigo aberto. Os resultados mostraram que83% das classes JUnit sao afetadas por pelo menos um test smell. Alem disso, o test smellAssertion Roulette (AR) foi o mais frequente (existente em 54% das classes), seguido peloTest Code Duplication (existente em 33% das classes JUnit).

Alem disso, Peruma (2018a) realizou um estudo empırico em larga escala sobre aocorrencia, distribuicao e impacto dos test smells na manutencao de aplicativos Androidde codigo aberto. Eles tambem observaram que AR ocorreu em mais de 50% das classesde teste. Por sua vez, Garousi e Kucuk (2018) realizaram um estudo de mapeamentosistematico multi-vocal que apresenta um catalogo mais extenso de test smells, juntamentecom o resumo de diretrizes, tecnicas e ferramentas para lidar com eles. Como resultado,o estudo mostrou que um grande numero de tipos de test smells tem sido discutido emvarias fontes. Os autores apontaram que os tipos de test smells relacionados a duplicacaoe a complexidade do codigo (e.g., Test Redundancy e Long Test, respectivamente) foramos tipos mais discutidos.

Devido a alta frequencia de AR no codigo de teste (PERUMA, 2018b; PALOMBA etal., 2016) e a repercussao nos test smells relacionados a duplicacao de codigo (GAROUSI;KUCUK, 2018), esta primeira versao do plugin RAIDE da suporte a esses dois tipos detest smells, AR e Duplicate Assert (DA). Embora a literatura nao apresente diretamenteo DA como um dos tipos de test smells com mais evidencia em projetos, ele representaum tipo especıfico de duplicacao de codigo de teste restrito a estrutura dos assertions.

4.3 DESENVOLVIMENTO DO RAIDE

Alem do RAIDE analisar testes em projetos com linguagem Java no Eclipse IDE, tambemselecionamos o Java e o Eclipse IDE para o seu desenvolvimento. Utilizamos o Eclipse

10Disponıvel em 〈https://visualstudio.microsoft.com/pt-br/vs/〉11Disponıvel em 〈https://developer.android.com/studio〉

70 RAIDE

IDE na versao Eclipse IDE for RCP and RAP Developers12 como ambiente de desen-volvimento para a implementacao do plugin RAIDE, uma versao dedicada a criacao deplugins para o Eclipse IDE. Para controlar o versionamento do nosso plugin, utilizamoso repositorio do Github13.

Para o desenvolvimento do RAIDE foram reutilizados componentes graficos doJDeodorant14, um plugin do Eclipse IDE para identificar e refatorar code smells emcodigo Java. Dentre os componentes utilizados do JDeodorant, pode-se destacar: i)Menu no Eclipse IDE; ii) Guia de visualizacao; iii) Redirecionamento do cursordo mouse e destaque da linha com test smell ; e iv) Substituicao do metodocom test smell pelo metodo refatorado (Componentes em rosa na Figura 4.1).

Figura 4.1 Principais componentes do RAIDE

Alem disso, tambem foram reutilizadas regras de deteccao do Test Smell Detector

(tsDetect)15. Dentre os componentes utilizados do tsDetect, pode-se destacar: i) ASTdo projeto; e ii) as regras de deteccao do AR (Componentes em verde na Figura 4.1).Embora o metodo de deteccao do AR utilizado no RAIDE seja original do tsDetect, foramfeitas melhorias no codigo com o proposito de contemplar outros cenarios.

A forma com que a deteccao do DA foi implementada no tsDetect nao permitiu areutilizacao do codigo para identificar com precisao a localizacao de cada test smell noRAIDE. Para detectar se uma classe foi afetada ou nao pelo test smell DA, o tsDetect

compara a lista de assertions de um metodo com um HashSet criado a partir da lista deassertions. Uma estrutura HashSet possui apenas elementos exclusivos, assim tsDetect

utiliza HashSet para remover os elementos duplicados e comparar o tamanho com alista original de assertions. Se a lista original de assertions for maior que a estruturaHashSet,tsDetect classifica o metodo como um DA. Ao final, o tsDetect classificauma classe com DA se pelo menos um metodo da classe apresenta DA. Alem disso, o

12Disponıvel em 〈https://www.eclipse.org/downloads/packages/〉13Disponıvel em 〈https://github.com/raideplugin/Plugin-RAIDE〉14Disponıvel em 〈https://github.com/tsantalis/JDeodorant〉15Disponıvel em 〈https://testsmells.github.io/〉

4.4 PROCESSOS DO RAIDE 71

tsDetect nao contempla a refatoracao dos test smells identificados.Logo, foi necessario a implementacao de alguns modulos do zero no RAIDE. Dentre os

componentes originais do RAIDE, pode-se destacar: i) Deteccao do DA; ii) Refatoracaodo AR; e iii) Refatoracao do DA (Componentes em azul na Figura 4.1). Alem disso,o RAIDE integra os processos realizados pelo tsDetect que eram feitos separadamenteem cada executavel, como por exemplo, a identificacao das classes de teste. Na proximasecao, sera detalhado cada processo realizado pelo RAIDE.

4.4 PROCESSOS DO RAIDE

A Figura 4.2 mostra uma visao geral de como RAIDE funciona. O plugin possui doisprocessos principais e um conjunto de etapas: (i) Deteccao de test smells , que detectaos test smells e os apresenta nas guias de visualizacao do Eclipse IDE (etapas 1 a 4); e(ii) Refatoracao de test smells , que inclui uma abordagem de refatoracao de codigode teste semi-automatizada para auxiliar os desenvolvedores a corrigir o codigo de testecom test smells (etapas 5 e 6). Descrevemos melhor esses processos e etapas nas proximassubsecoes.

Figura 4.2 Processos do plugin RAIDE

4.4.1 Deteccao de test smells

Para o processo de Deteccao de test smells (Figura 4.2), o usuario seleciona o tipo detest smell a ser analisado, AR ou DA (Etapa 1). Apos selecionar o tipo de test smell a seranalisado, a ferramenta executa a Identificacao das classes de teste (Etapa 2) paraidentificar as classes de teste do projeto e criar um AST para cada classe de teste. Emseguida, a ferramenta extrai informacoes sobre a estrutura do codigo por meio do AST eaplica as regras de deteccao para a Deteccao do test smell (Etapa 3). Reutilizamosas regras de deteccao da ferramenta tsDetect e realizamos melhorias nelas. O tsDetect

e uma ferramenta de deteccao de test smells, que e utilizada atraves de command lineinterface (CLI). A saıda do tsDetect informa ao usuario se um test smell esta presenteou ausente em uma classe de teste. Por sua vez, o RAIDE e integrado a um IDE e indicaa localizacao exata (linha do codigo-fonte) dos test mells. Em seguida, serao descritas asregras de deteccao para cada tipo de test smell.

72 RAIDE

Assertion Roulette (AR). Para a analisar o AR em um projeto de software, o RAIDE

inicialmente busca as classes de teste em todo o projeto. Apos identificar cada classede teste, o RAIDE analisa cada uma individualmente. Para cada metodo de cada classede teste, o RAIDE busca por estruturas de assertions (e.g., assertTrue, assertFalse,assertNull, assertSame, assertEquals) para contabilizar a quantidade de parametrose verificar se o parametro opcional esta ausente ou nao.

A depender da estrutura do assertion, pode-se variar a quantidade de parametros.Podemos agrupar os assertions em 3 categorias:

• Categoria A: estruturas que possuem 2 parametros obrigatorios e 1 parametroopcional para explicacao - assertArrayEquals, assertEquals, assertNotSame,assertSame, assertThat;

• Categoria B: estruturas que possuem 1 parametro obrigatorio e 1 parametro op-cional de explicacao - assertFalse, assertNotNull, assertNull, assertTrue)

• Categoria C: estruturas que possuem apenas 1 parametro opcional de explicacao- fail.

Se as estruturas da Categoria A possuırem menos de 3 parametros, significa queo parametro opcional da string esta faltando, logo e um candidato a AR. Da mesmaforma, se um assertion da Categoria B possuir menos de 2 parametros ou um assertionda Categoria C possuir menos que 1 parametro, eles tambem serao considerados AR.

O RAIDE reutilizou parte do codigo-fonte da ferramenta tsDetect relacionado a iden-tificacao de AR. Alem disso, estendemos as regras de deteccao do AR para tambemverificar o conteudo do parametro opcional, caso exista. RAIDE considera string vazia(“”) ou strings com uma cadeia de espaco (“ ”) como um AR. Alem disso, a cadadeteccao de um assertion com o test smell AR, o RAIDE captura a linha, metodo, classee caminho do arquivo que contem o test smell e apresenta-os em uma guia de visua-lizacao. Essa guia de visualizacao permite ao usuario clicar duas vezes nas informacoes eser redirecionado para a linha do codigo.

O Algoritmo 1 apresenta o pseudocodigo do metodo de identificacao do AR. Apos oRAIDE identificar todos os assertions de um metodo, e feita a analise de cada assertion in-dividualmente (Algoritmo 1). Nesse metodo, RAIDE verifica qual categoria que o assertionpertence (linhas 6, 11 e 16). Apos isso, e feita a verificacao pra analisar se a quantidadede parametros e menor que a quantidade total de parametros (quantidade de parametrosobrigatorios + quantidade de parametros opcionais) que a categoria possui (linhas 7,12 e 17). Se a quantidade de parametros for menor que a quantidade total, e provavelque o parametro opcional esteja ausente. Caso o parametro nao esteja ausente, o RAIDE

tambem verifica se o conteudo da string de explicacao (linhas 7, 12 e 17) do assertione vazia ou se possui uma string contendo espacos (metodo ExplanationIsEmpty()).Logo, se a quantidade de parametros for menor que a quantidade total da categoria queo assertion possui; ou se o parametro de explicacao for vazio ou com uma string deespaco, o RAIDE retorna true (linhas 8, 13 e 18) e classifica esse assertion como um AR.

4.4 PROCESSOS DO RAIDE 73

Algoritmo 1 Pseudocodigo para identificar o test smell AR1: function IsAssertionRoulette(Assertion)2: CategoryA← [assertArrayEquals, assertEquals, assertNotSame, assertSame, assertThat]3: CategoryB ← [assertFalse, assertNotNull, assertNull, assertTrue]4: CategoryC ← fail5: Name← name of Assertion6: if Name is contained in CategoryA then7: if (Assertion has ParametersSize < 3) or ExplanationIsEmpty(Assertion) then8: return true9: end if10: end if11: if Name is contained in CategoryB then12: if (Assertion has ParametersSize < 2) or ExplanationIsEmpty(Assertion) then13: return true14: end if15: end if16: if Name equals CategoryC then17: if (Assertion has ParametersSize < 1) or ExplanationIsEmpty(Assertion) then18: return true19: end if20: end if21: end function

Duplicate Assert (DA). A deteccao do test smell DA e seu processo de refatoracaosao originais e desenvolvidos para a ferramenta RAIDE, sem reutilizacao mesmo que parcialde codigo de outras ferramentas. Semelhante a analise do test smell AR, o primeiro passopara detectar o DA e identificar todas as classes de testes no projeto em questao. Emseguida, RAIDE procura estruturas de assertions e verifica se ha outro assertion dentrodo mesmo metodo com os mesmos parametros. Se duas estruturas de assertions dentrodo mesmo metodo contiverem parametros identicos, o RAIDE os classifica como DA.

O Algoritmo 2 apresenta o pseudocodigo do metodo de identificacao do DA. Aposo RAIDE identificar todos os metodos de teste e identificar os assertions do metodo, efeita a chamada para o metodo de analise do DA passando como parametro a lista deassertions do metodo que esta sendo analisado. Enquanto a analise do AR pode ser feitade forma individual para cada assertion, a analise do DA depende de todas as estruturaspara realizar as comparacoes, por isso, passamos a lista de assertions como parametro,ao inves de apenas um unico assertion.

O Algoritmo 2 cria a variavel Size e atribui a essa variavel o tamanho da lista deAssertions (linha 2). O valor de Size e utilizado para criar o vetor Checked[ ] e paracontrolar as estruturas de repeticao que percorrem toda a lista Assertions. O RAIDE criauma lista dinamica para reportar as listas de duplicacoes existentes no metodo (Duplica-tions[], linha 4). Um assertion pode ser repetido uma ou mais vezes. Entao, assumimosque cada conjunto de assertions com parametros iguais corresponde a uma duplicacao.

Tambem assumimos que devido as mas praticas de desenvolvimento de teste, ummetodo de teste pode apresentar mais de uma duplicacao, i.e., varios conjuntos de asser-tions duplicados. Para atender a este cenario, agrupamos os resultados de cada duplicacaoem uma posicao da lista Duplications[] (linha 22). Portanto, o Algoritmo 2 percorre todaa lista Assertions (linha 5) e faz comparacoes com outras estruturas de assertions queainda nao foram “verificados” como duplicacao (linhas 9, 10 e 11). Caso identificada al-guma duplicacao, atribuımos a variavel DA o valor true (linha 12), utilizamos a variavel

74 RAIDE

Algoritmo 2 Pseudocodigo para identificar o test smell DA1: function IsDuplicateAssert(Assertions)2: Size← size of Assertions3: let Checked[size] be a new array4: let Duplications[] be a new array5: for i ← 0 to Size-1 do6: Lines← empty string7: if not Checked[i] then8: DA← false9: for j ← i+1 to size-1 do10: if not Checked[j] & Assertions[i] == Assertions[j] then11: if not DA then12: DA← true13: Lines← Line(Assertions[i])14: Cheched[i]← true15: end if16: Lines← Lines + “, ” + Line(Assertions[j])17: Checked[j]← true18: end if19: end for20: end if21: if DA then22: Duplications← add Lines23: end if24: end for25: return Duplications26: end function

auxiliar Lines para capturar a linha do assertion original (linha 13) e mudamos o valorde Checked[] na posicao i para true (linha 14). Em seguida, concatenamos a linha do as-sertion duplicado com a variavel Line. Esse processo se repete ate que um assertion sejacomparado com todos os outros assertions do metodo que ainda nao tenham sido verifi-cados como um DA. A cada iteracao do laco mais externo (linha 5), a lista Duplications[]adiciona uma string (linha 22) se existir duplicacoes (linha 21).

Apos a deteccao de test smells, o RAIDE executa a Apresentacao dos resultados dadeteccao de test smells (Etapa 4), que apresenta as guias de visualizacao para mostrara lista de test smells detectados. Para executar essa etapa, reutilizamos os componentesgraficos da ferramenta JDeodorant.

4.4.2 Refatoracao de test smells

Para executar a Refatoracao de test smells (Figura 4.2), o Usuario seleciona linhaou trecho de codigo com test smell (Etapa 5) na guia de visualizacao no Eclipse

IDE, com duplo clique. RAIDE apresenta a localizacao do test smell no codigo de teste,destacando a linha ou o trecho de codigo afetado com a cor verde. Alem disso, a fer-ramenta tambem apresenta uma definicao para cada test smell, ou seja, uma explicacaopara os usuarios, que pode ajuda-los e evitar a insercao de novos test smells. Para Apli-car a refatoracao (Etapa 6), foram criadas duas estrategias, uma para cada test smell(AR e DA). A seguir, cada estrategia de refatoracao e apresentada.

Assertion Roulette (AR). Para o processo de refatoracao do AR, o RAIDE reescreve aestrutura do assertion. Lidamos com duas situacoes diferentes. Primeiro, se nao houver

4.4 PROCESSOS DO RAIDE 75

explicacao no assert, o RAIDE incluira uma string de reparo no primeiro parametrodo assert : “Add Assertion Explanation here”. Segundo, se o assert tiver uma string

vazia ou uma string contendo uma sequencia de espaco, reescrevemos esse parametrocom a mesma string de reparo: “Add Assertion Explanation here”. No entanto, se ometodo de teste falhar, a sequencia gerada pelo RAIDE nao indicara corretamente qualassercao e responsavel pela falha do codigo de teste. Portanto, para remover o testsmell, o desenvolvedor precisa reescrever a string gerada pelo RAIDE com a descricaoque corresponde a verificacao feita pelo assertion.

O Algoritmo 3 explica como a refatoracao do codigo de teste com AR funciona. Ometodo recebe um assertion que deve ser corrigido. O algoritmo cria e instancia a variavelLength com o comprimento do assertion e a variavel Position com a posicao do primeiroparentese do assertion (linhas 2 e 3). Depois disso, a string AssertionRefactored ecriada. Primeiro, o AssertionRefatorored recebe uma copia do Assertion da posicao ini-cial “0” ate o valor Position (linha 4), concatena a string “Add Assertion ExplanationHere” (linha 5) e concatena uma copia do Assertion de Position + 1 ate Length (li-nha 6). Depois disso, o Assertion e substituıdo pela variavel AssertionRefactored (linha7). Para substituir o assertion original pelo assertion refatorado na classe de teste (li-nha 7), o RAIDE manipula o teste atraves das interfaces IJavaElement, ITextEditor,IDocumentProvider e IDocument, semelhante ao JDeodorant.

Algoritmo 3 Pseudocodigo para refatorar o test smell AR1: function RefactoringAssertionRoulette(Assertion)2: Length← length of Assertion3: Position← getF irstParenthesisPosition(assertion)4: AssertionRefectored← copy(Assertion, 0, Position)5: AssertionRefectored+← “AddAssertionExplanationhere, ”6: AssertionRefectored+← copy(Assertion, Position + 1, Length)7: Replace(Assertion,AssertionRefectored)8: end function

Duplicate Assert (DA). Para refatorar o codigo de teste referente ao DA, RAIDE

remove cada assertion duplicado do metodo e os coloca em novos metodos, um paracada ocorrencia de assertion duplicado. Os novos metodos sao copias do original, mascontem uma unica ocorrencia de cada assertion duplicado. Alem disso, o plugin preservao metodo comentado original como um backup para o engenheiro de testes.

O Algoritmo 4 apresenta o pseudocodigo relacionado a refatoracao do test smell DA. Afuncao recebe dois parametros: o metodo que contem as duplicacoes (Method) e um arraycom os assertions duplicados do metodo (Assertions na Figura 4.3), que foi gerado noAlgoritmo 2. Antes da refatoracao, o algoritmo armazena uma copia do metodo original(CopyMethod na linha 2) e o metodo original comentado (BackupMethod na linha 3).

Cada ındice do array Assertions agrupa as duplicacoes do mesmo assertion, comomostra a Figura 4.3. Por exemplo, o ındice 1 do array representa que um assertionespecıfico foi duplicado nas linhas 5 e 8 do metodo. Para refatora-lo, convertemos essearray de string em uma nova estrutura (array DuplicationOccurrence na linha 4). O

76 RAIDE

Algoritmo 4 Pseudocodigo para refatorar o test smell DA1: function RefactoringDuplicateAssert(Method, Assertions)2: CopyMethod← Copy of Method3: BackupMethod← Comment(CopyMethod)4: DuplicationOccurrence←MapDuplications(Assertions)5: Method← DeleteOtherAssertions(CopyMethod, 1, DuplicationOccurrence)6: Number ← HigherNumberOfDuplications(Assertions)7: NewMethods← empty string8: for i ← 2 to Number do9: Extracted← DeleteOtherAssertions(CopyMethod, i,DuplicationOccurrence)

10: NewMethods← add Extracted11: end for12: Replace(CopyMethod,BackupMethod + Method + NewMethods)13: end function

Figura 4.3 Descricao da conversao do array feito pelo metodo MapDuplications()

tamanho desse novo array esta relacionado a quantidade de linhas do metodo, na qualcada ındice corresponde a uma linha do metodo (por exemplo, o ındice 4 correspondea linha 4 do metodo). Assim, cada posicao do array DuplicationOccurrence contemum inteiro que corresponde a ocorrencia da repeticao do assertion. O valor zero (0)(por exemplo, ındices 6 e 9) representa que nao ha assertion na linha correspondentedo metodo ou ha um assertion nao duplicado. O valor um (1) representa a primeiraocorrencia do assertion duplicado, o valor dois (2) representa a segunda ocorrencia eassim por diante. Por exemplo, o ındice 4 do array DuplicationOccurrence (Figura 4.3)contem o valor 1 para indicar que esta e a primeira ocorrencia de um assertion duplicado.

Depois de criar o array DuplicationOccurrence (linha 4), o Algoritmo 4 refatora ometodo de teste original (DeleteOtherAssertions() na linha 5) para remover a duplicacao.Assim, apos a refatoracao, o metodo em analise deve conter apenas a primeira ocorrenciade cada assertion duplicado. O algoritmo cria copias do metodo para incluir os assertionsremovidos no metodo original (linhas 8-10). Por fim, o codigo-fonte do metodo original esubstituıdo por: (i) o metodo original comentado (para backup); (ii) o metodo refatorado;(iii) e os metodos extraıdos.

4.5 EXEMPLO DE USO

Esta Secao apresenta um exemplo de uso da ferramenta RAIDE. Para identificar testsmells com RAIDE, o usuario precisa selecionar test smells no menu superior do EclipseIDE e selecionar o tipo de test smell a ser analisado: AR e DA (Etapa 1 na Figura 4.4).

4.5 EXEMPLO DE USO 77

Em seguida, o usuario deve selecionar o pacote de teste do projeto (Etapa 2 na Figura4.4) e clicar na opcao correspondente para executar a identificacao dos test smells (Etapa3 na Figura 4.4). Para este exemplo de uso, foi selecionado o projeto Reflections16,versao 0.9.12. O Reflections e usado para analise de metadados do tempo de execucaoJava.

Apos detectar os test smells, as guias de visualizacao exibem todos os test smells dopacote de teste, um test smell por linha (Etapa 4 na Figura 4.4). Ao clicar em uma linhacom test smell relatada, a ferramenta destaca a linha do codigo-fonte afetada com a corverde (Etapa 5 na Figura 4.4). Ao passar o mouse sobre a linha do codigo destacada,a descricao do test smell e mostrada. As Figuras 4.5 e 4.7 mostram as descricoes dostest smells AR e DA, respectivamente. Em seguida, para refatorar o codigo de teste,e necessario clicar duas vezes na linha do test smell relatado na guia de visualizacao eselecionar a opcao de refatorar (Etapa 6 na Figura 4.4).

A Figura 4.5 mostra um trecho de codigo com o test smell AR. Existem tres assesti-ons nao documentados no metodo test includePackage() (linhas 25-27) identificadospelo plugin RAIDE. A Figura 4.6 mostra o processo de refatoracao para o segundo asser-tion nao documentado (linha 26). O RAIDE adicionou o primeiro parametro ausente, queinclui a seguinte sequencia: “Add Assertion Explanation here”. Em seguida, o desenvol-vedor precisa reescrever a sequencia gerada pelo RAIDE com a descricao que correspondacorretamente a verificacao feita pelo assertion.

A Figura 4.7 mostra um trecho de codigo no qual dois pares de assertions duplicadosforam identificados no metodo withReturn() (linhas 116 e 120; e linhas 117 e 121). Pararefatorar o codigo de teste referente ao test smell DA, o RAIDE refatora o metodo originale extrai novos metodos. Alem disso, ele preserva o metodo comentado original comoum backup para o desenvolvedor. A Figura 4.8 mostra a refatoracao do DA. O metodode teste original (withReturn()) foi comentado (linhas 112-123) e duas copias foramfeitas a partir do metodo original, metodo withReturn() (linhas 126-134) e metodowithReturnExtracted1() (linhas 137-145). A primeira ocorrencia de cada assertionduplicado (Figura 6, linhas 116 e 117) foi preservada no metodo original (Figura 7, linhas130 e 131); e a segunda ocorrencia dos assertions duplicados (Figura 6, linhas 120 e 121)foi preservado no segundo metodo, que foi extraıdo, como mostra a Figura 4.8 nas linhas143 e 144.

16Disponıvel em 〈https://github.com/ronmamo/reflections〉

78R

AID

E

Figura 4.4 Etapas para executar o RAIDE

4.5 EXEMPLO DE USO 79

Figura 4.5 AR identificado com o plugin RAIDE

Figura 4.6 AR refatorado com o plugin RAIDE

Figura 4.7 DA identificado com o plugin RAIDE

80 RAIDE

Figura 4.8 DA refatorado com o plugin RAIDE

A proxima secao aborda a licenca que adotamos para o plugin RAIDE.

4.6 LICENCA

Durante o desenvolvimento do RAIDE foi possıvel utilizar o codigo-fonte das ferramentastsDetect17 e JDeodorant18 devido a licenca de ambas as ferramentas. O codigo-fonte dotsDetect esta disponıvel no GitHub e e licenciado sob a GNU General Puplic License(Version 3)19 (Figura 4.9) e o codigo-fonte do JDeodorant tambem esta disponıvel noGitHub e esta licenciado sob a MIT License20 (Figura 4.10).

Figura 4.9 Licenca do tsDetect

17Disponıvel em 〈https://testsmells.github.io/〉18Disponıvel em 〈https://github.com/tsantalis/JDeodorant〉19Disponıvel em 〈www.gnu.org/licenses/gpl.html〉20Disponıvel em 〈https://mit-license.org/〉

4.7 SINTESE DO CAPITULO 81

Figura 4.10 Licenca do JDeodorant

A General Puplic License e uma licenca copyleft, isto e, softwares derivados de umproduto originalmente licenciado pela General Puplic License so podem ser distribuıdosse utilizarem a mesma licenca. Por outro lado, a MIT License possuem exigencias maissimples, e e compatıvel com General Puplic License. Assim, devido ao codigo-fonte doplugin RAIDE ser inspirado no codigo-fonte de duas ferramentas analisadoras de anti-padroes, o JDeodorant e o tsDetect, adotamos a GNU General Puplic License (Version3).

A General Puplic License possui permissoes para utilizar o software para qualquerfinalidade, direito de modificar o software, e ter acesso aos codigos fonte, direito decopiar e distribuir o software, direito de melhorar o software, e liberar outras versoes. AGeneral Puplic License nao permite que o codigo de um software seja seja apropriadopor outros nem que sejam estabelecidas restricoes que impecam que seja distribuıdo damesma maneira que foi adquirido. Sendo assim, o codigo-fonte do plugin RAIDE pode serutilizado em software livre.

4.7 SINTESE DO CAPITULO

Neste Capıtulo, apresentamos o plugin RAIDE e suas principais contribuicoes. Assim, fo-ram abordados os tipos de test smells que o plugin da suporte (AR e DA), as motivacoesque impulsionaram a escolha da linguagem e da IDE e detalhes da implementacao. Apre-sentamos os principais processos do RAIDE: (i) Identificacao de test smells no codigo deteste; e (ii) Refatoracao semi-automatizada do codigo de teste com test smells. Tambemapresentamos os algoritmos de identificacao e refatoracao dos test smells e os passos ne-cessarios para a execucao da ferramenta atraves de um exemplo de uso. Para avaliaro RAIDE, realizamos um experimento controlado, cujo estudo e apresentado no proximocapıtulo.

Capıtulo

5AVALIACAO EXPERIMENTAL

RAIDE foi proposto para melhorar a qualidade dos casos de teste escritos em JUnit atravesde uma interface grafica que simplifica o processo de deteccao e refatoracao de test smellsem projetos Java. Realizamos um estudo empırico para investigar como o processo au-tomatizado proposto auxilia a identificacao de test smells, bem como a refatoracao docodigo de teste “defeituoso”. Tambem investigamos a utilidade do RefActorIng test

Design Errors (RAIDE) como uma ferramenta analisadora de test smells integrada aoambiente de desenvolvimento. Assim, comparamos a capacidade dos usuarios de identi-ficar e refatorar test smells no codigo de teste com e sem o suporte do RAIDE, em umambiente com diferentes tarefas e projetos.

Neste estudo, comparamos RAIDE com Test Smell Detector (tsDetect) para adeteccao de test smells. No entanto, os resultados de nossa analise da literatura demons-trou a inexistencia de ferramentas de refatoracao automatica de testes de unidade, com oobjetivo de remover test smells. Portanto, em relacao a refatoracao, comparamos RAIDE

com a refatoracao realizada sem suporte ferramental.O Capıtulo esta organizado da seguinte forma:

Secao 5.1 define as questoes de pesquisa;

Secao 5.2 apresenta uma visao geral do experimento;

Secao 5.3 apresenta o estudo piloto;

Secao 5.4 traz informacoes sobre os participantes do experimento;

Secao 5.5 apresenta os materiais e tarefas do experimento;

Secao 5.6 apresenta o design e os procedimentos para execucao do experimento;

83

84 AVALIACAO EXPERIMENTAL

Secao 5.7 apresenta a analise de dados;

Secao 5.8 apresenta e discute os resultados obtidos;

Secao 5.9 apresenta as discussoes;

Secao 5.10 apresenta as ameacas a validade do presente estudo; e

Secao 5.11 sintetiza o Capıtulo.

5.1 QUESTOES DE PESQUISA

O estudo experimental foi conduzido a fim de avaliar como o RAIDE pode ajudar a ati-vidade de teste. Para atingir esse objetivo e orientar nosso estudo, definimos a seguinteQuestao de Pesquisa (QP): Como o plugin RAIDE auxilia os usuarios a detectar test smellse refatorar o codigo de teste? Alem disso, derivamos duas questoes especıficas da QPprincipal:

• QP1: Como o plugin RAIDE facilita o processo de deteccao dos test smells AssertionRoulette (AR) e Duplicate Assert (DA) em comparacao com a ferramenta do estadoda arte?

• QP2: Como o plugin RAIDE facilita o processo de refatoracao do codigo de testecom os test smells AR e DA em comparacao com a refatoracao manual?

Para responder a QP1, comparamos RAIDE com o tsDetect em relacao a forma comoas ferramentas detectam test smells e a facilidade com que os dados resultantes saoexibidos para o engenheiro de teste. Para responder a QP2, RAIDE foi comparado com oprocesso manual de refatoracao de codigo de teste.

Para resolver essas questoes, criamos duas tarefas semelhantes, nas quais os partici-pantes usam uma tarefa para cada uma das ferramentas (RAIDE ou tsDetect). Cadatarefa consiste em duas atividades: identificar as linhas do codigo com os test smells ARe DA (QP1) e refatorar os test smells AR e DA identificados no codigo (QP2). Assim,medimos o tempo que o participante leva para encontrar os test smells detectados nocodigo do teste (QP1), e tambem medimos o tempo para aplicar as refatoracoes do RAIDE

contra a refatoracao manual (QP2).

5.2 VISAO GERAL DO EXPERIMENTO

Os experimentos com os participantes foram realizados individualmente, i.e., foram rea-lizados 20 experimentos individuais, buscando controlar o mesmo ambiente e estruturapara cada um. Antes de realizar o experimento, os participantes responderam o Ques-tionario Preliminar atraves de um formulario online (Apendice A.1) com perguntas sobrea experiencia deles em relacao a programacao, testes, Java, JUnit, Eclipse IDE e test

5.3 ESTUDO PILOTO 85

Figura 5.1 Fluxo do experimento

smells. Em seguida, os participantes foram apresentados aos conceitos de test smells edos dois tipos de test smells utilizados no experimento, AR e DA, bem como a explicacaoe exemplificacao dos processos de deteccao e refatoracao de ambos. Os participantestambem foram informados sobre o objetivo do experimento, o qual consiste em identifi-car e refatorar test smells. A Figura 5.1 mostra o fluxo do experimento com as etapasexecutadas.

Os participantes executaram duas tarefas, uma para cada ferramenta, RAIDE e tsDetect.Cada tarefa abrange a analise de um projeto de software diferente. Pouco antes de exe-cutar o experimento, os participantes receberam treinamento sobre como usar e executara ferramenta que usariam logo depois. Um mesmo projeto foi usado nas sessoes de trei-namento (Projeto 1 na Figura 5.1). Apos o treinamento, os participantes realizaram astarefas do experimento, que sao: (i) usar a ferramenta fornecida para detectar dois testsmells (AR e DA) e relatar as linhas de codigo onde os test smells estao localizados; e (ii)refatorar o codigo para eliminar os dois tipos de test smells. As tarefas 1 e 2 da Figura5.1 sao semelhantes, diferem apenas pelas ferramentas (Ferramenta 1 ou Ferramenta 2 )e projetos usados (Projeto 2 ou Projeto 3 ).

No final das duas tarefas, os participantes responderam outro formulario online, oQuestionario de Feedback (Apendice A.3). Esse questionario e composto por perguntassobre a execucao do experimento e sobre a percepcao dos participantes de cada ferra-menta. Alem dos formularios, a tela do computador e o audio do experimento foramcapturados para dar suporte no processo de coleta de dados. Neste estudo, usamos othink-aloud protocol durante o experimento (SOARES et al., 2018; BEYER; HOLTZ-BLATT, 1997), ou seja, pedimos aos participantes para nos manter informados e explicar(dizer em voz alta) cada passo que estavam tomando.

5.3 ESTUDO PILOTO

Antes do experimento, realizamos um estudo piloto com cinco participantes: dois pesqui-sadores; dois profissionais da industria; e um pesquisador que tambem atua na industria.Nesse estudo inicial, ao usar o plugin RAIDE, os participantes levaram em media 47 segun-dos para executar o processo de identificacao de test smells, uma vez que a ferramentafaz a identificacao de forma automatica. Com a ferramenta tsDetect, eles levaram 15minutos, em media, para realizar a mesma tarefa.

86 AVALIACAO EXPERIMENTAL

Este estudo foi fundamental para revisar os conceitos e padronizar como o treinamentoseria realizado, especialmente os comandos necessarios para usar o tsDetect. O pilototambem serviu para avaliar se os participantes conseguiram entender de forma eficienteas tarefas e ferramentas, alem de treinar o pesquisador que conduziu o experimento. Paraa analise, os dados do estudo piloto nao foram considerados.

5.4 PARTICIPANTES

Recrutamos vinte participantes: dez pesquisadores, cinco profissionais da industria ecinco pesquisadores que trabalham na industria simultaneamente. Todos os participantespossuem graduacao, sete deles sao estudantes de mestrado e sete sao alunos de doutorado.Os participantes sao de dezesseis instituicoes diferentes, sendo oito universidades de ensino(U1 a U8) e oito empresas de desenvolvimento (C1 a C8), como mostra a Tabela 5.1. Alemdisso, alguns participantes pertencem a mais de uma instituicao, como os participantesP1, P7, P12, P15, P17, P18 e P20.

Com relacao a experiencia dos participantes, eles foram entrevistados quanto a ex-periencia (em anos) em programacao de software, programacao com linguagem Java,programacao usando o Eclipse IDE, experiencia com teste de software e teste automa-tizado com JUnit. A Tabela 5.1 mostra a experiencia em anos para cada participante.Todos eles tinham alguma experiencia com programacao e quinze participantes tinhamalguma experiencia com teste de software. No entanto, a maioria deles tinha menos deum ano de experiencia com as tecnologias especıficas usadas durante o experimento (porexemplo, JUnit), destacando a importancia de realizar as sessoes de treinamento antesde executar as tarefas reais do experimento.

Quanto ao conhecimento sobre os test smells, quatro dos vinte participantes nuncaouviram falar deles; nove ja tinham ouvido falar, mas nunca haviam trabalhado com testsmells ; um participante sabia um pouco sobre test smells ; quatro ouviram falar sobretest smells e ja haviam trabalhado com test smells ; e dois participantes trabalham compesquisas sobre test smells.

Tabela 5.1 Perfil e experiencia (em anos) dos Participantes

ID Grupo Titulacao Perfil Instituicao Programacao Java Eclipse IDE Teste de Software JUnit

P01 1 Doutorando Pesquisador/Professor U1/U2 10+ 10+ 10+ 10+ 1` 5

P02 2 Mestrando Pesquisador U1 10+ 0-1 0-1 5` 10 0-1

P03 3 Doutorando Pesquisador U1 0-1 0 1`5 1 `5 1` 5

P04 4 Graduado Analista de requisitos C1 1`5 1`5 1`5 1`5 0-1

P05 1 Graduado Desenvolvedor C2 5`10 1`5 0-1 0-1 0-1

P06 2 Mestrando Pesquisador U1 5`10 1`5 1`5 1`5 1`5

P07 3 Doutorando Pesquisador/Professor U1/U3 1`5 1`5 1`5 5`10 0-1

P08 4 Graduado Professor U4 5`10 1`5 1`5 0-1 0

P09 1 Graduado Desenvolvedor C1 1`5 1`5 0 0-1 0-1

P10 2 Graduado Desenvolvedor C3 1`5 0-1 0-1 0-1 0

P11 3 Mestrando Pesquisador/Database Admin. U5 1`5 1`5 1`5 0 0

P12 4 Doutorando Pesquisador/Professor U1/U6 5`10 1`5 1`5 0-1 0-1

P13 1 Doutorando Pesquisador U7 10+ 1`5 1`5 0 0

P14 2 Doutorando Pesquisador U1 1`5 1`5 0-1 0-1 0

P15 3 Mestrando Pesquisador/Desenvolvedor U1/C4 1`5 1`5 0-1 0 0

P16 4 Graduado Desenvolvedor C5 5`10 1`5 1`5 1`5 1`5

P17 1 Mestrando Pesquisador/Agile coach U5 e C6 5`10 5`10 5`10 0-1 0-1

P18 2 Mestrando Pesquisador/Desenvolvedor U1/C7 5`10 1`5 1`5 0 0

P19 3 Doutorando Pesquisador U8 10+ 10+ 10+ 10+ 10+

P20 4 Mestrando Pesquisador/Desenvolvedor U1/C8 1`5 1`5 1`5 0 0

88 AVALIACAO EXPERIMENTAL

5.5 MATERIAL EXPERIMENTAL E TAREFAS

Tres projetos de codigo aberto foram selecionados para este experimento: Reflections

para o treinamento (Projeto 1 na Figura 5.1), Joda-Time e Commons-collections para aexecucao das tarefas 1 e 2 (Projeto 2 e Projeto 3 na Figura 5.1, mas nao necessariamentenessa ordem). A escolha dos projetos foi baseada nas limitacoes do RAIDE e do tsDetect,que suportam projetos Maven e teste de unidade com o JUnit (versao 4). Assim, usamosesses criterios e selecionamos tres projetos open source do Github1.

Reflections2 e um projeto utilizado para analise de metadados de codigo Java emtempo de execucao. Ele e capaz de obter todos os subtipos de algum tipo; todos ostipos/membros anotados com alguma anotacao; todos os recursos que correspondem auma expressao regular; todos os metodos com assinatura especıfica, incluindo parametros,anotacoes de parametros e tipos de retorno. O Joda-Time3 fornece um substituto dequalidade para as classes de data e hora do Java. O projeto Joda-Time permite variossistemas de calendario e fornece uma API simples. O projeto Commons-collections4 foiuma adicao importante ao JDK 1.2. Ele adicionou muitas estruturas de dados poderosasque aceleram o desenvolvimento dos aplicativos Java, tornando-o o padrao para lidar comcolecoes Java. A tabela 5.2 apresenta o numero de estrelas para cada projeto, quantidadede commits, o ultimo commit (versao utilizada nesse estudo), o numero de colaboradorese a versao do JUnit usada para o teste de unidade.

Tabela 5.2 Projetos selecionados para o estudo experimental

Projeto Estrelas Commits Ultimo Commit Contribuidores JUnit

Reflections 3k 144 Jan 11, 2020 24 4.13

Joda-Time 4.3k 2,139 Oct 24, 2019 73 3.8.2

Commons-collection 400 3,239 Jan 12, 2020 46 4.12

Cada projeto foi usado para uma tarefa diferente. Devido ao escopo e o limite detempo para realizar o experimento, foi necessario reduzir o tamanho do pacote de testede cada projeto e deixa-los com apenas duas classes de teste. Assim, apos os ajustes, todosos tres sistemas (Reflections, Joda-Time e Commons-collection) possuıam um nıvelde complexidade, numero de metodos e test smells semelhantes. Em relacao a execucaodas ferramentas, cada uma tem as suas especificidades. A ferramenta tsDetect re-quer tres arquivos a serem executados: TestFileDetector.jar, TestFileMapping.jare TestSmellDetector.jar.

Dessa forma, durante o treinamento do tsDetect, um script com um tutorial foi for-necido para os participantes demonstrando como deveriam executar os arquivos. Para otreinamento do RAIDE, exportamos e instalamos o plugin diretamente no Eclipse IDE.Assim, para cada ferramenta, apresentamos a demonstracao detalhadamente e esclare-

1Disponıvel em 〈https://github.com/〉2Disponıvel em 〈https://github.com/ronmamo/reflections〉3Disponıvel em 〈https://github.com/JodaOrg/joda-time〉4Disponıvel em 〈https://github.com/apache/commons-collections〉

5.6 DESIGN E PROCEDIMENTOS 89

cemos as duvidas dos participantes sobre a execucao da ferramentas antes de utiliza-lalogo em seguida. Apos o treinamento de cada ferramenta, pedimos aos participantes queusassem a ferramenta fornecida (RAIDE ou tsDetect) para identificar os test smells erelatar a classe e a linha de teste afetadas pelos dois tipos de test smells explorados nestetrabalho (AR e DA).

Em relacao a quantidade de test smells nos projetos, cada um deles tinha um metodocom o test smell AR (4 assertions sem explicacao no mesmo metodo) e um metodocom 2 pares de DA (4 assertions no mesmo metodo). Para deteccao dos test smells, oparticipante deve ser capaz de detectar o metodo afetado com os test smells e verbalizarpara o pesquisador as linhas onde os test smells estao localizados.

Depois disso, solicitamos que refatorassem o codigo de teste com os test smells identifi-cados no processo anterior. Para refatorar o codigo com o test smell AR, os participantesdevem refatorar 4 linhas no mesmo metodo de teste. Para remover o test smell DA, elesdevem extrair as 2 linhas duplicadas do metodo original para um novo metodo.

5.6 DESIGN E PROCEDIMENTOS

Este estudo possui duas variaveis independentes: os projetos (Joda-Time e Commons-

collection) e as ferramentas de deteccao (tsDetect e RAIDE). Medimos o tempo gastopelos participantes para detectar e refatorar os test smells. O tsDetect coleta todos ostest smells por meio de uma execucao que requer manipulacao manual de dois arquivose gera um arquivo .csv com os resultados. Por outro lado, o RAIDE detecta cada tipode test smell individualmente, o que requer duas execucoes, uma para cada tipo. Aocontrario de tsDetect, RAIDE destaca o codigo de teste para mostrar os resultados.

Como os participantes realizam uma sequencia de duas tarefas, pode haver um efeitode aprendizado. Para evitar esse efeito, usamos o Latin Square (DODGE, 2008). Essedesign e usado para realizar um arranjo das variaveis independentes (projetos e ferra-mentas), de modo que cada uma delas apareca uma vez em cada linha e coluna do design(Figura 5.2). Alem disso, atraves do Latin Square, podemos controlar a variacao emduas direcoes. Portanto, nosso experimento segue um design de Latin Square 2x2 paracombinar cada ferramenta com um projeto e quatro grupos (Figura 5.2) de participantespara executar as tarefas nas duas direcoes (da esquerda para a direita e vice-versa).

Os grupos sao descritos da seguinte maneira:

• Grupo 1 - os participantes executaram a primeira tarefa com a ferramenta tsDetect

no projeto Joda-Time;

• Grupo 2 - os participantes realizaram a primeira tarefa com o plugin RAIDE noprojeto Commons-Collection;

• Grupo 3 - os participantes realizaram a primeira tarefa com a ferramenta tsDetect

no projeto Commons-Collection;

• Grupo 4 - os participantes executaram a primeira tarefa com o plugin RAIDE noprojeto Joda-Time.

90 AVALIACAO EXPERIMENTAL

Figura 5.2 Latin Square para o tratamento do experimento

A Figura 5.3 apresenta a distribuicao das ferramentas e projetos para cada grupo.A Figura 5.3 e uma visao detalhada da etapa Treinamentos e Tarefas representada naFigura 5.1.

Todos os grupos tiveram o mesmo numero de participantes (5 participantes). Equili-bramos os grupos em relacao a experiencia dos participantes com as tecnologias. Nenhumparticipante repetiu ferramenta ou projeto durante o experimento.

5.7 ANALISE DOS DADOS

Para a analise dos dados, primeiro executamos o teste Shapiro-Wilk (THODE, 2002)para verificar a normalidade dos dados. Este teste retorna um p-value, que deve seranalisado com o nıvel de significancia de 5%. Portanto, se o p-value retornado pelo testefor menor que 5%, a distribuicao dos dados sera normal. Como resultado, os dados desseestudo apresentaram uma distribuicao de dados nao normal. Em seguida, selecionamoso teste pareado de Mann-Whitney (MANN; WHITNEY, 1947) para responder as nossasquestoes de pesquisa.

Para responder a QP1, foram definidas as seguintes hipoteses:

H01: O tempo para detectar e localizar os test smells AR e DA no codigo de teste comRAIDE e maior ou igual ao tempo gasto por tsDetect.

H11: O tempo para detectar e localizar os test smells AR e DA no codigo de teste comRAIDE e menor que o tempo gasto por tsDetect.

Para responder a QP2, foram definidas as seguintes hipoteses:

H02: O tempo para refatorar o codigo de teste com os test smells AR e DA com RAIDE

e maior ou igual ao tempo gasto pela refatoracao manual.

H12: O tempo para refatorar o codigo de teste com os test smells AR e DA com RAIDE

e menor que tempo gasto pela refatoracao manual.

5.8 RESULTADOS 91

Figura 5.3 Fluxo do experimento

O teste de Mann-Whitney retorna um p-value que e utilizado para analisar com onıvel de significancia de 5%. Portanto, se o p-value retornado pelo teste for menor que5%, a hipotese nula e refutada, ou seja, o tempo de deteccao dos test smells com RAIDE

e menor que o tempo gasto por tsDetect (QP1), e o tempo para refatoracao dos testsmells com RAIDE e menor que o tempo gasto na refatoracao manual (QP2). As respostascoletadas no Questionario de Feedback tambem foram utilizadas para compreender aspercepcoes dos participantes sobre as ferramentas e o experimento.

5.8 RESULTADOS

Esta secao apresenta os resultados reunidos nesta avaliacao empırica e discute os princi-pais resultados posteriormente.

92 AVALIACAO EXPERIMENTAL

5.8.1 Deteccao de test smells (QP1)

Para responder QP1, coletamos e analisamos o tempo gasto pelos participantes paradetectar e localizar os test smells AR e DA com RAIDE e tsDetect. A deteccao de testsmells com o plugin RAIDE foi muito mais rapida que a ferramenta tsDetect. Como RAIDE, os participantes concluıram a tarefa em 63,95 segundos (s), em media, comum desvio padrao (sd) de 28,12s (Tabela 5.3). Este valor e uma soma do tempo gastopelo participante para executar a ferramenta e relatar as linhas onde os test smells estaolocalizados. Por sua vez, os participantes gastaram 673,5s (sd = 248,71s) para executara mesma atividade usando tsDetect, o que sugere que a deteccao com tsDetect e maislenta que o processo realizado com RAIDE.

Tabela 5.3 Estatıstica descritiva do tempo para detectar e localizar os test smells AR e DA

Ferramenta Mınimo 1º Quartil Mediana Media Desvio Padrao 3º Quartil Maximo

RAIDE 27.00 48.50 56.50 63.95 28.12 75.00 135.00

tsDetect 293.00 483.50 673.50 679.20 248.71 803.80 1286.00

A diferenca entre as ferramentas esta relacionada ao fato de que RAIDE e uma fer-ramenta integrada a IDE, na qual os participantes selecionam um tipo de test smellque desejam analisar e a ferramenta relata as linhas com os test smells identificados.Enquanto com o tsDetect, os participantes precisavam executar tres ferramentas di-ferentes (TestFileDetector, TestFileMapping e TestSmellDetect), abrir um arquivo.csv para verificar quais classes apresentava test smells ou nao e depois inspecionar ma-nualmente o codigo do teste. Ao usar tsDetect, a maior parte do tempo e gasta parausar as ferramentas TestFileDetector e TestFileMapping, realizar ajustes nos arquivos.csv e localizar as linhas manualmente.

Devido a falta de precisao com o processo de identificacao das linhas de forma ma-nual, o pesquisador que conduziu o estudo precisou orientar os participantes a encontraras linhas corretamente, quando necessario. Assim, as ferramentas utilizadas para identi-ficacao apresentam uma grande diferenca em sua eficiencia em relacao a rapidez com quecolocam o usuario na frente dos test smells.

Tambem foi investigado se houve diferenca estatıstica significativa nesse processo deidentificacao de test smells com cada ferramenta. Como nossos dados nao tinham dis-tribuicao normal (valor-p = 7.748e-05), realizamos o teste de Mann-Whitney. O testeindicou que ha uma diferenca significativa (p-value = 9.537e-07) entre o tempo mediogasto usando cada ferramenta, tsDetect e RAIDE. Assim, refutamos a hipotese nula(H01) e respondemos QP1. Tambem observamos que os dados resultantes das medi-das de tempo com tsDetect sao mais dispersos do que o tempo dos participantes queusam RAIDE. A Figura 5.4 mostra os boxplots comparando dados coletados de RAIDE etsDetect, nao ha sobreposicao entre os boxplots de RAIDE e tsDetect, o que significaque ha uma diferenca entre eles.

Alem disso, mesmo o tempo mais longo relatado para detectar os test smells com aferramenta RAIDE ainda foi inferior ao menor tempo para detectar com tsDetect. Os

5.8 RESULTADOS 93

participantes que usaram RAIDE obtiveram resultados semelhantes em termos de eficienciapara detectar os test smells. No entanto, o mesmo nao foi identificado quando os par-ticipantes usaram tsDetect. Nesse sentido, tais resultados podem indicar que o RAIDE

padroniza a maneira como os participantes identificam os test smells, independentementede sua experiencia, enquanto com tsDetect, os participantes com menos habilidadespodem ter passado mais tempo realizando suas atividades.

Figura 5.4 Tempo de deteccao de test smells com as ferramentas RAIDE e tsDetect

Nossos resultados mostram que todos os participantes encontraram os test smellsmais rapidamente com RAIDE do que quando usavam a ferramenta tsDetect. A dife-renca media entre o tempo de cada ferramenta para o processo de deteccao foi superior a615s, considerando todas as etapas necessarias para executar o tsDetect. Alem disso, osparticipantes apontaram muitas vantagens que o RAIDE teria sobre o tsDetect relacio-nado a identificacao dos test smells. Por exemplo, de acordo com P02, RAIDE se destacouem relacao ao tsDetect porque “O processo de aprendizado e mais facil e rapido, possuimenos etapas a serem seguidas. E integrado a uma ferramenta de desenvolvimento comuma interface grafica, o que facilita seu uso. Tambem identifica as linhas em que cadatest smell afeta e sugere refatoracoes.”

Em seguida, resumimos as principais descobertas sobre a QP1:

QP1: Nossos resultados mostram que, usando RAIDE, os participantes identificam ostest smells cerca de dez vezes mais rapido em comparacao com tsDetect. Alem disso,RAIDE e integrado a IDE, detecta test smells com um clique e destaca as linhas decodigo onde os test smells estao localizados.

5.8.2 Refatoracao de codigo de teste (QP2)

Para responder QP2, coletamos e analisamos o tempo gasto pelos participantes pararefatorar o codigo de teste com os test smells AR e DA usando RAIDE e a refatoracao

94 AVALIACAO EXPERIMENTAL

manual. Para o processo de refatoracao do codigo de teste com test smells utilizandoa tecnica manual houve a necessidade de o pesquisador orientar os participantes pararealizar a tarefa corretamente, uma vez que refatoracao manual esta sujeita a erros.Assim, o tempo para realizacao da refatoracao foi contabilizado ate os participantesrealizassem o processo corretamente, tanto com a refatoracao manual, quanto para arefatoracao com RAIDE.

A seguir, sera discutido a refatoracao de cada tipo de test smell :

Refatoracao do AR. A analise do tempo gasto para refatorar o codigo do teste foirealizada individualmente para cada tipo de test smell. Assim, os participantes foramcapazes de refatorar o codigo do teste com RAIDE em media 49,9s (sd = 41,35s) (Tabela5.4). Enquanto a refatoracao manual levou 78,30s (sd = 46,39s). Como a refatoracao doRAIDE para o AR e realizada por linha, precisamos contar o tempo gasto pelo usuariopara selecionar adequadamente cada test smell do metodo e refatora-los individualmente.

Tabela 5.4 Estatıstica descritiva do tempo para refatorar codigo de teste com AR

Tecnica Mınimo 1º Quartil Mediana Media Desvio Padrao 3º Quartil Maximo

Automatizada 13.00 23.50 40.00 49.90 41.35 72.25 190.00

Manual 18.00 49.75 67.50 78.30 46.39 98.75 229.00

Para a analise estatıstica, realizamos o teste de normalidade de Shapiro-Wilk e desco-brimos que o tempo de refatoracao da AR nao possui uma distribuicao normal (valor-p =6,607e-05). Portanto, tambem usamos o teste de Mann-Whitney. Embora a refatoracaode AR com RAIDE tenha mostrado uma dispersao semelhante a refatoracao manual, osresultados indicaram que ha uma diferenca significativa entre a refatoracao automatizadae a refatoracao manual para refatoracao de AR (p-value = 0.02287). Isso nos leva aentender que, para refatoracao de AR, o RAIDE possui um tempo de deteccao menor, oque refuta a hipotese nula (H02) para o test smell AR. A Figura 5.5 mostra os boxplotscom essas comparacoes. Se a linha mediana do boxplot do RAIDE for tracada, nao haveraintersecao com o boxplot da refatoracao manual, o que confirma que ha uma diferencaentre as duas ferramentas.

Refatoracao do DA. Tambem foi realizado o teste de normalidade Shapiro-Wilk (p-value = 7.69e-06), o qual os resultados informaram que os dados nao sao normais. Porisso, tambem foi necessario aplicar o teste de Mann-Whitney.

Nossos resultados mostraram uma diferenca significativa entre os tipos de refatoracaopara DA (p-value = 4,764e-05), confirmando que ha uma diferenca significativa entre arefatoracao com e sem o RAIDE para o test smell DA. Portanto, foi possıvel refutar ahipotese nula (H02) para o test smell DA. O tempo medio para refatoracao manual doDA foi de 107,2s (sd = 35,86) (Tabela 5.5). A media do plugin RAIDE foi de 2,55s (sd =1,57s). A Figura 5.6 mostra boxplots com essas comparacoes; os boxplots mostram quenao ha sobreposicao das caixas para cada tecnica de refatoracao usada.

Alem de analisar o tempo contabilizado para cada tarefa, tambem consideramos todosos comentarios deixados pelos participantes no Questionario de Feedback em relacao a

5.8 RESULTADOS 95

Figura 5.5 Refatoracao do AR com o RAIDE e com a refatoracao manual

Tabela 5.5 Estatıstica descritiva do tempo para refatorar codigo de teste com DA

Tecnica Mınimo 1º Quartil Mediana Media Desvio Padrao 3º Quartil Maximo

Automatizada 1.00 1.75 2.00 2.55 1.57 3.25 7.00

Manual 54.00 80.75 104.50 107.20 35.86 134.50 157.00

Figura 5.6 Refatoracao do DA com o RAIDE e com a refatoracao manual

avaliacao do processo de refatoracao realizado com e sem RAIDE. Os participantes P01,P13 e P16, por exemplo, indicaram que usariam o plugin RAIDE em seus projetos, devidoa sua capacidade de sugerir correcoes para os test smells detectados, alem da feature dedeteccao de test smells. De acordo com P17, o plugin RAIDE pode aumentar a produti-vidade no processo de identificacao e refatoracao, e esses recursos automatizados tendem

96 AVALIACAO EXPERIMENTAL

diminuir a chance de erro humano. De acordo com P19, o plugin RAIDE e preferıvel,pois a correcao automatizada dos test smells e feita de maneira visual, o que permite aousuario entender as etapas executadas.

Em seguida, resumimos as principais descobertas sobre QP2:

QP2: Em relacao a refatoracao, a diferenca entre RAIDE e o processo de refatoracaomanual do codigo de teste com o test smell AR e DA e significativa. No entanto,para refatorar o codigo de teste com o test smell DA, o RAIDE foi mais que quarentae duas vezes mais rapido em comparacao com o processo sem o plugin RAIDE. Alemdisso, pudemos identificar um consenso no relatorio dos participantes quando todosconcordaram que o plugin RAIDE foi mais facil para refatorar os test smells e queescolheriam RAIDE ao inves do processo manual para corrigir os test smells AR e DA.

5.9 DISCUSSOES

Apos analisar os dados coletados, pudemos inferir que a deteccao de AR e DA comtsDetect consistiu na atividade mais demorada. Este resultado esta relacionado a frag-mentacao do tsDetect, que possui tres etapas intermediarias ate apresentar os resulta-dos. Tambem destacamos a baixa usabilidade da ferramenta e o processo trabalhoso paraidentificar onde os test smells estao localizados. A Figura 5.7 resume os resultados doexperimento.

O feedback dos participantes inclui dados bastante importantes que devemos levar emconsideracao. Por exemplo, P01 e P02 relataram que, embora tsDetect abrange umaquantidade maior de tipos de test smells comparado ao RAIDE, o processo de identificacaode test smells na primeira ferramenta e mais complicado. Os participantes afirmaram quee necessario manipular varios arquivos e a interacao da linha de comando pode dificultaro processo de identificacao.

P03 e P06 destacaram que o processo de deteccao de test smells com tsDetect levamais tempo do que com o plugin RAIDE. P04 alegou que o processo executado pelotsDetect e contra-intuitivo, ou seja, os usuarios precisariam repetir as etapas com maisfrequencia para aprender o processo (a ordem de entrada e saıda dos arquivos). P06tambem mencionou que os resultados de tsDetect nao sao muito expressivos, pois apenasinforma se ha ou nao test smells, sendo suscetıvel a erros, especialmente ao lidar comclasses de teste de tamanho grande. Tais comentarios estao alinhados com os dadosapresentados na Figura 5.7.

Alem disso, as tarefas executadas com o suporte de RAIDE levaram em media 116s,contra uma media de 865s para executar as tarefas com tsDetect. Alem disso, limitamoso numero de classes e test smells dos projetos utilizados para conduzir o experimento.Portanto, os dados coletados nos fornecem uma indicacao de que a refatoracao manualdo codigo de teste levaria muito mais tempo em ambientes do mundo real, se RAIDE naofor usado. De fato, estudos nessa direcao devem ser realizados para confirmar ou refutaressa afirmacao.

5.10 AMEACAS A VALIDADE 97

Figura 5.7 Media de Tempo

5.10 AMEACAS A VALIDADE

Validade interna. Refere-se aos efeitos dos tratamentos sobre as variaveis devido afatores nao controlados no ambiente (WOHLIN et al., 2012). Para reduzir essa ameaca,foi realizado um treinamento do sistema para apresentar as ferramentas e as tarefasaos participantes, e usamos a randomizacao para atribuir a ordem dos participantes astarefas para reduzir o efeito de aprendizado. No entanto, durante a realizacao das tarefasatribuıdas, alguns participantes apresentaram algumas dificuldades para realizar a tarefade refatoracao manualmente (ou seja, usando o tsDetect). Nesse caso, direcionamos-os a encontrar uma solucao que possa influenciar positivamente o desempenho dessesparticipantes usando o tsDetect.

Validade externa. Diz respeito a generalizacao dos resultados fora do cenario expe-rimental (WOHLIN et al., 2012). Para mitigar essa ameaca, o experimento foi realizadocom especialistas da industria e da academia. Embora nao tenha havido uma grande di-ferenca no numero de profissionais e academicos, apresentamos os conceitos de deteccao erefatoracao com as ferramentas usando um sistema de treinamento. Mesmo os participan-tes que nao tinham experiencia no contexto do experimento, ao final de cada treinamento,os participantes estavam nivelados o suficiente para realizar as tarefas.

Validade de construto. Representa os conceitos de causa e efeito que devem sermedidos no experimento por meio de variaveis dependentes e independentes (WOHLINet al., 2012). Atraves do estudo piloto, foi possıvel melhorar o design do experimento emitigar algumas ameacas, treinando o pesquisador que conduziu o experimento e padro-nizando as instrucoes dadas a todos os participantes.

Validade de conclusao. Refere-se a extensao das conclusoes sobre a relacao entreos tratamentos e os resultados (WOHLIN et al., 2012). A principal ameaca a validade

98 AVALIACAO EXPERIMENTAL

da conclusao foi o pequeno tamanho da amostra. No entanto, nao interferiu nos testesestatısticos aplicados. Alem disso, a comparacao do plugin foi feita com outra ferramentaque nao apresenta os mesmos recursos. A ferramenta tsDetect detecta varios tipos detest smells, mas nao ajuda na refatoracao deles. Por outro lado, o RAIDE detecta apenasdois tipos de test smells e ajuda na refatora-los. Portanto, para a etapa de refatoracao,buscou-se comparar a atividade manual com a automatizada.

5.11 SINTESE DO CAPITULO

Conduzimos um estudo experimental para avaliar se a ferramenta RAIDE facilita o pro-cesso de deteccao de test smells em comparacao com o estado da arte e se facilita oprocesso de refatoracao comparado com a refatoracao tradicional do codigo de teste. Fo-ram utilizados dois sistemas reais do GitHub: Joda-Time e Commons-collections. Aposos participantes realizarem as tarefas e contabilizar o tempo gasto com o RAIDE e com otsDetect, comparamos as duas ferramentas. A partir da analise dos dados, descobrimosque o RAIDE foi mais rapido nas duas atividades (identificacao e refatoracao) comparadocom o estado da arte.

Capıtulo

6CONSIDERACOES FINAIS

Garantir a qualidade de produtos de software e atividade essencial no processo de desen-volvimento. Neste estudo, apresentamos o RefActorIng test Design Errors (RAIDE),uma abordagem semi-automatizada para auxiliar a deteccao e refatoracao de test smellsno codigo de teste. Com a integracao do RAIDE com o Eclipse IDE, a identificacao erefatoracao dos test smells sao feitas de forma mais integrada ao desenvolvimento docodigo.

Para validar a proposta, realizamos um experimento controlado que investigou a uti-lidade e o desempenho do RAIDE em identificar test smells em comparacao com a fer-ramenta do estado da arte, o Test Smell Detector (tsDetect). Alem disso, com-paramos tambem a tecnica existente para refatoracao de test smells do RAIDE com arefatoracao manual.

A partir da nossa investigacao empırica, descobrimos que RAIDE possibilita identificaros test smells Assertion Roulette (AR) e Duplicate Assert (DA) mais rapidamente queo tsDetect. Em relacao ao processo de refatoracao, o RAIDE apresentou um impactosignificativo na refatoracao do test smell AR. E, para a refatoracao de DA, RAIDE refatoraum metodo de teste em menos de 3 segundos.

Esse capıtulo apresenta as consideracoes finais deste trabalho e esta organizado con-forme e apresentado a seguir:

Secao 6.1 relata as contribuicoes desta dissertacao de mestrado; e

Secao 6.2 apresenta direcoes para investigacoes futuras.

6.1 CONTRIBUICOES

O presente trabalho apresenta contribuicoes para a area de Teste de Software e para a areade Inspecao de Software, especificamente sobre o processo de identificacao e refatoracao decodigo de teste com JUnit, sob a perspectiva de test smells. De maneira geral, resumimosas principais contribuicoes desta pesquisa:

99

100 CONSIDERACOES FINAIS

1. Apresentacao de uma sıntese de ferramentas presentes na literatura que fornecemsubsıdios para auxiliar desenvolvedores e engenheiros de teste a melhorar a quali-dade do codigo de producao e do codigo de teste analisando metricas e anti-padroesexistentes;

2. Uma sıntese de test smells existentes na literatura, a qual apresenta definicao,exemplificacao, possıvel efeito, identificacao e refatoracao para cada tipo de testsmell.

3. Um estudo sobre o plugin RAIDE, o qual descreve os detalhadamente os processosde deteccao e refatoracao com os respectivos pseudo-codigos, alem de apresentaro exemplo de uso da ferramenta, arquitetura do plugin e comparacao com outrasferramentas similares (SANTANA et al., 2020);

4. Outros tres estudos vinculados a test smells realizados em conjunto com colabora-dores do grupo de pesquisa:

• Um estudo preliminar com carater quantitativo que objetivou a investigacaoda correlacao entre a presenca de test smells e a cobertura do codigo de teste(VIRGINIO et al., 2019);

• Um estudo empırico para analisar a qualidade do codigo de teste de unidadegerado por ferramentas de teste automatizado. Comparamos os testes gera-dos por duas ferramentas (Randoop e EvoSuite) com o conjunto de testes deunidade existente de vinte e um projetos Java de codigo aberto (VIRGINIOet al., 2020b); e

• Um estudo sobre o ferramental JNose Test, o qual apresenta a descricao dosprocessos da ferramenta, a arquitetura, exemplo de uso e comparacao comferramentas similares (VIRGINIO et al., 2020a).

5. Aplicacao de abordagens baseadas em regras para detectar e apontar automatica-mente no codigo de teste dois tipos de test smells, AR e DA;

6. Proposta e implementacao de duas estrategias semi-automatizadas para refatorarcodigos de teste com os test smells AR e DA;

7. Disponibilizacao da ferramenta RAIDE, um plugin do Eclipse IDE, capaz de auxiliarengenheiros de testes na busca por melhorias na qualidade dos teste de unidade;

8. Estudo com usuarios para comparar o RAIDE com o estado da arte, apresentando ediscutindo a utilidade de uma ferramenta integrada a IDE que identifica e refatoratest smells de forma automatizada.

6.2 TRABALHOS FUTUROS 101

6.2 TRABALHOS FUTUROS

Esta Secao destina-se a discutir estrategias e informacoes adicionais que possam contribuirpara a evolucao da ferramenta RAIDE. Nesta Secao tambem destacaremos oportunidadesque foram percebidas por meio desta pesquisa. Seguem nosso trabalhos futuros:

• Elaborar casos de teste para a ferramenta RAIDE e analisa-los sob a perspectiva detest smells.

• Ampliar a lista de test smells que o plugin RAIDE identifica e refatora. A quantidadede test smells que o RAIDE suporta foi mencionada pela maioria dos participantesda avaliacao empırica como uma fraqueza do plugin.

• Melhoria da ferramenta RAIDE para permitir a exportacao dos resultados em arqui-vos .csv. Resultados exportaveis podem ser uteis para futuras analises do codigode teste e comparacoes com outras versoes do codigo de teste.

• Avaliar o plugin RAIDE a fim de mensurar a precisao dos resultados apresentados.

• Expandir o plugin RAIDE para analisar test smells em codigos de testes em outraslinguagens de programacao, como Kotlin1, Swift2, Python3, entre outras.

• Para atender outras linguagens de programacao, alem que evoluir a forma como oRAIDE analisa o codigo de teste, sera necessario integra-la em outros ambientes dedesenvolvimento como um plugin, uma vez que o Eclipse IDE nao da suporte aalgumas linguagens de programacao. Futuramente, pretendemos ampliar o RAIDE

para outras IDE (e.g. Intellij4, Android Studio5, Visual Studio6 e Xcode7).

• Conforme o plugin RAIDE evolua, e essencial que o estudo inicial com os usuariosseja replicado com mais participantes a fim de validar cada melhoria implementadana ferramenta.

• Tambem pretendemos conduzir um experimento na industria em um projeto realpara compreendermos os efeitos do RAIDE a longo prazo.

1Disponıvel em https://kotlinlang.org/2Disponıvel em https://developer.apple.com/swift/3Disponıvel em https://www.python.org/4Disponıvel em https://www.jetbrains.com/pt-br/idea/5Disponıvel em https://developer.android.com/studio6Disponıvel em https://visualstudio.microsoft.com/pt-br/7Disponıvel em https://developer.apple.com/xcode/

REFERENCIAS

ABBES, M.; KHOMH, F.; GUEHENEUC, Y.-G.; ANTONIOL, G. An empirical studyof the impact of two antipatterns, blob and spaghetti code, on program comprehension.In: IEEE. 2011 15th European Conference on Software Maintenance and Reengineering.[S.l.], 2011. p. 181–190.

ARNOLD, K.; GOSLING, J.; HOLMES, D.; HOLMES, D. The Java programming lan-guage. Santa Clara, California: Addison-wesley Reading, 2000. v. 2.

ATHANASIOU, D.; NUGROHO, A.; VISSER, J.; ZAIDMAN, A. Test code quality andits relation to issue handling performance. IEEE Transactions on Software Engineering,IEEE, v. 40, n. 11, p. 1100–1125, 2014.

AYEWAH, N.; PUGH, W.; HOVEMEYER, D.; MORGENTHALER, J. D.; PENIX, J.Using static analysis to find bugs. IEEE software, IEEE, v. 25, n. 5, p. 22–29, 2008.

AYEWAH, N.; PUGH, W.; MORGENTHALER, J. D.; PENIX, J.; ZHOU, Y. Evaluatingstatic analysis defect warnings on production software. 2007.

BARTIE, A. Garantia da qualidade de software. CAMPUS - RJ, 2002.ISBN 9788535211245. Disponıvel em: 〈https://books.google.com.br/books?id=n7jqD1NOqtoC〉.

BAVOTA, G.; QUSEF, A.; OLIVETO, R.; LUCIA, A. D.; BINKLEY, D. An empiricalanalysis of the distribution of unit test smells and their impact on software maintenance.In: 2012 28th IEEE International Conference on Software Maintenance (ICSM). Trento,Italy: IEEE, 2012. p. 56–65.

BAVOTA, G.; QUSEF, A.; OLIVETO, R.; LUCIA, A. D.; BINKLEY, D. Are test smellsreally harmful? an empirical study. Empirical Software Engineering, Springer, v. 20, n. 4,p. 1052–1094, 2015.

BEYER, H.; HOLTZBLATT, K. Contextual Design: Defining Customer- Centered Sys-tems. MA, USA: Elsevier, 1997.

BOUHOURS, C.; LEBLANC, H.; PERCEBOIS, C. Bad smells in design and designpatterns. The Journal of Object Technology, v. 8, n. 3, p. 43–63, 2009.

BREUGELMANS, M.; ROMPAEY, B. V. Testq: Exploring structural and maintenancecharacteristics of unit test suites. In: WASDeTT-1: 1st International Workshop on Ad-vanced Software Development Tools and Techniques. Beijing, China: IEEE InternationalConference on Software Maintenance, 2008. p. 4–15.

103

104 REFERENCIAS

CHATLEY, R.; TIMBUL, T. Kenyaeclipse: learning to program in eclipse. In: Procee-dings of the 10th European software engineering conference held jointly. Lisbon, Portugal:ACM, 2005. p. 245–248.

CHECKSTYLE. 2020. Acessado em Marco de 2020. Disponıvel em: 〈https://checkstyle.sourceforge.io/〉.

CHEN, Z.; MARX, D. Experiences with eclipse ide in programming courses. Journal ofComputing Sciences in Colleges, Consortium for Computing Sciences in Colleges, v. 21,n. 2, p. 104–112, 2005.

CROSBY, P. Quality is Free: The Art of Making Quality Certain. McGraw-Hill, 1979.(Mentor book). ISBN 9780070145122. Disponıvel em: 〈https://books.google.com.br/books?id=n4IubCcpm0EC〉.

DEURSEN, A. V.; MOONEN, L.; BERGH, A. V. D.; KOK, G. Refactoring test code.In: Proceedings of the 2nd international conference on extreme programming and flexibleprocesses in software engineering (XP2001). NLD: CWI (Centre for Mathematics andComputer Science), 2001. p. 92–95.

DODGE, Y. The concise encyclopedia of statistics. Switzerland: Springer Science & Bu-siness Media, 2008.

EHA, B. P. CNN - Is Knight’s $440 million glitch the costliest computer bug ever?2012. Acessado em abril de 2019. Disponıvel em: 〈https://money.cnn.com/2012/08/09/technology/knight-expensive-computer-bug/index.html〉.

FANG, Z. Test clone detection via assertion fingerprints. Dissertacao (Mestrado) — Uni-versity of Waterloo, 2014.

FANTINATO, M.; CUNHA, A. C. R. da; DIAS, S. V.; CARDOSO, S. A. M.; CUNHA,C. A. Q. Autotest–um framework reutilizavel para a automacao de teste funcional desoftware. In: Simposio Brasileiro de Qualidade de Software. Brasilia: ACM, 2004. p. 5.

FEMMER, H.; FERNANDEZ, D. M.; JUERGENS, E.; KLOSE, M.; ZIMMER, I.; ZIM-MER, J. Rapid requirements checks with requirements smells: two case studies. In:RCoSE. Hyderabad, India: ACM, 2014. p. 10–19.

FERENC, R.; LANGO, L.; SIKET, I.; GYIMOTHY, T.; BAKOTA, T. Source metersonar qube plug-in. In: IEEE. 2014 IEEE 14th International Working Conference onSource Code Analysis and Manipulation. Victoria, BC, Canada: IEEE, 2014. p. 77–82.

FOKAEFS, M.; TSANTALIS, N.; CHATZIGEORGIOU, A. Jdeodorant: Identificationand removal of feature envy bad smells. In: IEEE. 2007 IEEE International Conferenceon Software Maintenance. Paris, France, 2007. p. 519–520.

REFERENCIAS 105

FOKAEFS, M.; TSANTALIS, N.; CHATZIGEORGIOU, A.; SANDER, J. Decomposingobject-oriented class modules using an agglomerative clustering technique. In: IEEE.2009 IEEE International Conference on Software Maintenance. Edmonton, AB, Canada,2009. p. 93–101.

FOKAEFS, M.; TSANTALIS, N.; STROULIA, E.; CHATZIGEORGIOU, A. Jdeodo-rant: identification and application of extract class refactorings. In: IEEE. 2011 33rdInternational Conference on Software Engineering (ICSE). Honolulu, HI, USA, 2011. p.1037–1039.

FOKAEFS, M.; TSANTALIS, N.; STROULIA, E.; CHATZIGEORGIOU, A. Identifica-tion and application of extract class refactorings in object-oriented systems. Journal ofSystems and Software, Elsevier, v. 85, n. 10, p. 2241–2260, 2012.

FONTANA, F. A.; BRAIONE, P.; ZANONI, M. Automatic detection of bad smells incode: An experimental assessment. Journal of Object Technology, v. 11, n. 2, p. 5–1,2012.

FOWLER, M. Refactoring: Improving the Design of Existing Code (Object Techno-logy Series). illustrated edition. Amsterdam: Addison-Wesley Longman, 1999. ISBN0201485672.

FOWLER, M. Refactoring: improving the design of existing code. Boston, MA: Addison-Wesley Professional, 2018.

GARCIA, J.; POPESCU, D.; EDWARDS, G.; MEDVIDOVIC, N. Identifying architec-tural bad smells. In: IEEE. 2009 13th European Conference on Software Maintenanceand Reengineering. Kaiserslautern, Germany, 2009. p. 255–258.

GARCIA-MUNOZ, J.; GARCIA-VALLS, M.; ESCRIBANO-BARRENO, J. Improvedmetrics handling in sonarqube for software quality monitoring. In: SPRINGER. Distri-buted Computing and Artificial Intelligence, 13th International Conference. Switzerland,2016. p. 463–470.

GAROUSI, V.; KUCUK, B. Smells in software test code: A survey of knowledge inindustry and academia. Journal of systems and software, Elsevier, v. 138, p. 52–81, 2018.

GAROUSI, V.; KUCUK, B.; FELDERER, M. What we know about smells in softwaretest code. IEEE Software, IEEE, v. 36, n. 3, p. 61–73, 2018.

Goth, G. Beware the march of this ide: Eclipse is overshadowing other tool technologies.IEEE Software, v. 22, n. 4, p. 108–111, 2005.

GRAHAM, D.; VEENENDAAL, E. V.; EVANS, I.; BLACK, R. Foundations of Soft-ware Testing: ISTQB Certification. London: Intl Thomson Business Pr, 2008. ISBN9781844803552.

106 REFERENCIAS

Greiler, M.; van Deursen, A.; Storey, M. Automated detection of test fixture strategiesand smells. In: 2013 IEEE Sixth International Conference on Software Testing, Verifica-tion and Validation. Luxembourg, Luxembourg: IEEE, 2013. p. 322–331. ISSN 2159-4848.

GREILER, M.; ZAIDMAN, A.; DEURSEN, A. v.; STOREY, M.-A. Strategies for avoi-ding text fixture smells during software evolution. In: Proceedings of the 10th WorkingConference on Mining Software Repositories. San Francisco, CA, USA: IEEE Press, 2013.p. 387–396.

GRYNA, F. Quality Planning and Analysis: From Product Development Through Use.New York: McGraw-Hill, 2001. (McGraw-Hill series in industrial engineering and mana-gement science).

GUEHENEUC, Y.-G. Ptidej: Promoting patterns with patterns. In: Proceedings of the1st ECOOP workshop on Building a System using Patterns. Glasgow, Scotland: Springer-Verlag, 2005. p. 1–9.

GUERRA, A.; COLOMBO, R. Tecnologia da informacao: qualidade de produto de soft-ware. Ministerio da Ciencia e Tecnologia, 2009. Disponıvel em: 〈https://books.google.com.br/books?id=5j1sQwAACAAJ〉.

GUERRA, E. M. Um estudo sobre refatoracao de codigo de teste. Tese (Doutorado) —Instituto Tecnologico de Aeronautica, 2005.

HIRAMA, K. Engenharia de software: Qualidade e produtividade com tecnologia. ElsevierEditora Ltda., 2012. ISBN 9788535248814. Disponıvel em: 〈https://books.google.com.br/books?id=tYhQYH2yiiYC〉.

HUO, C.; CLAUSE, J. Improving oracle quality by detecting brittle assertions and unusedinputs in tests. In: Proceedings of the 22nd ACM SIGSOFT International Symposium onFoundations of Software Engineering. Hong Kong, China: ACM, 2014. p. 621–631.

JUDD, C. M.; SHITTU, H. Pro Eclipse JST: Plug-Ins for J2EE Development. 1st. ed.USA: Apress, 2005. ISBN 1590594932.

KOOCHAKZADEH, N.; GAROUSI, V. Tecrevis: A tool for test coverage and test re-dundancy visualization. In: BOTTACI, L.; FRASER, G. (Ed.). Testing – Practice andResearch Techniques. Berlin, Heidelberg: Springer Berlin Heidelberg, 2010. p. 129–136.ISBN 978-3-642-15585-7.

KOOCHAKZADEH, N.; GAROUSI, V. A tester-assisted methodology for test redun-dancy detection. Advances in Software Engineering, Hindawi, v. 2010, 2010.

Krishnan, G. P.; Tsantalis, N. Refactoring clones: An optimization problem. In:2013 IEEE International Conference on Software Maintenance. Eindhoven, Netherlands:IEEE, 2013. p. 360–363.

REFERENCIAS 107

KRISHNAN, G. P.; TSANTALIS, N. Unification and refactoring of clones. In: IEEE. 2014Software Evolution Week-IEEE Conference on Software Maintenance, Reengineering, andReverse Engineering (CSMR-WCRE). Antwerp, Belgium, 2014. p. 104–113.

MANN, H. B.; WHITNEY, D. R. On a test of whether one of two random variables isstochastically larger than the other. In: The annals of mathematical statistics. Michigan:JSTOR, 1947. v. 18, p. 50–60.

MAZINANIAN, D.; TSANTALIS, N.; STEIN, R.; VALENTA, Z. Jdeodorant: clonerefactoring. In: Proceedings of the 38th International Conference on Software EngineeringCompanion. Austin, TX, USA: ACM, 2016. p. 613–616.

MESZAROS, G. xUnit test patterns: refactoring test code. 1st. ed. United States:Addison-Wesley, 2007.

MOHA, N.; GUeHeNEUC, Y.-G. Ptidej and decor: Identification of design pat-terns and design defects. In: Companion to the 22nd ACM SIGPLAN Conference onObject-Oriented Programming Systems and Applications Companion. New York, NY,USA: Association for Computing Machinery, 2007. (OOPSLA ’07), p. 868–869. ISBN9781595938657. Disponıvel em: 〈https://doi.org/10.1145/1297846.1297930〉.

MOHA, N.; GUEHENEUC, Y.-G.; DUCHIEN, L.; MEUR, A.-F. L. Decor: A method forthe specification and detection of code and design smells. IEEE Transactions on SoftwareEngineering, IEEE, v. 36, n. 1, p. 20–36, 2009.

MURPHY, G. C.; KERSTEN, M.; FINDLATER, L. How are Java software developersusing the Elipse IDE? IEEE software, IEEE, v. 23, n. 4, p. 76–83, 2006.

MYERS, G. J.; SANDLER, C. The Art of Software Testing. USA: John Wiley Sons, Inc.,2004.

NAIK, K.; TRIPATHY, P. Software Testing and Quality Assurance: Theory and Practice.2nd. ed. New Jersey: Wiley Publishing, 2018. ISBN 111919475X, 9781119194750.

OLBRICH, S. M.; CRUZES, D. S.; SJØBERG, D. I. Are all code smells harmful? a studyof god classes and brain classes in the evolution of three open source systems. In: 2010IEEE International Conference on Software Maintenance. Timisoara, Romania: IEEEComputer Society, 2010. p. 1–10.

PAIVA, T.; DAMASCENO, A.; PADILHA, J.; FIGUEIREDO, E.; SANT’ANNA, C.Experimental evaluation of code smell detection tools. In: 3rd workshop on softwareVisualization, Evolution, and Maintenance (VEM). Belo Horizonte, Brazil: SBC, 2015.p. 17–24.

PALOMBA, F.; BAVOTA, G.; PENTA, M. D.; FASANO, F.; OLIVETO, R.; LUCIA,A. D. On the diffuseness and the impact on maintainability of code smells: a large scaleempirical investigation. Empirical Software Engineering, Springer, v. 23, n. 3, p. 1188–1221, 2018.

108 REFERENCIAS

PALOMBA, F.; NUCCI, D. D.; PANICHELLA, A.; OLIVETO, R.; LUCIA, A. D. Onthe diffusion of test smells in automatically generated test code: An empirical study.In: ACM. Proceedings of the 9th international workshop on search-based software testing.Austin, TX, USA: IEEE, 2016. p. 5–14.

PALOMBA, F.; ZAIDMAN, A. Does refactoring of test smells induce fixing flaky tests?In: 2017 IEEE international conference on software maintenance and evolution (ICSME).Shanghai, China: IEEE, 2017. p. 1–12.

PALOMBA, F.; ZAIDMAN, A.; LUCIA, A. D. Automatic test smell detection using infor-mation retrieval techniques. In: IEEE. 2018 IEEE International Conference on SoftwareMaintenance and Evolution (ICSME). Madrid, Spain: IEEE, 2018. p. 311–322.

PERUMA, A.; ALMALKI, K.; NEWMAN, C. D.; MKAOUER, M. W.; OUNI, A.; PA-LOMBA, F. On the distribution of test smells in open source android applications: Anexploratory study. In: Proceedings of the 29th Annual International Conference on Com-puter Science and Software Engineering. USA: IBM Corp., 2019. (CASCON ’19), p.193–202.

PERUMA, A. S. A. What the Smell? An Empirical Investigation on the Distributionand Severity of Test Smells in Open Source Android Applications. Tese (Ph.D. Thesis)— Rochester Institute of Technology, Rochester, New York, 2018.

PERUMA, A. S. A. What the smell? an empirical investigation on the distribution andseverity of test smells in open source android applications. 2018.

RAMLER, R.; WOLFMAIER, K. Economic perspectives in test automation: Balancingautomated and manual testing with opportunity cost. In: Proceedings of the 2006 Inter-national Workshop on Automation of Software Test. New York, NY, USA: Associationfor Computing Machinery, 2006. (AST ’06), p. 85–91. ISBN 1595934081. Disponıvel em:〈https://doi.org/10.1145/1138929.1138946〉.

REICHHART, S. Assessing test quality–testlint. Citeseer, 2007.

REICHHART, S.; GIRBA, T.; DUCASSE, S. Rule-based assessment of test quality. J.Object Technol., Citeseer, v. 6, n. 9, p. 231–251, 2007.

ROMPAEY, B. V.; BOIS, B. D.; DEMEYER, S.; RIEGER, M. On the detection of testsmells: A metrics-based approach for general fixture and eager test. IEEE Transactionson Software Engineering, IEEE, v. 33, n. 12, p. 800–817, 2007.

SAARIMAKI, N.; BALDASSARRE, M. T.; LENARDUZZI, V.; ROMANO, S. On theaccuracy of sonarqube technical debt remediation time. In: IEEE. 2019 45th Euromi-cro Conference on Software Engineering and Advanced Applications (SEAA). Kallithea-Chalkidiki, Greece, Greece, 2019. p. 317–324.

REFERENCIAS 109

SANTANA, R.; MARTINS, L.; ROCHA, L.; VIRGINIO, T.; CRUZ, A.; COSTA, H.;MACHADO, I. Raide: a tool for assertion roulette and duplicate assert identification andrefactoring. In: Proceedings of the XXXIV Brazilian Symposium on Software Engineering- Tools Track. New York, NY, USA: ACM, 2020. (SBES 2020).

SCHMAUCH, C. H. ISO 9000 for Software Developers. New York, USA: ASQ QualityPress, 1993. ISBN 0873892461.

SEDGWICK, K. Bad Code Has Lost $500 Million of Cryptocurrency in Under aYear. 2018. Acessado em abril de 2019. Disponıvel em: 〈https://news.bitcoin.com/bad-code-has-lost-500-million-of-cryptocurrency-in-under-a-year/〉.

SOARES, L. R.; MEINICKE, J.; NADI, S.; KASTNER, C.; ALMEIDA, E. S. de. Explo-ring feature interactions without specifications: A controlled experiment. In: Proceedingsof the 17th ACM SIGPLAN International Conference on Generative Programming: Con-cepts and Experiences. New York, NY, USA: Association for Computing Machinery, 2018.p. 40–52.

SOMMERVILLE, I. Engenharia de software. 9th. ed. Brasil: PEARSON BRASIL, 2011.

THODE, H. C. Testing for normality. United States: CRC press, 2002. v. 164.

TOURE, F.; BADRI, M.; LAMONTAGNE, L. A metrics suite for junit test code: amultiple case study on open source software. Journal of Software Engineering Researchand Development, SpringerOpen, v. 2, n. 1, p. 14, 2014.

TSANTALIS, N.; CHAIKALIS, T.; CHATZIGEORGIOU, A. Jdeodorant: Identificationand removal of type-checking bad smells. In: IEEE. 2008 12th European Conference onSoftware Maintenance and Reengineering. Athens, Greece, 2008. p. 329–331.

TSANTALIS, N.; CHATZIGEORGIOU, A. Identification of extract method refactoringopportunities. In: IEEE. 2009 13th European Conference on Software Maintenance andReengineering. Kaiserslautern, Germany: IEEE, 2009. p. 119–128.

TSANTALIS, N.; CHATZIGEORGIOU, A. Identification of move method refactoringopportunities. IEEE Transactions on Software Engineering, IEEE, v. 35, n. 3, p. 347–367, 2009.

TSANTALIS, N.; CHATZIGEORGIOU, A. Identification of refactoring opportunitiesintroducing polymorphism. Journal of Systems and Software, Elsevier, v. 83, n. 3, p.391–404, 2010.

TSANTALIS, N.; CHATZIGEORGIOU, A. Identification of extract method refactoringopportunities for the decomposition of methods. Journal of Systems and Software, Else-vier, v. 84, n. 10, p. 1757–1782, 2011.

TSANTALIS, N.; MAZINANIAN, D.; KRISHNAN, G. P. Assessing the refactorabilityof software clones. IEEE Transactions on Software Engineering, IEEE, v. 41, n. 11, p.1055–1090, 2015.

110 REFERENCIAS

TSANTALIS, N.; MAZINANIAN, D.; ROSTAMI, S. Clone refactoring with lambda ex-pressions. In: IEEE. 2017 IEEE/ACM 39th International Conference on Software Engi-neering (ICSE). Buenos Aires, Argentina, 2017. p. 60–70.

TUFANO, M.; PALOMBA, F.; BAVOTA, G.; PENTA, M. D.; OLIVETO, R.; LUCIA,A. D.; POSHYVANYK, D. An empirical investigation into the nature of test smells. In:IEEE. 31st IEEE/ACM International Conference on Automated Software Engineering(ASE). Melbourne , VIC , Australia, 2016. p. 4–15.

VETRO, A.; MORISIO, M.; TORCHIANO, M. An empirical validation of findbugs issuesrelated to defects. In: 15th Annual Conference on Evaluation & Assessment in SoftwareEngineering (EASE 2011). Durham, UK: IET, 2011. p. 144–153.

VIRGINIO, T.; MARTINS, L.; ROCHA, L.; SANTANA, R.; CRUZ, A.; COSTA, H.;MACHADO, I. Jnose: Java test smell detector. In: Proceedings of the XXXIV BrazilianSymposium on Software Engineering - Tools Track. New York, NY, USA: ACM, 2020.(SBES 2020).

VIRGINIO, T.; MARTINS, L.; SOARES, L. R.; RAILANA, S.; COSTA, H.; MACHADO,I. An empirical study of automatically-generated tests from the perspective of test smells.In: Proceedings of the XXXIV Brazilian Symposium on Software Engineering. New York,NY, USA: ACM, 2020. (SBES 2020).

VIRGINIO, T.; SANTANA, R.; MARTINS, L. A.; SOARES, L. R.; COSTA, H.; MA-CHADO, I. On the influence of test smells on test coverage. In: Proceedings of the XX-XIII Brazilian Symposium on Software Engineering. New York, NY, USA: Associationfor Computing Machinery, 2019. (SBES 2019), p. 467–471.

WAZLAWICK, R. ENGENHARIA DE SOFTWARE: CONCEITOS E PRATICAS. El-sevier Editora Ltda., 2013. ISBN 9788535260854. Disponıvel em: 〈https://books.google.com.br/books?id=Qtg4VUkE0V0C〉.

WOHLIN, C.; RUNESON, P.; HOST, M.; OHLSSON, M. C.; REGNELL, B.; WESSLEN,A. Experimentation in software engineering. New York, USA: Springer Science & BusinessMedia, 2012.

YUSIFOgLU, V. G.; AMANNEJAD, Y.; CAN, A. B. Software test-code engineering: Asystematic mapping. Information and Software Technology, v. 58, p. 123 – 147, 2015.ISSN 0950-5849.

ZEISS, B. A refactoring tool for ttcn-3. Master’s thesis, Institute for Informatics, ZFI-BM-2006-05, ISSN, Citeseer, p. 1612–6793, 2006.

ZHU, H.; HALL, P. A.; MAY, J. H. Software unit test coverage and adequacy. ACMComputing Surveys (CSUR), ACM, v. 29, n. 4, p. 366–427, 1997.

Apedice

AAVALIACAO EMPIRICA: DADOS E MATERIAL DE

SUPORTE

Este apendice contem questionarios, dados, protocolo e material de suporte usado noestudo experimental, abordado no Capıtulo 5. Este apendice esta organizado da seguinteforma:

Secao A.1 apresenta o questionario online usado para obter o perfil de cada partici-pante (Questionario Preliminar);

Secao A.2 apresenta o protocolo utilizado pelo pesquisador para realizar o experi-mento com cada grupo;

Secao A.3 apresenta o questionario online usado para obter o feedback cada partici-pante sobre o experimento (Questionario de Feedback);

Secao A.4 apresenta o tempo gasto por cada participante para realizar as tarefas doexperimento;

Secao A.5 apresenta as respostas dos participantes do Questionario Preliminar eQuestionario de Feedback ;

Secao A.6 apresenta o script utilizado para analisar os dados com R;

A.1 QUESTIONARIO PRELIMINAR

111

/

Termo de consentimento livre e esclarecido1. Você está sendo convidado para participar da pesquisa Identificação e refatoração de test smells .2. Você foi selecionado para ser voluntário e sua participação não é obrigatória.3. A qualquer momento você pode desistir de participar e retirar seu consentimento.4. Sua recusa não trará nenhum prejuízo em sua relação com o pesquisador ou com a instituição.5. Sua participação nesta pesquisa consistirá na realização de tarefas utilizando ferramentas computacionais e em responder um questionário com questões de texto curto e questões objetivas.6. A sua participação nesta pesquisa pode envolver algum desconforto, ainda que pequeno, relacionado ao tempo despendido para a realização das tarefas e preenchimento do questionário. Faremos o possível para minimizar possíveis desconfortos e não ocupar seu tempo desnecessariamente.7. As informações obtidas serão confidenciais e asseguramos o sigilo sobre sua participação. Os dados publicados não permitirão a sua identificação.8. As informações obtidas serão utilizadas única e exclusivamente para os fins específicos deste estudo. 9. Os benefícios relacionados à sua participação estão em contribuir com a pesquisa científica. Será permitido o acesso aos resultados desta pesquisa por meio de publicações científicas realizadas a partir desse estudo.10. Este questionário utiliza o pacote de aplicativo Google Docs, portanto a coleta e o uso de informações do Google estão sujeitos à Política de privacidade do Google (https://www.google.co.uk/policies/privacy/).11. Ao clicar no botão "Concordo", você concorda com as informações aqui descritas, porém a qualquer momento você pode interromper a pesquisa sem ônus algum.12. Abaixo seguem os dados de contato dos responsáveis por esta pesquisa, com os quais você pode tirar suas dúvidas sobre sua participação.Railana Santana <[email protected]>Larissa Soares <[email protected]>Luana Martins <[email protected]>Ivan Machado (supervisor) <[email protected]>

1.

Marcar apenas uma oval.

Concordo

Bloco 1: Dados pessoais

2.

Questionário 1: Pesquisa sobre Test SmellsCaro(a) participante,

Este questionário é parte de um experimento sobre Testes Automatizados, pesquisa acadêmica do mestrado em Ciência da Computação e linha de pesquisa de Engenharia de Software da Universidade Federal da Bahia (UFBA). O objetivo da pesquisa é analisar diferentes ferramentas para identificação e refatoração de test smells. A sua participação neste estudo é fundamental.*Obrigatório

Declaro que entendi os objetivos, riscos e benefícios de minha participação na pesquisa. *

Nome completo *

112 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

/

3.

4.

5.

Marcar apenas uma oval.

Outro:

Estudante de Graduação

Graduação Completa

Estudante de Mestrado

Mestrado Completo

Estudante de Doutorado

Doutorado Completo

6.

Bloco 2: Experiência

7.

Marcar apenas uma oval.

Academia

Indústria

Academia e indústria

E-mail *

Cidade/Estado *

Escolaridade *

Instituição que estuda e/ou empresa em que trabalha

1. Onde você atua? *

A.1 QUESTIONARIO PRELIMINAR 113

/

8.

Marcar apenas uma oval.

Outro:

Pesquisador

Engenheiro de Teste

Desenvolvedor/programador

Analista de qualidade

9.

Marcar apenas uma oval.

< 1 ano

>= 1 ano e < 5 anos

>= 5 anos e < 10 anos

>= 10 anos

10.

Marcar apenas uma oval.

< 1 ano

>= 1 ano e < 5 anos

>= 5 anos e < 10 anos

>= 10 anos

Não possuo

2. Qual a sua posição atual?

3. Quantos anos de experiência em programação você possui usando qualquer linguagemde programação *

4. Quantos anos de experiência você tem em programação com JAVA? *

114 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

/

11.

Marcar apenas uma oval.

< 1 ano

>= 1 ano e < 5 anos

>= 5 anos e < 10 anos

>= 10 anos

Não possuo

12.

Marcar apenas uma oval.

< 1 ano

>= 1 ano e < 5 anos

>= 5 anos e < 10 anos

>= 10 anos

Não possuo

13.

Marcar apenas uma oval.

< 1 ano

>= 1 ano e < 5 anos

>= 5 anos e < 10 anos

>= 10 anos

Não possuo

5. Quantos anos de experiência você possui no uso do Eclipse IDE para programação? *

6. Quantos anos de experiência você tem na área de testes de software? *

7. Quantos anos de experiência você tem no desenvolvimento de testes com o JUnit? *

A.1 QUESTIONARIO PRELIMINAR 115

/

14.

Marcar apenas uma oval.

Outro:

Trabalho/trabalhei com testes utilizando Teste Automatizado

Sou pesquisador trabalhando em tópicos relacionados a Teste Automatizado

Possuo conhecimento sobre Teste Automatizado, mas nunca trabalhei com Testesautomatizados

Eu nunca ouvi falar sobre Teste Automatizado

15.

Marcar apenas uma oval.

Outro:

Sei o que são Test Smells

Sou pesquisador e trabalho com tópicos relacionados a Test Smells

Sei o que são Test Smells, mas nunca trabalhei com prevenção e refatoração de Test Smells

Eu nunca ouvi falar sobre Test Smells

Este conteúdo não foi criado nem aprovado pelo Google.

8. Em relação ao seu conhecimento sobre Teste Automatizado *

9. Em relação ao seu conhecimento sobre Test Smells *

 Formulários

116 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

A.2 PROTOCOLO DO EXPERIMENTO 117

A.2 PROTOCOLO DO EXPERIMENTO

○ Possível Efeito: Várias declarações de asserção em um método de teste sem uma mensagem descritiva afetam a legibilidade e facilidade de compreensão e manutenção, pois não é possível entender o motivo da falha do teste.

○ Detecção: Verifica se o teste possui um método com mais de uma declaração de asserção sem uma explicação (parâmetro no método de asserção).

○ Refatoração: Incluir mensagem de explicação no asserção, referente ao teste que está sendo feito pelo assert. No JUnit, as asserções possuem um primeiro argumento opcional para adicionar uma mensagem que explica quando a asserção falha. Assim, torna-se mais fácil compreender as diferentes asserções que ocorrem no mesmo teste.

● Duplicate Assert: Ocorre quando um método de teste testa a mesma

condição várias vezes no mesmo método de teste. ○ Exemplo:

118 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

○ Possível Efeito: Um método de teste que testa a mesma condição com valores diferentes.

○ Detecção: Um método de teste que contém mais de uma declaração de asserção com os mesmos parâmetros.

○ Refatoração: Se houver necessidade de testar a mesma condição com valores diferentes, um novo método de teste deve ser criado; o nome do método de teste deve ser uma indicação do teste que está sendo executado.

Objetivo do experimento

Objetivo do experimento: identificar e refatorar test smells. Treinamento 1: tsDetect - Reflections

tsDetect Ferramenta analisadora de test smells (via terminal). Etapas principais:

● Test File Detect ● Test File Mapping ● Teste Smell Detect

(apresentar demonstração)

Passos: Abrir a pasta do projeto $ cd pasta_tarefa Rodar o TestFileDetector $ java -jar TestFileDetector.jar pasta_projeto ⚠ Fazer cópia e remover colunas desnecessárias do arquivo csv Rodar o Test File Mapping $ java -jar TestFileMapping.jar nome_arquivo_classetest ⚠ Remover colunas desnecessárias do arquivo csv. Caso o Test File Mapping não encontre todos os arquivos de produção, remover as linhas com apenas o caminho do teste Rodar o Test Smell Detect $ java -jar TestSmellDetector.jar nome_arquivo_csv

A.2 PROTOCOLO DO EXPERIMENTO 119

⚠ Abrir o arquivo csv com o excel

Reflections Análise de metadados de tempo de execução Java.

Cenário do caso de teste:

Você recebe os testes de unidade que foram desenvolvidos no projeto do Reflections.

Tarefa: 1. Rode a ferramenta tsDetect no terminal. 2. Abra o arquivo gerado 3. Explore arquivo e saída e tente entender como o

arquivo de saída apresenta os smells 4. A ferramenta indicou smells do tipo Assertion

Roulette no projeto? a. Você concorda com o resultado apresentado

pela ferramenta? b. Se sim, informe as linhas onde eles estão

localizados. c. Refatore os smells identificados. d. Como você fez a refatoração?

5. A ferramenta indicou smells do tipo Duplicate Assert?

a. Você concorda com o resultado apresentado pela ferramenta?

b. Se sim, informe as linhas onde eles estão localizados.

c. Refatore os smells identificados. d. Como você fez a refatoração?

Tarefa 1: tsDetect - Joda Time

Você tem 20 minutos para analisar o teste de unidade. Caso o teste

apresente test smells, você deve corrigi-los.

Joda-Time Fornece uma substituição de qualidade para as classes de data e hora do Java. O design permite vários sistemas de calendário, enquanto ainda fornece uma API simples. O calendário 'padrão' é o padrão ISO8601 usado pelo XML.

Tarefa 1. Rode a ferramenta tsDetect no terminal. 2. Abra o arquivo gerado

120 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

3. Há smells do tipo Assertion Roulette ? a. Se sim, informe as linhas onde eles estão

localizados. b. Refatore os smells identificados. c. Como você fez a refatoração?

4. Há smells do tipo Duplicate Assert ? e. Se sim, informe as linhas onde eles estão

localizados. f. Refatore os smells identificados. g. Como você fez a refatoração?

Treinamento 2: RAIDE - Reflections

RAIDE Ferramenta analisadora de test smells (plugin do eclipse). Principais features: Identificação de Test Smells Refatoração de Test Smells (apresentar demonstração)

Reflections Análise de metadados de tempo de execução Java.

Cenário do caso de teste:

Você recebe os testes de unidade que foram desenvolvidos no projeto do Reflections.

Tarefa: 1. Abra o plugin RAIDE no Eclipse. 2. Selecione o pacote de teste e identifique os test

smells 3. Explore os resultados apresentados pelo RAIDE

e tente entender como a aba de visualização apresenta os smells

4. A ferramenta indicou smells do tipo Assertion Roulette no projeto ?

a. Você concorda com o resultado apresentado pela ferramenta?

b. Se sim, informe as linhas onde eles estão localizados.

c. Refatore os smells identificados. d. Como você fez a refatoração?

A.2 PROTOCOLO DO EXPERIMENTO 121

5. A ferramenta indicou smells do tipo Duplicate Assert no projeto ?

a. Você concorda com o resultado apresentado pela ferramenta?

b. Se sim, informe as linhas onde eles estão localizados.

c. Refatore os smells identificados. d. Como você fez a refatoração?

Tarefa 2: RAIDE - Commons-Collection

Você tem 20 minutos para analisar o teste de unidade. Caso o teste

apresente test smells, você deve corrigi-los.

Commons-Colle ction

Adicionou muitas estruturas de dados poderosas que aceleram o desenvolvimento dos aplicativos Java mais significativos. Se tornou o padrão reconhecido para manipulação de coleções em Java. O Commons-Collections procura desenvolver as classes JDK, fornecendo novas interfaces, implementações e utilitários

Tarefa 1. Abra o plugin RAIDE no Eclipse. 2. Selecione o pacote de teste e identifique os test smells 3. Há smells do tipo Assertion Roulette ?

a. Se sim, informe as linhas onde eles estão localizados.

b. Refatore os smells identificados. c. Como você fez a refatoração?

4. Há smells do tipo Duplicate Assert ? a. Se sim, informe as linhas onde eles estão

localizados. b. Refatore os smells identificados. c. Como você fez a refatoração?

Aplicar questionário 2 Link do questionário 2

122 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

Grupo 2

Cronograma: ● Aplicar questionário 1 ● Definição de conceitos ● Objetivo do experimento ● Treinamento 1: RAIDE - Reflections ● Tarefa 1: RAIDE - Commons Collection ● Treinamento 2: tsDetect - Reflections ● Tarefa 2: tsDetect - Joda Time ● Aplicar questionário 2

Obs.: As informações serão lidas, com a finalidade de manter o padrão, já que se trata de um estudo experimental e o treinamento com todos os participantes deve ser o mais semelhante. Utilizaremos o protocolo de Pense em voz alta , pois torna o processo mais explícito durante as tarefas.

Aplicar questionário 1

Link do questionário 1

Definição de conceitos

Test Smells: O código de teste, assim como o código fonte de produção está sujeito a práticas de programação inadequadas, também conhecidas como anti padrões ou smells. Os Test Smells são considerados decisões ou práticas ruins de design, os quais diminuem a qualidade dos testes, e tornam os testes mais difíceis de serem compreendidos e mantidos durante a evolução do sistema. Tipos de Smells:

● Assertion Roulette: Ocorre quando um método de teste tem múltiplas asserções não documentadas.

○ Exemplo:

A.2 PROTOCOLO DO EXPERIMENTO 123

○ Possível Efeito: Várias declarações de asserção em um método de teste sem uma mensagem descritiva afetam a legibilidade e facilidade de compreensão e manutenção, pois não é possível entender o motivo da falha do teste.

○ Detecção: Verifica se o teste possui um método com mais de uma declaração de asserção sem uma explicação (parâmetro no método de asserção).

○ Refatoração: Incluir mensagem de explicação no asserção, referente ao teste que está sendo feito pelo assert. No JUnit, as asserções possuem um primeiro argumento opcional para adicionar uma mensagem que explica quando a asserção falha. Assim, torna-se mais fácil compreender as diferentes asserções que ocorrem no mesmo teste.

● Duplicate Assert: Ocorre quando um método de teste testa a mesma

condição várias vezes no mesmo método de teste. ○ Exemplo:

124 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

○ Possível Efeito: Um método de teste que testa a mesma condição com valores diferentes.

○ Detecção: Um método de teste que contém mais de uma declaração de asserção com os mesmos parâmetros.

○ Refatoração: Se houver necessidade de testar a mesma condição com valores diferentes, um novo método de teste deve ser criado; o nome do método de teste deve ser uma indicação do teste que está sendo executado.

Objetivo do experimento

Objetivo do experimento: identificar e refatorar test smells. Treinamento 1: RAIDE - Reflections

RAIDE Ferramenta analisadora de test smells (plugin do eclipse). Principais features: Identificação de Test Smells Refatoração de Test Smells (apresentar demonstração)

Reflections Análise de metadados de tempo de execução Java.

Cenário do caso de teste:

Você recebe os testes de unidade que foram desenvolvidos no projeto do Reflections.

Tarefa: 1. Abra o plugin RAIDE no Eclipse. 2. Selecione o pacote de teste e identifique os test

smells 3. Explore os resultados apresentados pelo RAIDE

e tente entender como a aba de visualização apresenta os smells

4. A ferramenta indicou smells do tipo Assertion Roulette no projeto ?

a. Você concorda com o resultado apresentado pela ferramenta?

b. Se sim, informe as linhas onde eles estão localizados.

c. Refatore os smells identificados. d. Como você fez a refatoração?

A.2 PROTOCOLO DO EXPERIMENTO 125

5. A ferramenta indicou smells do tipo Duplicate Assert no projeto ?

a. Você concorda com o resultado apresentado pela ferramenta?

b. Se sim, informe as linhas onde eles estão localizados.

c. Refatore os smells identificados. d. Como você fez a refatoração?

Tarefa 1: RAIDE - Commons-Collection

Você tem 20 minutos para analisar o teste de unidade. Caso o teste

apresente test smells, você deve corrigi-los.

Commons-Colle ction

Adicionou muitas estruturas de dados poderosas que aceleram o desenvolvimento dos aplicativos Java mais significativos. Se tornou o padrão reconhecido para manipulação de coleções em Java. O Commons-Collections procura desenvolver as classes JDK, fornecendo novas interfaces, implementações e utilitários

Tarefa 1. Abra o plugin RAIDE no Eclipse. 2. Selecione o pacote de teste e identifique os test smells 3. Há smells do tipo Assertion Roulette ?

a. Se sim, informe as linhas onde eles estão localizados.

b. Refatore os smells identificados. c. Como você fez a refatoração?

4. Há smells do tipo Duplicate Assert ? a. Se sim, informe as linhas onde eles estão

localizados. b. Refatore os smells identificados. c. Como você fez a refatoração?

Treinamento 2: tsDetect - Reflections

tsDetect Ferramenta analisadora de test smells (via terminal). Etapas principais:

● Test File Detect

126 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

● Test File Mapping ● Teste Smell Detect

(apresentar demonstração)

Passos: Abrir a pasta do projeto $ cd pasta_tarefa Rodar o TestFileDetector $ java -jar TestFileDetector.jar pasta_projeto ⚠ Fazer cópia e remover colunas desnecessárias do arquivo csv Rodar o Test File Mapping $ java -jar TestFileMapping.jar nome_arquivo_classetest ⚠ Remover colunas desnecessárias do arquivo csv. Caso o Test File Mapping não encontre todos os arquivos de produção, remover as linhas com apenas o caminho do teste Rodar o Test Smell Detect $ java -jar TestSmellDetector.jar nome_arquivo_csv ⚠ Abrir o arquivo csv com o excel

Reflections Análise de metadados de tempo de execução Java.

Cenário do caso de teste:

Você recebe os testes de unidade que foram desenvolvidos no projeto do Reflections.

Tarefa: 1. Rode a ferramenta tsDetect no terminal. 2. Abra o arquivo gerado 3. Explore arquivo e saída e tente entender como o

arquivo de saída apresenta os smells 4. A ferramenta indicou smells do tipo Assertion

Roulette no projeto? a. Você concorda com o resultado apresentado

pela ferramenta? b. Se sim, informe as linhas onde eles estão

localizados. c. Refatore os smells identificados.

A.2 PROTOCOLO DO EXPERIMENTO 127

d. Como você fez a refatoração? 5. A ferramenta indicou smells do tipo Duplicate

Assert? a. Você concorda com o resultado apresentado

pela ferramenta? b. Se sim, informe as linhas onde eles estão

localizados. c. Refatore os smells identificados. d. Como você fez a refatoração?

Tarefa 2: tsDetect - Joda Time

Você tem 20 minutos para analisar o teste de unidade. Caso o teste

apresente test smells, você deve corrigi-los.

Joda-Time Fornece uma substituição de qualidade para as classes de data e hora do Java. O design permite vários sistemas de calendário, enquanto ainda fornece uma API simples. O calendário 'padrão' é o padrão ISO8601 usado pelo XML.

Tarefa 1. Rode a ferramenta tsDetect no terminal. 2. Abra o arquivo gerado 3. Há smells do tipo Assertion Roulette ?

a. Se sim, informe as linhas onde eles estão localizados.

b. Refatore os smells identificados. c. Como você fez a refatoração?

4. Há smells do tipo Duplicate Assert ? a. Se sim, informe as linhas onde eles estão

localizados. b. Refatore os smells identificados. c. Como você fez a refatoração?

Aplicar questionário 2 Link do questionário 2

128 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

Grupo 3

Cronograma: ● Aplicar questionário 1 ● Definição de conceitos ● Objetivo do experimento ● Treinamento 1: tsDetect - Reflections ● Tarefa 1: tsDetect - Commons Collection ● Treinamento 2: RAIDE - Reflections ● Tarefa 2: RAIDE - Joda Time ● Aplicar questionário 2

Obs.: As informações serão lidas, com a finalidade de manter o padrão, já que se trata de um estudo experimental e o treinamento com todos os participantes deve ser o mais semelhante. Utilizaremos o protocolo de Pense em voz alta , pois torna o processo mais explícito durante as tarefas.

Aplicar questionário 1

Link do questionário 1

Definição de conceitos

Test Smells: O código de teste, assim como o código fonte de produção está sujeito a práticas de programação inadequadas, também conhecidas como anti padrões ou smells. Os Test Smells são considerados decisões ou práticas ruins de design, os quais diminuem a qualidade dos testes, e tornam os testes mais difíceis de serem compreendidos e mantidos durante a evolução do sistema. Tipos de Smells:

● Assertion Roulette: Ocorre quando um método de teste tem múltiplas asserções não documentadas.

○ Exemplo:

○ Possível Efeito: Várias declarações de asserção em um método

de teste sem uma mensagem descritiva afetam a legibilidade e

A.2 PROTOCOLO DO EXPERIMENTO 129

facilidade de compreensão e manutenção, pois não é possível entender o motivo da falha do teste.

○ Detecção: Verifica se o teste possui um método com mais de uma declaração de asserção sem uma explicação (parâmetro no método de asserção).

○ Refatoração: Incluir mensagem de explicação no asserção, referente ao teste que está sendo feito pelo assert. No JUnit, as asserções possuem um primeiro argumento opcional para adicionar uma mensagem que explica quando a asserção falha. Assim, torna-se mais fácil compreender as diferentes asserções que ocorrem no mesmo teste.

● Duplicate Assert: Ocorre quando um método de teste testa a mesma

condição várias vezes no mesmo método de teste. ○ Exemplo:

○ Possível Efeito: Um método de teste que testa a mesma

condição com valores diferentes. ○ Detecção: Um método de teste que contém mais de uma

declaração de asserção com os mesmos parâmetros. ○ Refatoração: Se houver necessidade de testar a mesma

condição com valores diferentes, um novo método de teste deve ser criado; o nome do método de teste deve ser uma indicação do teste que está sendo executado.

Objetivo do experimento

Objetivo do experimento: identificar e refatorar test smells.

130 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

Treinamento 1: tsDetect - Reflections

tsDetect Ferramenta analisadora de test smells (via terminal). Etapas principais:

● Test File Detect ● Test File Mapping ● Teste Smell Detect

(apresentar demonstração)

Passos: Abrir a pasta do projeto $ cd pasta_tarefa Rodar o TestFileDetector $ java -jar TestFileDetector.jar pasta_projeto ⚠ Fazer cópia e remover colunas desnecessárias do arquivo csv Rodar o Test File Mapping $ java -jar TestFileMapping.jar nome_arquivo_classetest ⚠ Remover colunas desnecessárias do arquivo csv. Caso o Test File Mapping não encontre todos os arquivos de produção, remover as linhas com apenas o caminho do teste Rodar o Test Smell Detect $ java -jar TestSmellDetector.jar nome_arquivo_csv ⚠ Abrir o arquivo csv com o excel

Reflections Análise de metadados de tempo de execução Java.

Cenário do caso de teste:

Você recebe os testes de unidade que foram desenvolvidos no projeto do Reflections.

Tarefa: 1. Rode a ferramenta tsDetect no terminal. 2. Abra o arquivo gerado 3. Explore arquivo e saída e tente entender como o

arquivo de saída apresenta os smells

A.2 PROTOCOLO DO EXPERIMENTO 131

4. A ferramenta indicou smells do tipo Assertion Roulette no projeto?

a. Você concorda com o resultado apresentado pela ferramenta?

b. Se sim, informe as linhas onde eles estão localizados.

c. Refatore os smells identificados. d. Como você fez a refatoração?

5. A ferramenta indicou smells do tipo Duplicate Assert?

a. Você concorda com o resultado apresentado pela ferramenta?

b. Se sim, informe as linhas onde eles estão localizados.

c. Refatore os smells identificados. d. Como você fez a refatoração?

Tarefa 1: tsDetect - Commons-Collection

Você tem 20 minutos para analisar o teste de unidade. Caso o teste

apresente test smells, você deve corrigi-los.

Commons-Colle ction

Adicionou muitas estruturas de dados poderosas que aceleram o desenvolvimento dos aplicativos Java mais significativos. Se tornou o padrão reconhecido para manipulação de coleções em Java. O Commons-Collections procura desenvolver as classes JDK, fornecendo novas interfaces, implementações e utilitários

Tarefa 1. Rode a ferramenta tsDetect no terminal. 2. Abra o arquivo gerado 3. Há smells do tipo Assertion Roulette ?

a. Se sim, informe as linhas onde eles estão localizados.

b. Refatore os smells identificados. c. Como você fez a refatoração?

4. Há smells do tipo Duplicate Assert ? a. Se sim, informe as linhas onde eles estão

localizados. b. Refatore os smells identificados. c. Como você fez a refatoração?

132 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

Treinamento 2: RAIDE - Reflections

RAIDE Ferramenta analisadora de test smells (plugin do eclipse). Principais features: Identificação de Test Smells Refatoração de Test Smells (apresentar demonstração)

Reflections Análise de metadados de tempo de execução Java.

Cenário do caso de teste:

Você recebe os testes de unidade que foram desenvolvidos no projeto do Reflections.

Tarefa: 1. Abra o plugin RAIDE no Eclipse. 2. Selecione o pacote de teste e identifique os test

smells 3. Explore os resultados apresentados pelo RAIDE

e tente entender como a aba de visualização apresenta os smells

4. A ferramenta indicou smells do tipo Assertion Roulette no projeto ?

a. Você concorda com o resultado apresentado pela ferramenta?

b. Se sim, informe as linhas onde eles estão localizados.

c. Refatore os smells identificados. d. Como você fez a refatoração?

5. A ferramenta indicou smells do tipo Duplicate Assert no projeto ?

a. Você concorda com o resultado apresentado pela ferramenta?

b. Se sim, informe as linhas onde eles estão localizados.

c. Refatore os smells identificados. d. Como você fez a refatoração?

A.2 PROTOCOLO DO EXPERIMENTO 133

Tarefa 2: RAIDE - Joda Time

Você tem 20 minutos para analisar o teste de unidade. Caso o teste apresente test smells, você deve corrigi-los.

Joda-Time Fornece uma substituição de qualidade para as classes de data e hora do Java. O design permite vários sistemas de calendário, enquanto ainda fornece uma API simples. O calendário 'padrão' é o padrão ISO8601 usado pelo XML.

Tarefa 1. Abra o plugin RAIDE no Eclipse. 2. Selecione o pacote de teste e identifique os test smells 3. Há smells do tipo Assertion Roulette ?

a. Se sim, informe as linhas onde eles estão localizados.

b. Refatore os smells identificados. c. Como você fez a refatoração?

4. Há smells do tipo Duplicate Assert ? a. Se sim, informe as linhas onde eles estão

localizados. b. Refatore os smells identificados. c. Como você fez a refatoração?

Aplicar questionário 2 Link do questionário 2

134 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

Grupo 4 Cronograma:

● Aplicar questionário 1 ● Definição de conceitos ● Objetivo do experimento ● Treinamento 1: RAIDE - Reflections ● Tarefa 1: RAIDE - Joda Time ● Treinamento 2: tsDetect - Reflections ● Tarefa 2: tsDetect - Commons Collection ● Aplicar questionário 2

Obs.: As informações serão lidas, com a finalidade de manter o padrão, já que se trata de um estudo experimental e o treinamento com todos os participantes deve ser o mais semelhante. Utilizaremos o protocolo de Pense em voz alta , pois torna o processo mais explícito durante as tarefas.

Aplicar questionário 1

Link do questionário 1

Definição de conceitos

Test Smells: O código de teste, assim como o código fonte de produção está sujeito a práticas de programação inadequadas, também conhecidas como anti padrões ou smells. Os Test Smells são considerados decisões ou práticas ruins de design, os quais diminuem a qualidade dos testes, e tornam os testes mais difíceis de serem compreendidos e mantidos durante a evolução do sistema. Tipos de Smells:

● Assertion Roulette: Ocorre quando um método de teste tem múltiplas asserções não documentadas.

○ Exemplo:

○ Possível Efeito: Várias declarações de asserção em um método

de teste sem uma mensagem descritiva afetam a legibilidade e

A.2 PROTOCOLO DO EXPERIMENTO 135

facilidade de compreensão e manutenção, pois não é possível entender o motivo da falha do teste.

○ Detecção: Verifica se o teste possui um método com mais de uma declaração de asserção sem uma explicação (parâmetro no método de asserção).

○ Refatoração: Incluir mensagem de explicação no asserção, referente ao teste que está sendo feito pelo assert. No JUnit, as asserções possuem um primeiro argumento opcional para adicionar uma mensagem que explica quando a asserção falha. Assim, torna-se mais fácil compreender as diferentes asserções que ocorrem no mesmo teste.

● Duplicate Assert: Ocorre quando um método de teste testa a mesma

condição várias vezes no mesmo método de teste. ○ Exemplo:

○ Possível Efeito: Um método de teste que testa a mesma

condição com valores diferentes. ○ Detecção: Um método de teste que contém mais de uma

declaração de asserção com os mesmos parâmetros. ○ Refatoração: Se houver necessidade de testar a mesma

condição com valores diferentes, um novo método de teste deve ser criado; o nome do método de teste deve ser uma indicação do teste que está sendo executado.

Objetivo do experimento

Objetivo do experimento: identificar e refatorar test smells.

136 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

Treinamento 1: RAIDE - Reflections

RAIDE Ferramenta analisadora de test smells (plugin do eclipse). Principais features: Identificação de Test Smells Refatoração de Test Smells (apresentar demonstração)

Reflections Análise de metadados de tempo de execução Java.

Cenário do caso de teste:

Você recebe os testes de unidade que foram desenvolvidos no projeto do Reflections.

Tarefa: 1. Abra o plugin RAIDE no Eclipse. 2. Selecione o pacote de teste e identifique os test

smells 3. Explore os resultados apresentados pelo RAIDE

e tente entender como a aba de visualização apresenta os smells

4. A ferramenta indicou smells do tipo Assertion Roulette no projeto ?

a. Você concorda com o resultado apresentado pela ferramenta?

b. Se sim, informe as linhas onde eles estão localizados.

c. Refatore os smells identificados. d. Como você fez a refatoração?

5. A ferramenta indicou smells do tipo Duplicate Assert no projeto ?

a. Você concorda com o resultado apresentado pela ferramenta?

b. Se sim, informe as linhas onde eles estão localizados.

c. Refatore os smells identificados. d. Como você fez a refatoração?

A.2 PROTOCOLO DO EXPERIMENTO 137

Tarefa 1: RAIDE - Joda-Time

Você tem 20 minutos para analisar o teste de unidade. Caso o teste apresente test smells, você deve corrigi-los.

Joda-Time Fornece uma substituição de qualidade para as classes de data e hora do Java. O design permite vários sistemas de calendário, enquanto ainda fornece uma API simples. O calendário 'padrão' é o padrão ISO8601 usado pelo XML.

Tarefa 5. Abra o plugin RAIDE no Eclipse. 6. Selecione o pacote de teste e identifique os test smells 7. Há smells do tipo Assertion Roulette ?

a. Se sim, informe as linhas onde eles estão localizados.

b. Refatore os smells identificados. c. Como você fez a refatoração?

8. Há smells do tipo Duplicate Assert ? a. Se sim, informe as linhas onde eles estão

localizados. b. Refatore os smells identificados. c. Como você fez a refatoração?

Treinamento 2: tsDetect - Reflections

tsDetect Ferramenta analisadora de test smells (via terminal). Etapas principais:

● Test File Detect ● Test File Mapping ● Teste Smell Detect

(apresentar demonstração)

Passos:

138 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

Abrir a pasta do projeto $ cd pasta_tarefa Rodar o TestFileDetector $ java -jar TestFileDetector.jar pasta_projeto ⚠ Fazer cópia e remover colunas desnecessárias do arquivo csv Rodar o Test File Mapping $ java -jar TestFileMapping.jar nome_arquivo_classetest ⚠ Remover colunas desnecessárias do arquivo csv. Caso o Test File Mapping não encontre todos os arquivos de produção, remover as linhas com apenas o caminho do teste Rodar o Test Smell Detect $ java -jar TestSmellDetector.jar nome_arquivo_csv ⚠ Abrir o arquivo csv com o excel

Reflections Análise de metadados de tempo de execução Java.

Cenário do caso de teste:

Você recebe os testes de unidade que foram desenvolvidos no projeto do Reflections.

Tarefa: 6. Rode a ferramenta tsDetect no terminal. 7. Abra o arquivo gerado 8. Explore arquivo e saída e tente entender como o

arquivo de saída apresenta os smells 9. A ferramenta indicou smells do tipo Assertion

Roulette no projeto? a. Você concorda com o resultado apresentado

pela ferramenta? b. Se sim, informe as linhas onde eles estão

localizados. c. Refatore os smells identificados. d. Como você fez a refatoração?

10.A ferramenta indicou smells do tipo Duplicate Assert?

a. Você concorda com o resultado apresentado pela ferramenta?

b. Se sim, informe as linhas onde eles estão localizados.

c. Refatore os smells identificados. d. Como você fez a refatoração?

A.2 PROTOCOLO DO EXPERIMENTO 139

Tarefa 2: tsDetect - Commons-Collection

Você tem 20 minutos para analisar o teste de unidade. Caso o teste

apresente test smells, você deve corrigi-los.

Commons-Colle ction

Adicionou muitas estruturas de dados poderosas que aceleram o desenvolvimento dos aplicativos Java mais significativos. Se tornou o padrão reconhecido para manipulação de coleções em Java. O Commons-Collections procura desenvolver as classes JDK, fornecendo novas interfaces, implementações e utilitários

Tarefa 5. Rode a ferramenta tsDetect no terminal. 6. Abra o arquivo gerado 7. Há smells do tipo Assertion Roulette ?

a. Se sim, informe as linhas onde eles estão localizados.

b. Refatore os smells identificados. c. Como você fez a refatoração?

8. Há smells do tipo Duplicate Assert ? a. Se sim, informe as linhas onde eles estão

localizados. b. Refatore os smells identificados. c. Como você fez a refatoração?

Aplicar questionário 2 Link do questionário 2

140 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

A.3 QUESTIONARIO DE FEEDBACK 141

A.3 QUESTIONARIO DE FEEDBACK

/

5.

6.

7.

Este conteúdo não foi criado nem aprovado pelo Google.

Você vê alguma vantagem ou desvantagem da ferramenta RAIDE?

Qual ferramenta é mais fácil de identificar cada tipo test smell?

O que torna essa ferramenta mais fácil em comparação com a outra?

 Formulários

142 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

A.4 DADOS COLETADOS: TEMPO GASTO PELOS PARTICIPANTES PARA REALIZAR AS TAREFAS143

A.4 DADOS COLETADOS: TEMPO GASTO PELOS PARTICIPANTES PARAREALIZAR AS TAREFAS

Tabela A.1: Tempo de realizacao das atividades do experimento

Participante Grupo Ferramenta Tarefa Test Smell Tempo (s)

P01 1 tsDetect identificacao AR e DA 471

P02 2 tsDetect identificacao AR e DA 847

P03 3 tsDetect identificacao AR e DA 936

P04 4 tsDetect identificacao AR e DA 797

P05 1 tsDetect identificacao AR e DA 1286

P06 2 tsDetect identificacao AR e DA 684

P07 3 tsDetect identificacao AR e DA 293

P08 4 tsDetect identificacao AR e DA 787

P09 1 tsDetect identificacao AR e DA 689

P10 2 tsDetect identificacao AR e DA 339

P11 3 tsDetect identificacao AR e DA 473

P12 4 tsDetect identificacao AR e DA 650

P13 1 tsDetect identificacao AR e DA 525

P14 2 tsDetect identificacao AR e DA 751

P15 3 tsDetect identificacao AR e DA 1083

P16 4 tsDetect identificacao AR e DA 487

P17 1 tsDetect identificacao AR e DA 663

P18 2 tsDetect identificacao AR e DA 397

P19 3 tsDetect identificacao AR e DA 602

P20 4 tsDetect identificacao AR e DA 824

P01 1 RAIDE identificacao AR e DA 49

P02 2 RAIDE identificacao AR e DA 65

P03 3 RAIDE identificacao AR e DA 27

P04 4 RAIDE identificacao AR e DA 37

P05 1 RAIDE identificacao AR e DA 94

P06 2 RAIDE identificacao AR e DA 70

P07 3 RAIDE identificacao AR e DA 27

P08 4 RAIDE identificacao AR e DA 55

P09 1 RAIDE identificacao AR e DA 55

P10 2 RAIDE identificacao AR e DA 39

P11 3 RAIDE identificacao AR e DA 47

P12 4 RAIDE identificacao AR e DA 73

P13 1 RAIDE identificacao AR e DA 55

P14 2 RAIDE identificacao AR e DA 121

P15 3 RAIDE identificacao AR e DA 135

P16 4 RAIDE identificacao AR e DA 82

P17 1 RAIDE identificacao AR e DA 50

P18 2 RAIDE identificacao AR e DA 58

P19 3 RAIDE identificacao AR e DA 59

P20 4 RAIDE identificacao AR e DA 81

P01 1 tsDetect refatoracao AR 49

P02 2 tsDetect refatoracao AR 68

P03 3 tsDetect refatoracao AR 53

P04 4 tsDetect refatoracao AR 113

P05 1 tsDetect refatoracao AR 229

P06 2 tsDetect refatoracao AR 27

continua na proxima pagina

144 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

Tabela A.1 Continuacao da tabela

Participante Grupo Ferramenta Tarefa Test Smell Tempo (s)

P07 3 tsDetect refatoracao AR 97

P08 4 tsDetect refatoracao AR 49

P09 1 tsDetect refatoracao AR 43

P10 2 tsDetect refatoracao AR 66

P11 3 tsDetect refatoracao AR 72

P12 4 tsDetect refatoracao AR 133

P13 1 tsDetect refatoracao AR 67

P14 2 tsDetect refatoracao AR 93

P15 3 tsDetect refatoracao AR 104

P16 4 tsDetect refatoracao AR 109

P17 1 tsDetect refatoracao AR 50

P18 2 tsDetect refatoracao AR 18

P19 3 tsDetect refatoracao AR 52

P20 4 tsDetect refatoracao AR 74

P01 1 RAIDE refatoracao AR 18

P02 2 RAIDE refatoracao AR 96

P03 3 RAIDE refatoracao AR 47

P04 4 RAIDE refatoracao AR 46

P05 1 RAIDE refatoracao AR 51

P06 2 RAIDE refatoracao AR 82

P07 3 RAIDE refatoracao AR 16

P08 4 RAIDE refatoracao AR 190

P09 1 RAIDE refatoracao AR 73

P10 2 RAIDE refatoracao AR 13

P11 3 RAIDE refatoracao AR 48

P12 4 RAIDE refatoracao AR 22

P13 1 RAIDE refatoracao AR 24

P14 2 RAIDE refatoracao AR 73

P15 3 RAIDE refatoracao AR 34

P16 4 RAIDE refatoracao AR 26

P17 1 RAIDE refatoracao AR 26

P18 2 RAIDE refatoracao AR 24

P19 3 RAIDE refatoracao AR 72

P20 4 RAIDE refatoracao AR 17

P01 1 tsDetect refatoracao DA 114

P02 2 tsDetect refatoracao DA 61

P03 3 tsDetect refatoracao DA 65

P04 4 tsDetect refatoracao DA 95

P05 1 tsDetect refatoracao DA 156

P06 2 tsDetect refatoracao DA 55

P07 3 tsDetect refatoracao DA 132

P08 4 tsDetect refatoracao DA 156

P09 1 tsDetect refatoracao DA 95

P10 2 tsDetect refatoracao DA 128

P11 3 tsDetect refatoracao DA 54

P12 4 tsDetect refatoracao DA 157

P13 1 tsDetect refatoracao DA 95

P14 2 tsDetect refatoracao DA 143

P15 3 tsDetect refatoracao DA 131

P16 4 tsDetect refatoracao DA 89

P17 1 tsDetect refatoracao DA 86

continua na proxima pagina

A.5 RESPOSTAS DO SURVEY 145

Tabela A.1 Continuacao da tabela

Participante Grupo Ferramenta Tarefa Test Smell Tempo (s)

P18 2 tsDetect refatoracao DA 63

P19 3 tsDetect refatoracao DA 142

P20 4 tsDetect refatoracao DA 127

P01 1 RAIDE refatoracao DA 5

P02 2 RAIDE refatoracao DA 3

P03 3 RAIDE refatoracao DA 4

P04 4 RAIDE refatoracao DA 2

P05 1 RAIDE refatoracao DA 2

P06 2 RAIDE refatoracao DA 1

P07 3 RAIDE refatoracao DA 1

P08 4 RAIDE refatoracao DA 1

P09 1 RAIDE refatoracao DA 2

P10 2 RAIDE refatoracao DA 1

P11 3 RAIDE refatoracao DA 7

P12 4 RAIDE refatoracao DA 2

P13 1 RAIDE refatoracao DA 4

P14 2 RAIDE refatoracao DA 4

P15 3 RAIDE refatoracao DA 2

P16 4 RAIDE refatoracao DA 2

P17 1 RAIDE refatoracao DA 2

P18 2 RAIDE refatoracao DA 2

P19 3 RAIDE refatoracao DA 1

P20 4 RAIDE refatoracao DA 3

A.5 RESPOSTAS DO SURVEY

Devido a quantidade de colunas e linhas da tabela com as respostas dos questionarios,disponibilizamos o link1 para uma melhor visualizacao das respostas dos participantes.

1Disponıvel em 〈https://zenodo.org/record/3909706#.XvYspihKjIU〉

146 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

A.6 SCRIPT

data_base <- read.csv("time2.csv")

1.2) Summarysummary(data_base)

## Participant Group Tool Task TestSmell ## P01 : 6 Min. :1.00 RAIDE :60 identification:40 AR :40 ## P02 : 6 1st Qu.:1.75 tsDetect:60 refactoring :80 both:40 ## P03 : 6 Median :2.50 DA :40 ## P04 : 6 Mean :2.50 ## P05 : 6 3rd Qu.:3.25 ## P06 : 6 Max. :4.00 ## (Other):84 ## Time ## Min. : 1.00 ## 1st Qu.: 26.75 ## Median : 65.50 ## Mean : 163.52 ## 3rd Qu.: 131.25 ## Max. :1286.00 ##

1.3) Visualizationhead(data_base)

## Participant Group Tool Task TestSmell Time ## 1 P01 1 tsDetect identification both 471 ## 2 P02 2 tsDetect identification both 847 ## 3 P03 3 tsDetect identification both 936 ## 4 P04 4 tsDetect identification both 797 ## 5 P05 1 tsDetect identification both 1286 ## 6 P06 2 tsDetect identification both 684

2) Initialization of Variables2.1) Refactoring Techniquedata_base["Refactoring_Technique"]<- paste(data_base$Tool) data_base$Refactoring_Technique[data_base$Refactoring_Technique == "RAIDE"] <- "Automated refactoring (RAIDE)" data_base$Refactoring_Technique[data_base$Refactoring_Technique == "tsDetect"] <- "Manual refactoring"

2.2) AR and DA identification

A.6 SCRIPT 147

identification <- subset(data_base, Task=="identification")

2.3) AR refactoringrefactoring_AR <- subset(data_base, Task=="refactoring" & TestSmell=="AR")

2.4) DA refactoringrefactoring_DA <- subset(data_base, Task=="refactoring" & TestSmell=="DA")

3) Data analysis of the identification time ofthe AR and DA3.1) Summary of datasummary(identification)

## Participant Group Tool Task TestSmell ## P01 : 2 Min. :1.00 RAIDE :20 identification:40 AR : 0 ## P02 : 2 1st Qu.:1.75 tsDetect:20 refactoring : 0 both:40 ## P03 : 2 Median :2.50 DA : 0 ## P04 : 2 Mean :2.50 ## P05 : 2 3rd Qu.:3.25 ## P06 : 2 Max. :4.00 ## (Other):28 ## Time Refactoring_Technique ## Min. : 27.00 Length:40 ## 1st Qu.: 57.25 Class :character ## Median : 214.00 Mode :character ## Mean : 371.57 ## 3rd Qu.: 668.25 ## Max. :1286.00 ##

3.2) Visualization of datahead(identification)

148 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

## Participant Group Tool Task TestSmell Time ## 1 P01 1 tsDetect identification both 471 ## 2 P02 2 tsDetect identification both 847 ## 3 P03 3 tsDetect identification both 936 ## 4 P04 4 tsDetect identification both 797 ## 5 P05 1 tsDetect identification both 1286 ## 6 P06 2 tsDetect identification both 684 ## Refactoring_Technique ## 1 Manual refactoring ## 2 Manual refactoring ## 3 Manual refactoring ## 4 Manual refactoring ## 5 Manual refactoring ## 6 Manual refactoring

3.3) Shapiro testshapiro.test(identification$Time)

## ## Shapiro-Wilk normality test ## ## data: identification$Time ## W = 0.84732, p-value = 7.748e-05

3.4) Mann-Whitney test#wilcox.test(identification$Time~identification$Tool) wilcox.test(identification$Time~identification$Tool, paired = TRUE, alternative = "less")

## ## Wilcoxon signed rank test ## ## data: identification$Time by identification$Tool ## V = 0, p-value = 9.537e-07 ## alternative hypothesis: true location shift is less than 0

3.5) Boxplot (tool)boxplot(identification$Time ~ identification$Tool, col=c("#ADD8E6"), ylab="Time (seconds)", xlab="Tool used")

A.6 SCRIPT 149

3.6) Summary for each Toolsummary(subset(identification, Tool=="RAIDE"))

## Participant Group Tool Task TestSmell ## P01 : 1 Min. :1.00 RAIDE :20 identification:20 AR : 0 ## P02 : 1 1st Qu.:1.75 tsDetect: 0 refactoring : 0 both:20 ## P03 : 1 Median :2.50 DA : 0 ## P04 : 1 Mean :2.50 ## P05 : 1 3rd Qu.:3.25 ## P06 : 1 Max. :4.00 ## (Other):14 ## Time Refactoring_Technique ## Min. : 27.00 Length:20 ## 1st Qu.: 48.50 Class :character ## Median : 56.50 Mode :character ## Mean : 63.95 ## 3rd Qu.: 75.00 ## Max. :135.00 ##

summary(subset(identification, Tool=="tsDetect"))

150 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

## Participant Group Tool Task TestSmell ## P01 : 1 Min. :1.00 RAIDE : 0 identification:20 AR : 0 ## P02 : 1 1st Qu.:1.75 tsDetect:20 refactoring : 0 both:20 ## P03 : 1 Median :2.50 DA : 0 ## P04 : 1 Mean :2.50 ## P05 : 1 3rd Qu.:3.25 ## P06 : 1 Max. :4.00 ## (Other):14 ## Time Refactoring_Technique ## Min. : 293.0 Length:20 ## 1st Qu.: 483.5 Class :character ## Median : 673.5 Mode :character ## Mean : 679.2 ## 3rd Qu.: 803.8 ## Max. :1286.0 ##

3.7) Standard deviationsd(identification$Time[identification$Tool == "RAIDE"])

## [1] 28.1228

sd(identification$Time[identification$Tool == "tsDetect"])

## [1] 248.7109

4) Analysis of AR refactoring time data4.1) Summary of datasummary(refactoring_AR)

## Participant Group Tool Task TestSmell ## P01 : 2 Min. :1.00 RAIDE :20 identification: 0 AR :40 ## P02 : 2 1st Qu.:1.75 tsDetect:20 refactoring :40 both: 0 ## P03 : 2 Median :2.50 DA : 0 ## P04 : 2 Mean :2.50 ## P05 : 2 3rd Qu.:3.25 ## P06 : 2 Max. :4.00 ## (Other):28 ## Time Refactoring_Technique ## Min. : 13.00 Length:40 ## 1st Qu.: 26.75 Class :character ## Median : 51.50 Mode :character ## Mean : 64.10 ## 3rd Qu.: 76.00 ## Max. :229.00 ##

A.6 SCRIPT 151

4.2) Data visualizationhead(refactoring_AR)

## Participant Group Tool Task TestSmell Time Refactoring_Technique ## 41 P01 1 tsDetect refactoring AR 49 Manual refactoring ## 42 P02 2 tsDetect refactoring AR 68 Manual refactoring ## 43 P03 3 tsDetect refactoring AR 53 Manual refactoring ## 44 P04 4 tsDetect refactoring AR 113 Manual refactoring ## 45 P05 1 tsDetect refactoring AR 229 Manual refactoring ## 46 P06 2 tsDetect refactoring AR 27 Manual refactoring

4.3) Shapiro testshapiro.test(refactoring_AR$Time)

## ## Shapiro-Wilk normality test ## ## data: refactoring_AR$Time ## W = 0.84442, p-value = 6.607e-05

4.4) Mann-Whitney test#wilcox.test(refactoring_AR$Time~refactoring_AR$Tool) wilcox.test(refactoring_AR$Time~refactoring_AR$Tool, paired = TRUE, alternative = "less")

## Warning in wilcox.test.default(x = c(18L, 96L, 47L, 46L, 51L, 82L, 16L, : cannot ## compute exact p-value with ties

## ## Wilcoxon signed rank test with continuity correction ## ## data: refactoring_AR$Time by refactoring_AR$Tool ## V = 51, p-value = 0.02287 ## alternative hypothesis: true location shift is less than 0

4.5) Boxplot (tool)boxplot(refactoring_AR$Time~refactoring_AR$Refactoring_Technique, col=c("#ADD8E6"), ylab="Time (seconds)", xlab="Tool used")

152 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

4.6) Summary for each Toolsummary(subset(refactoring_AR, Tool=="RAIDE"))

## Participant Group Tool Task TestSmell ## P01 : 1 Min. :1.00 RAIDE :20 identification: 0 AR :20 ## P02 : 1 1st Qu.:1.75 tsDetect: 0 refactoring :20 both: 0 ## P03 : 1 Median :2.50 DA : 0 ## P04 : 1 Mean :2.50 ## P05 : 1 3rd Qu.:3.25 ## P06 : 1 Max. :4.00 ## (Other):14 ## Time Refactoring_Technique ## Min. : 13.00 Length:20 ## 1st Qu.: 23.50 Class :character ## Median : 40.00 Mode :character ## Mean : 49.90 ## 3rd Qu.: 72.25 ## Max. :190.00 ##

summary(subset(refactoring_AR, Tool=="tsDetect"))

A.6 SCRIPT 153

## Participant Group Tool Task TestSmell ## P01 : 1 Min. :1.00 RAIDE : 0 identification: 0 AR :20 ## P02 : 1 1st Qu.:1.75 tsDetect:20 refactoring :20 both: 0 ## P03 : 1 Median :2.50 DA : 0 ## P04 : 1 Mean :2.50 ## P05 : 1 3rd Qu.:3.25 ## P06 : 1 Max. :4.00 ## (Other):14 ## Time Refactoring_Technique ## Min. : 18.00 Length:20 ## 1st Qu.: 49.75 Class :character ## Median : 67.50 Mode :character ## Mean : 78.30 ## 3rd Qu.: 98.75 ## Max. :229.00 ##

4.7) Standard deviationsd(refactoring_AR$Time[refactoring_AR$Tool == "RAIDE"])

## [1] 41.35456

sd(refactoring_AR$Time[refactoring_AR$Tool == "tsDetect"])

## [1] 46.38636

5) Analysis of DA refactoring time data5.1) Summary of datasummary(refactoring_DA)

## Participant Group Tool Task TestSmell ## P01 : 2 Min. :1.00 RAIDE :20 identification: 0 AR : 0 ## P02 : 2 1st Qu.:1.75 tsDetect:20 refactoring :40 both: 0 ## P03 : 2 Median :2.50 DA :40 ## P04 : 2 Mean :2.50 ## P05 : 2 3rd Qu.:3.25 ## P06 : 2 Max. :4.00 ## (Other):28 ## Time Refactoring_Technique ## Min. : 1.00 Length:40 ## 1st Qu.: 2.00 Class :character ## Median : 30.50 Mode :character ## Mean : 54.88 ## 3rd Qu.: 99.75 ## Max. :157.00 ##

154 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

5.2) Data visualizationhead(refactoring_DA)

## Participant Group Tool Task TestSmell Time Refactoring_Technique ## 81 P01 1 tsDetect refactoring DA 114 Manual refactoring ## 82 P02 2 tsDetect refactoring DA 61 Manual refactoring ## 83 P03 3 tsDetect refactoring DA 65 Manual refactoring ## 84 P04 4 tsDetect refactoring DA 95 Manual refactoring ## 85 P05 1 tsDetect refactoring DA 156 Manual refactoring ## 86 P06 2 tsDetect refactoring DA 55 Manual refactoring

5.3) Shapiro testshapiro.test(refactoring_DA$Time)

## ## Shapiro-Wilk normality test ## ## data: refactoring_DA$Time ## W = 0.80263, p-value = 7.69e-06

5.4) Mann-Whitney test#wilcox.test(refactoring_DA$Time~refactoring_DA$Tool) wilcox.test(refactoring_DA$Time~refactoring_DA$Tool, paired = TRUE, alternative = "less")

## Warning in wilcox.test.default(x = c(5L, 3L, 4L, 2L, 2L, 1L, 1L, 1L, 2L, : ## cannot compute exact p-value with ties

## ## Wilcoxon signed rank test with continuity correction ## ## data: refactoring_DA$Time by refactoring_DA$Tool ## V = 0, p-value = 4.764e-05 ## alternative hypothesis: true location shift is less than 0

5.5) Boxplot (tool)boxplot(refactoring_DA$Time ~ refactoring_DA$Refactoring_Technique, col=c("#ADD8E6"), ylab="Time (seconds)", xlab="Refactoring Technique")

A.6 SCRIPT 155

5.6) Summary for each Toolsummary(subset(refactoring_DA, Tool=="RAIDE"))

## Participant Group Tool Task TestSmell ## P01 : 1 Min. :1.00 RAIDE :20 identification: 0 AR : 0 ## P02 : 1 1st Qu.:1.75 tsDetect: 0 refactoring :20 both: 0 ## P03 : 1 Median :2.50 DA :20 ## P04 : 1 Mean :2.50 ## P05 : 1 3rd Qu.:3.25 ## P06 : 1 Max. :4.00 ## (Other):14 ## Time Refactoring_Technique ## Min. :1.00 Length:20 ## 1st Qu.:1.75 Class :character ## Median :2.00 Mode :character ## Mean :2.55 ## 3rd Qu.:3.25 ## Max. :7.00 ##

summary(subset(refactoring_DA, Tool=="tsDetect"))

156 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

## Participant Group Tool Task TestSmell ## P01 : 1 Min. :1.00 RAIDE : 0 identification: 0 AR : 0 ## P02 : 1 1st Qu.:1.75 tsDetect:20 refactoring :20 both: 0 ## P03 : 1 Median :2.50 DA :20 ## P04 : 1 Mean :2.50 ## P05 : 1 3rd Qu.:3.25 ## P06 : 1 Max. :4.00 ## (Other):14 ## Time Refactoring_Technique ## Min. : 54.00 Length:20 ## 1st Qu.: 80.75 Class :character ## Median :104.50 Mode :character ## Mean :107.20 ## 3rd Qu.:134.50 ## Max. :157.00 ##

5.7) Standard deviationsd(refactoring_DA$Time[refactoring_DA$Tool == "RAIDE"])

## [1] 1.571958

sd(refactoring_DA$Time[refactoring_DA$Tool == "tsDetect"])

## [1] 35.86466

6) Graph creation with all tasksdata_base["Tool_Desc"]<- paste(data_base$Tool) data_base$Tool_Desc[data_base$Tool_Desc == "RAIDE"] <- "With RAIDE" data_base$Tool_Desc[data_base$Tool_Desc == "tsDetect"] <- "Without RAIDE"

data_base["Task_TestSmell"]<- paste(data_base$TestSmell, data_base$Task)

data_base$Task_TestSmell[data_base$Task_TestSmell == "both identification"] <- "AR e DA)"

data_base$Task_TestSmell[data_base$Task_TestSmell == "AR refactoring"] <- "AR refactoring" data_base$Task_TestSmell[data_base$Task_TestSmell == "DA refactoring"] <- "DA refactoring"

ToolTask <- xtabs(~Tool_Desc+Task_TestSmell,data=data_base) ToolTask

A.6 SCRIPT 157

## Task_TestSmell ## Tool_Desc AR e DA) AR refactoring DA refactoring ## With RAIDE 20 20 20 ## Without RAIDE 20 20 20

# identification of test smells with the RAIDE tool AR_DA_identification_RAIDE <- subset(identification, Tool=="RAIDE") # identification of test smells with the tsDetect tool AR_DA_identification_tsDetect <- subset(identification, Tool=="tsDetect") # AR refactoring with the RAIDE tool AR_refactoring_RAIDE <- subset(refactoring_AR, Tool=="RAIDE") # AR refactoring with the tsDetect tool AR_refactoring_tsDetect <- subset(refactoring_AR, Tool=="tsDetect") # DA refactoring with the RAIDE tool DA_refactoring_RAIDE <- subset(refactoring_DA, Tool=="RAIDE") # DA refactoring with the tsDetect tool DA_refactoring_tsDetect <- subset(refactoring_DA, Tool=="tsDetect")

ToolTask[1,1] <- mean(AR_DA_identification_RAIDE$Time) ToolTask[1,2] <- mean(AR_refactoring_RAIDE$Time) ToolTask[1,3] <- mean(DA_refactoring_RAIDE$Time) ToolTask[2,1] <- mean(AR_DA_identification_tsDetect$Time) ToolTask[2,2] <- mean(AR_refactoring_tsDetect$Time) ToolTask[2,3] <- mean(DA_refactoring_tsDetect$Time) ToolTask

## Task_TestSmell ## Tool_Desc AR e DA) AR refactoring DA refactoring ## With RAIDE 63.95 49.90 2.55 ## Without RAIDE 679.20 78.30 107.20

bp <- barplot(ToolTask, main="Average Time vs. Task", xlab="", ylab = "Time (seconds)", col = c("#ADD8E6", "#6495ED"), ylim = c(0, 800), legend = rownames(ToolTask), beside=TRUE) bp

158 AVALIACAO EMPIRICA: DADOS E MATERIAL DE SUPORTE

## [,1] [,2] [,3] ## [1,] 1.5 4.5 7.5 ## [2,] 2.5 5.5 8.5

text(x = c(bp), y = ToolTask, labels = ToolTask, pos = 3) box()

A.6 SCRIPT 159