Você está na página 1de 94

Universidade Federal do Rio Grande do Norte

Centro de Ciências Exatas e da Terra


Departamento de Informática e Matemática Aplicada
Programa de Pós-Graduação em Sistemas e Computação
Mestrado Acadêmico em Sistemas e Computação

Entendendo a Relação entre Integração


Contínua e Cobertura de Testes: Um Estudo
Empírico

José Gameleira do Rêgo Neto

Natal-RN
Agosto 2021
José Gameleira do Rêgo Neto

Entendendo a Relação entre Integração Contínua e


Cobertura de Testes: Um Estudo Empírico

Dissertação de Mestrado apresentada ao Pro-


grama de Pós-Graduação em Sistemas e
Computação do Departamento de Informá-
tica e Matemática Aplicada da Universidade
Federal do Rio Grande do Norte como re-
quisito parcial para a obtenção do grau de
Mestre em Sistemas e Computação.

Linha de pesquisa:
Engenharia de Software

Orientador
Prof. Dr. Uirá Kulesza

PPgSC – Programa de Pós-Graduação em Sistemas e Computação


DIMAp – Departamento de Informática e Matemática Aplicada
CCET – Centro de Ciências Exatas e da Terra
UFRN – Universidade Federal do Rio Grande do Norte

Natal-RN
Agosto 2021
Universidade Federal do Rio Grande do Norte - UFRN
Sistema de Bibliotecas - SISBI
Catalogação de Publicação na Fonte. UFRN - Biblioteca Setorial Prof. Ronaldo Xavier de Arruda - CCET

Rêgo Neto, José Gameleira do.


Entendendo a relação entre integração contínua e cobertura de
testes: um estudo empírico / José Gameleira do Rêgo Neto. -
2021.
92f.: il.

Dissertação (Mestrado) - Universidade Federal do Rio Grande


do Norte, Departamento de Informática e Matemática Aplicada,
Programa de Pós-Graduação em Sistemas e Computação. Natal, 2021.
Orientador: Prof. Dr. Uirá Kulesza.

1. Engenharia de software - Dissertação. 2. Integração


contínua - Dissertação. 3. Cobertura de testes - Dissertação. 4.
Estudo empírico - Dissertação. I. Kulesza, Uirá. II. Título.

RN/UF/CCET CDU 004.41

Elaborado por Joseneide Ferreira Dantas - CRB-15/324


Dissertação de Mestrado sob o título Entendendo a Relação entre Integração Contínua e
Cobertura de Testes: Um Estudo Empírico apresentada por José Gameleira do Rêgo Neto
e aceita pelo Programa de Pós-Graduação em Sistemas e Computação do Departamento
de Informática e Matemática Aplicada da Universidade Federal do Rio Grande do Norte,
sendo aprovada por todos os membros da banca examinadora abaixo especificada:

Prof. Dr. Uirá Kulesza


Presidente
DIMAp – Departamento de Informática e Matemática Aplicada
UFRN – Universidade Federal do Rio Grande do Norte

Prof. Dr. Elder José Reioli Cirilo


Examinador
UFSJ – Universidade Federal de São João del-Rei

Prof. Dr. Frederico Araújo da Silva Lopes


Examinador
IMD – INSTITUTO METROPOLE DIGITAL
UFRN – Universidade Federal do Rio Grande do Norte

Prof. Dr. Nélio Alessandro Azevedo Cacho


Examinador
DIMAp – Departamento de Informática e Matemática Aplicada
UFRN – Universidade Federal do Rio Grande do Norte

Natal-RN, 13/08/2021
Dedico esse trabalho a toda minha família, meu orientador e meus colegas de grupo de
pesquisa. Sem o suporte dessas pessoas, eu não conseguiria ter chegado até aqui.
Agradecimentos

Gostaria de agradecer a todos os meus familiares e amigos por terem me ajudado


a conseguir terminar essa importante etapa da minha vida. Em especial, gostaria de
agradecer meu orientador por toda a paciência e empenho me mostrar como seguir e
finalizar esse momento da minha pesquisa.
“We can only see a short distance ahead, but we can see plenty there that needs to be
done”

Alan Turing
Entendendo a Relação entre Integração Contínua e
Cobertura de Testes: Um Estudo Empírico

Autor: José Gameleira do Rêgo Neto


Orientador(a): Prof. Dr. Uirá Kulesza

Resumo

A evolução das metodologias e práticas de desenvolvimento vem possibilitando a redução


no tempo de entrega de novas funcionalidades e melhorias de um software. Uma das prá-
ticas mais populares e utilizadas atualmente que pode contribuir para redução no tempo
de entrega do software é a Integração Contínua (Continuous Integration - CI). Ela busca
automatizar e integrar o código fonte de uma equipe com uma alta frequência durante o
desenvolvimento do software. A adoção de CI ajuda aos desenvolvedores encontrar pro-
blemas de integração mais rapidamente, agilizando na sua resolução. Acredita-se também
que a prática de CI contribui para a redução de bugs ao longo do ciclo de vida do soft-
ware, uma vez que ela também preconiza o uso de testes automatizados para garantir a
qualidade do código integrado. Uma das formas para avaliar a qualidade dos testes re-
alizados é usando métricas de cobertura de testes. Estudos recentes buscam entender a
relação que existe entre a adoção da prática de CI e os testes realizados. Este trabalho
apresenta um estudo empírico que investiga a relação entre CI e cobertura dos testes no
contexto de projetos open sources. O estudo compara projetos que adotaram a prática de
integração contínua (CI) com projetos que não adotaram CI (NOCI), assim como projetos
que adotaram CI mas são de repositórios diferentes. Os resultados do estudo sugerem que
projetos CI apresentam taxas mais altas e uma maior estabilidade na cobertura de código
quando comparado com projetos NOCI.

Palavras-chave: integração contínua, cobertura de testes, estudo empírico.


Understanding the Relationship between Continuous
Integration and Test Coverage: An Empirical Study

Author: José Gameleira do Rêgo Neto


Supervisor: Prof. Dr. Uirá Kulesza

Abstract

The evolution of software development methodologies has enabled an increase in the


delivering of new features and improvements. One of the best practices for increasing the
delivery speed is continuous integration (CI). CI is a practice that motivates automating
and integrating source code more often during software development. The adoption of CI
helps developers to find integration issues faster. It is believed that the practice of CI
helps the software to have fewer bugs throughout its lifecycle. One of the ways to find
bugs is by performing software tests, and one of the most used metrics to ensure quality
in software testing is test coverage. Therefore, it is believed that CI adoption and test
coverage have a strong relationship. Previous studies have provided preliminary evidence
for this relationship between CI and tests, however most of them do not demonstrate
them empirically. This dissertation proposes an empirical study that aims to identify the
relationship between CI adoption and test coverage through the analysis of several open
source projects. We quantify coverage trend comparisons over time between projects that
adopt (or do not ) CI. Our results suggest that CI projects have high test coverage rates
and stability, while NOCI projects have low coverage rates and less potential for growth.

Keywords: continuous integration, test coverage, empirical study.


Lista de figuras

1 Comparação de custos nos testes manuais e automatizados . . . . . . . p. 22

2 Etapas da integração contínua. Fonte: Google Cloud Website (2020). . . p. 24

3 Visão geral do processo de seleção de projetos CI . . . . . . . . . . . . p. 29

4 Visão geral do processo de seleção de projetos NOCI . . . . . . . . . . p. 30

5 Visão geral do processo de seleção de projetos CI POSCI . . . . . . . . p. 31

6 Visão geral do processo de seleção de projetos Coveralls . . . . . . . . p. 32

7 Procedimentos realizados para QP1 . . . . . . . . . . . . . . . . . . . . p. 33

8 Procedimentos realizados para QP2 . . . . . . . . . . . . . . . . . . . . p. 34

9 Visão geral do processo de seleção dos checkouts . . . . . . . . . . . . . p. 35

10 Diferenças entre os métodos Distância Euclidiana e DTW (MÜLLER, 2007) p. 40

11 Imagem com os projetos em seus respectivos grupos . . . . . . . . . . p. 47

12 Imagem com os projetos em seus respectivos grupos . . . . . . . . . . p. 48

13 Imagem com os projetos em seus respectivos grupos . . . . . . . . . . p. 52

14 Imagem com os projetos em seus respectivos grupos do datasetCoveralls p. 55


Lista de tabelas

1 Grupos do datasetCI . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 46

2 Grupos do datasetN OCI . . . . . . . . . . . . . . . . . . . . . . . . . p. 49

3 Grupos do datasetP osCI . . . . . . . . . . . . . . . . . . . . . . . . . p. 53

4 Grupos do datasetCoverallsCI . . . . . . . . . . . . . . . . . . . . . . p. 56

5 Analise comparativa entre datasetP osCI e datasetCoveralls . . . . . p. 56

6 Comparação entre os projetos por CI, cobertura, tipo do estudo e tempo p. 63

7 Comparação entre os projetos por versões analisadas e linguagens supor-


tadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 63

8 Dataset CI - Parte 1/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 73

9 Dataset CI - Parte 2/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 74

10 Dataset CI - Parte 3/3 . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 75

11 Dataset NOCI - Parte 1/3 . . . . . . . . . . . . . . . . . . . . . . . . . p. 76

12 Dataset NOCI - Parte 2/3 . . . . . . . . . . . . . . . . . . . . . . . . . p. 77

13 Dataset NOCI - Parte 3/3 . . . . . . . . . . . . . . . . . . . . . . . . . p. 78

14 Dataset POSCI - Parte 1/2 . . . . . . . . . . . . . . . . . . . . . . . . p. 79

15 Dataset POSCI - Parte 2/2 . . . . . . . . . . . . . . . . . . . . . . . . p. 80

16 Dataset Coveralls - Parte 1/2 . . . . . . . . . . . . . . . . . . . . . . . p. 84

17 Dataset Coveralls - Parte 2/2 . . . . . . . . . . . . . . . . . . . . . . . p. 87


Lista de abreviaturas e siglas

CI – Continuous Integration

NOCI – Não adoção de integração contínua

DTW – Dynamic Time Warping


Lista de símbolos
Sumário

1 Introdução p. 15

1.1 Caracterização do Problema . . . . . . . . . . . . . . . . . . . . . . . . p. 16

1.2 Trabalho Proposto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 17

1.3 Objetivos Gerais e Específicos . . . . . . . . . . . . . . . . . . . . . . . p. 18

1.4 Organização do trabalho . . . . . . . . . . . . . . . . . . . . . . . . . . p. 19

2 Fundamentação Teórica p. 20

2.1 Qualidade de software . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 20

2.2 Teste de software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 21

2.3 Integração contínua . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 23

2.4 Coveralls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 24

3 Configurações do Estudo p. 27

3.1 Questões de pesquisa . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 27

3.2 Datasets utilizados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 28

3.2.1 DatasetCI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 28

3.2.2 DatasetN OCI . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 29

3.2.3 DatasetP OSCI . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 31

3.2.4 DatasetCoveralls . . . . . . . . . . . . . . . . . . . . . . . . . . p. 31

3.3 Procedimento do Estudo . . . . . . . . . . . . . . . . . . . . . . . . . . p. 32

3.3.1 Coleta dos dados . . . . . . . . . . . . . . . . . . . . . . . . . . p. 34

3.3.2 Tratamento dos dados . . . . . . . . . . . . . . . . . . . . . . . p. 36


3.3.2.1 A Coleta de Cobertura . . . . . . . . . . . . . . . . . . p. 36

3.3.3 Obtenção dos resultados . . . . . . . . . . . . . . . . . . . . . . p. 37

3.3.3.1 Gap statistic . . . . . . . . . . . . . . . . . . . . . . . p. 37

3.3.3.2 Dynamic Time Warping . . . . . . . . . . . . . . . . . p. 39

3.3.3.3 Trend categories . . . . . . . . . . . . . . . . . . . . . p. 41

3.3.3.4 Obtenção dos dados da RQ1 . . . . . . . . . . . . . . . p. 42

3.3.3.5 Obtenção dos dados da RQ2 . . . . . . . . . . . . . . . p. 44

3.4 Considerações . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 45

4 Resultados p. 46

4.1 QP1 - Quais são as tendências do comportamento da cobertura de testes


de projetos CI e NOCI? . . . . . . . . . . . . . . . . . . . . . . . . . . p. 46

4.2 QP2 - Existe uma associação entre as taxas de cobertura de testes de


projetos CI com as de outros projetos CI advindos do Coveralls? . . . . p. 51

4.2.1 Discussão dos resultados . . . . . . . . . . . . . . . . . . . . . . p. 56

4.3 Ameaças a Validade do trabalho . . . . . . . . . . . . . . . . . . . . . . p. 58

4.3.1 Ameaças de Construção . . . . . . . . . . . . . . . . . . . . . . p. 58

4.3.2 Ameaças internas . . . . . . . . . . . . . . . . . . . . . . . . . . p. 58

4.3.3 Ameaças Externas . . . . . . . . . . . . . . . . . . . . . . . . . p. 59

5 Trabalhos Relacionados p. 60

5.1 Análise da Evolução da Cobertura em Projetos CI . . . . . . . . . . . . p. 60

5.2 Análise Comparativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 62

6 Considerações finais p. 64

6.1 Contribuições da dissertação . . . . . . . . . . . . . . . . . . . . . . . . p. 64

6.1.1 QP1 - Quais são as tendências de comportamento dos valores de


cobertura de testes de projetos CI e NOCI? . . . . . . . . . . . p. 66
6.1.2 QP2 - Existe uma associação entre as taxas de cobertura de testes
dos projetos CI analisados com as de outros projetos CI advindos
do Coveralls? . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 67

6.2 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 67

Referências p. 69

Apêndice A -- DatasetCI p. 73

Apêndice B -- DatasetN OCI p. 76

Apêndice C -- DatasetP OSCI p. 79

Apêndice D -- DatasetCoveralls p. 81

Apêndice E -- Extração de dados dos formatos Clover p. 88

Apêndice F -- Algoritmo para obtenção dos dados p. 90


15

1 Introdução

A qualidade de software é uma área que vem sendo amplamente estudada na engenha-
ria de software (CROWSTON; ANNABI; HOWISON, 2003). Tal investigação fornece diversas
medidas de qualidade de software, incluindo compreensibilidade, integridade, concisão,
portabilidade, consistência, capacidade de manutenção, testabilidade, usabilidade, con-
fiabilidade, estrutura e eficiência (BOEHM; BROWN; LIPOW, 1976) (GORTON; LIU, 2002).
Diversos trabalhos discorrem sobre como a qualidade, entre elas a de código, impactam
no sucesso do software (CHOW; CAO, 2008) (LEE; KIM; GUPTA, 2009) (REEL, 1999).

É necessário estabelecer procedimentos e expectativas para altos níveis de qualidade


antes que o desenvolvimento comece (REEL, 1999). Décadas de práticas recomendadas
de engenharia de software mostraram que quanto mais cedo os bugs são encontrados,
mais barato é para consertá-los (ABERDOUR, 2007). Por esse motivo, é necessário que os
desenvolvedores tenham bastante cuidado na definição dos respectivos níveis de qualidade
do software a ser desenvolvido e devem ser criados mecanismos para que os bugs sejam
encontrados o mais próximo possível do estágio inicial.

Em projetos open source existe a necessidade que o seu código fonte seja rigorosamente
modular, independente e autoexplicativo (STAMELOS et al., 2002). Outra razão para obter
código de alta qualidade de um projeto de código aberto é o fato de que a próxima
etapa pode ser a iniciação (fork ) de uma extensão fechada do projeto, necessitando que
os requisitos sejam melhor definidos, demandas de design e documentação sejam mais
rigorosas, e isso exige um código de alta qualidade (STAMELOS et al., 2002).

Abordagens de desenvolvimento mais modernas costumam utilizar a integração con-


tínua CI para realizar o build e testes automatizados do projeto para cada integração de
código local com o código presente em um repositório remoto (HILTON; BELL; MARINOV,
2018). Neste contexto, (DUVALL; MATYAS; GLOVER, 2007) acredita que CI pode ajudar de-
senvolvedores a avaliar a qualidade e reduzir riscos. CI é uma prática de desenvolvimento
que consiste na integração frequente, geralmente diária, das contribuições de código dos
16

membros de uma equipe. Cada integração acarreta na produção de um (build ) da apli-


cação, onde também se executam testes no intuito de se detectar o mais cedo possível
problemas de integração (FOWLER; FOEMMEL, 2006). Ao longo dos últimos anos, CI vem
sendo estudada por diversos estudos (MEYER, 2014) (MÅRTENSSON; HAMMARSTRÖM;
BOSCH, 2017) (PINTO et al., 2018) (MÅRTENSSON; STÅHL; BOSCH, 2017) (LUZ; PINTO; BO-
NIFÁCIO, 2018) (MÅRTENSSON; STÅHL; BOSCH, 2019) (PINTO; REBOUÇAS; CASTOR, 2017)
(HILTON et al., 2016) (WIDDER et al., 2019) (BERNARDO, 2017) (NERY, 2020) (VASILESCU
et al., 2015).

Os testes automatizados, que são essenciais no processo de integração contínua, po-


dem ajudar aos desenvolvedores a avaliar a qualidade do software (FOWLER; FOEMMEL,
2006). Testes automatizados são programas ou scripts que executam as funcionalidades
do sistema em cenários específicos e fazem verificações automáticas com o objetivo de
detectar bugs no sistema, assim como possíveis efeitos colaterais existentes que atrapa-
lhem na corretude do sistema (BERNARDO; KON, 2008). (BERNARDO; KON, 2008) também
relata que a grande vantagem dessa abordagem é a alta replicabilidade dos testes e uma
redução no esforço necessário para realizá-la.

Ao conduzir o desenvolvimento com testes automatizados e eliminar duplicação de


código, isso contribui para que o desenvolvedor escreva código mais confiável e com menos
erros, independentemente do seu nível de complexidade (BECK, 2003). Dessa maneira, um
projeto de software que adote a prática de CI tende a se beneficiar das vantagens de
realizar testes automatizados.

Várias pesquisas recentes estudaram o efeito de CI no contexto de projetos de de-


senvolvimento de software (BERNARDO, 2017) (NERY, 2020) (HILTON et al., 2016) (LA-
BUSCHAGNE; INOZEMTSEVA; HOLMES, 2017) (VASILESCU et al., 2015). A necessidade de
desenvolver softwares de melhor qualidade pode alinhar com a prática de CI, no sentido
que tal prática estimula a adoção maciça de testes automatizados.

1.1 Caracterização do Problema

A integração contínua (CI - continuous integration) é uma prática que busca contribuir
para a qualidade do software. Entretanto, é necessário investigar quais os aspectos de CI
que mais impactam na manutenção ou melhoria da qualidade do código fonte. CI pode
trazer a falsa impressão de que apenas gerar builds/ é suficiente para atingir um alto nível
de qualidade no código (NERY, 2020). Um dos objetivos de CI é o aumento da cobertura
17

de testes a cada nova mudança, mas também manter o conjunto de testes rápido (MEYER,
2014). Dessa forma, além de automatizar os testes, em teoria a prática de CI pode acarretar
o aumento de cobertura do código.

Quando um projeto adota integração contínua, o ideal é que ele se beneficie de todas
as vantagens que essa prática apresenta. Entretanto, muitos projetos podem não adotar
CI completamente, principalmente a parte de testes automatizados, já que existe um custo
associado a produção dos mesmos (LI et al., 2019).

O sucesso da prática de integração contínua depende da disciplina da equipe (RO-


GERS, 2004). Dessa maneira é necessário verificar se os projetos estão realmente adotando
integração contínua em cada um dos seus aspectos. (ZHAO et al., 2017) investigam qual
é o impacto da adoção da automação de processos nas práticas de desenvolvimento, con-
tabilizando frequência de commits, rotatividade de código, solicitações de pull requests e
fechamento de problemas e teste. (LABUSCHAGNE; INOZEMTSEVA; HOLMES, 2017) analisa
o overhead de se ter CI sem ferramentas de instrumentação dos builds. Enquanto (BELLER;
GOUSIOS; ZAIDMAN, 2016) analisam a quantidade de testes executadas por compilação e
a frequência de falha de tais testes. Essas pesquisas, no entanto, não servem para apoiar
ou refutar de forma abrangente as reivindicações de aumento de cobertura do código.

Nesse contexto, verificar como se comporta a cobertura de testes de projetos que


adotam CI e de projetos que não adotam CI pode ajudar a entender como a cobertura de
testes esta relacionada com a adoção da prática de CI (NERY; COSTA; KULESZA, 2019).

1.2 Trabalho Proposto

Este trabalho propõe a condução de um estudo empírico que busca entender o impacto
que a adoção de integração contínua na cobertura dos testes. Em um primeiro momento,
nós investigamos as tendências de cobertura de código ao longo do tempo de um grupo
de 30 projetos que adotaram integração contínua (projetos CI) e de projetos que não
adotaram integração contínua (projetos NOCI ). Posterior a essa etapa, verificamos quais
as tendências existentes entre esses dois grupos, comparando as dados entre os respecti-
vos grupos. Numa segunda etapa, comparamos as tendências de dados de cobertura de
projetos CI apenas após a data de adoção de integração contínua 30 projetos POSCI com
os dados de cobertura de 92 projetos do Github que utilizam o TravisCI para CI por
pelo menos 1 ano e o Coveralls1 : um serviço web de coleta e armazenamento de dados de
1
https://coveralls.io/
18

cobertura de testes de um projeto (COVERALLS, 2021).

Nós decidimos em usar pelo menos 30 projetos em cada conjunto de análise por ser
considerado, de forma heurística na estatística, como o número mínimo de tamanho de
uma amostra para se aplicar métodos estatísticos. Em relação a quantidade de dias (30
dias) e anos (2 anos) foram ideias que nos baseamos no trabalho de (NERY, 2020). Pelo
fato de que no Coveralls encontramos apenas projetos que adotaram CI, nós coletamos
versões apenas do intervalo de 1 ano. Este valor representa os dados após a adoção de CI.

A questão de pesquisa central do nosso trabalho é: existe uma relação entre integração
contínua e aumento, estabilização ou diminuição da cobertura de testes em projetos open-
source? Nossa primeira parte da pesquisa investiga de forma direta tal questão. Enquanto
a segunda parte da análise busca descobrir se existe semelhanças nas tendências entre os
dados de projetos CI (da primeira parte) com os dados dos projetos advindos do Coveralls.
Para responder nossa questão de pesquisa central, nós coletamos a cobertura dos testes
de 24 versões de 30 projetos CI e 24 versões de 30 projetos NOCI e coletamos a cobertura
de 12 versões de 92 projetos do Github que utilizaram o TravisCI e o Coveralls. Para
cada parte da análise realizada nesse estudo, nós explicamos o processo de obtenção e
tratamento dos dados na seção 3.

Devido ao alto volume de trabalho realizado para se obter as coberturas de 24 versões


de cada um dos 60 projetos (30 projetos CI e 30 projetos NOCI), nós percebemos a
necessidade de se viabilizar uma outra maneira de ter a cobertura de testes desses projetos,
sem ser pela execução de cada uma das versões. Dessa forma, o trabalho proposto busca
alavancar a possibilidade de utilizar os dados de cobertura advindos do Coveralls nas
análises entre cobertura e integração contínua. Tendo como premissa que este trabalho
pode ajudar com uma nova possibilidade de obtenção de dados menos custosa que a
realização da execução de cada uma das versões. Ao se utilizar o Coveralls, o necessário
para se obter as cobertura é apenas realizar as requisições HTTPs a sua API.

1.3 Objetivos Gerais e Específicos

O objetivo principal desta dissertação é investigar a relação de projetos open-source


que adotam a prática de integração contínua com o comportamento da cobertura de testes
de software. Um estudo empírico foi conduzido buscando atender tal objetivo. Os objetivos
específicos são:
19

• Investigar a literatura de estudos de avaliação de testes de software no contexto de


projetos que adotaram CI em projetos open-source.

• Estender e ampliar as análises de cobertura de testes conduzidos no estudo de (NERY,


2020);

• Avaliar e confrontar as tendências existentes de cobertura nos projetos CI e NOCI;

• Investigar a similaridade de comportamentos entre as coberturas de teste de projetos


CI do GitHub e de projetos provenientes do Coveralls.

1.4 Organização do trabalho

Este trabalho está organizado da seguinte forma: o Capítulo 2 apresenta a funda-


mentação teórica deste trabalho. O Capítulo 3 denota a metodologia do estudo realizado,
contemplando todos os passos utilizados em cada uma das análises. O Capítulo 4 dis-
serta sobre os resultados obtidos a partir das análises nas bases de dados. O Capítulo 5
apresenta e discute os trabalhos relacionados. O Capítulo 6 contempla as conclusões do
trabalho, com as limitações existentes e apresenta possíveis trabalhos futuros.
20

2 Fundamentação Teórica

Este capítulo apresenta a fundamentação teórica para o desenvolvimento desta dis-


sertação de mestrado. A seção 2.1 denota o conceito de qualidade de software, incluindo
maneira de se definir a qualidade e formas de busca-la. A seção 2.2 discorre sobre as
principais características da atividade de se testar um software, juntamente mostrando
algumas das formas e métricas utilizadas. Posteriormente, na seção 2.3 é denotado sobre
a prática de integração contínua, explicando a proposta desse tipo de prática, dificuldades
e os respectivos efeitos comumente associados a sua adoção no desenvolvimento de um
software. Por último, na seção 2.4 é apresentado o que é o Coveralls, sua proposta e quais
as suas principais funcionalidades.

2.1 Qualidade de software

A qualidade de software pode ser definida como um processo sistemático que focaliza
todas as etapas e artefatos produzidos com o objetivo de garantir a conformidade de
processos e produtos, prevenindo e eliminando defeitos (FITZPATRICK, 1996).

Os sistemas de software são uma parte cada vez maior da vida, de aplicativos de
negócios a produtos de consumo. A maioria das pessoas já teve uma experiência com soft-
ware que não funcionou conforme o esperado. O software que não funciona corretamente
pode causar muitos problemas, como por exemplo: perda de dinheiro, perda de tempo ou
reputação comercial. Os erros ocorridos no código ou na documentação podem resultar
em falhas no software final, mas nem todos os defeitos o fazem.

De toda sorte, a qualidade de software busca construir produtos, minimizando os de-


feitos e atendendo aos níveis especificados de confiabilidade e desempenho. Formalmente,
a qualidade de acordo com a ISO 9000 é definida como a totalidade das características
de uma entidade que influenciam sua capacidade de satisfazer necessidades declaradas ou
implícitas.
21

Atualmente, existe um grande foco no desenvolvimento ágil, devido a capacidade deles


em produzir software mais rápido, melhor adaptável a mudanças e com menos burocracia.
Contudo, ainda assim, se faz necessário averiguar se os softwares produzidos atendem aos
requisito de qualidade.

A qualidade do software pode ser aferida explorando diferentes técnicas e considerando


diferentes questões. Usualmente a literatura estabelece duas dimensões para a qualidade
de software: a qualidade do processo e a qualidade do produto (PRESSMAN, 2009). A
primeira dimensão foca-se nas etapas do processo de desenvolvimento do software, desde
a análise do problema a sua manutenção. Avalia-se, portanto, a qualidade dos processos
envolvidos em cada etapa, visando o estabelecimento de boas práticas que permitam
o ambiente necessário para a criação de produtos com excelência. Por outro lado, na
dimensão da qualidade do produto, o foco deixa de ser o processo, evidentemente, e passa
a ser a qualidade do produto resultando do ciclo de desenvolvimento.

Essa pesquisa concentra-se na dimensão da qualidade relativa ao produto gerado pelo


processo de desenvolvimento de software. Nessa dimensão, o teste de software é uma das
técnicas de garantia de qualidade amplamente utilizada na indústria de software (BERTO-
LINO, 2007).

2.2 Teste de software

O teste de software desempenha um papel crucial no processo de desenvolvimento


de software. Os desenvolvedores escrevem testes com intuito de aumentar confiança na
qualidade esperada do sistema em teste (MAHDIEH et al., 2020). A eficácia do conjunto
de testes diz respeito à capacidade dos conjuntos de testes de revelar falhas (AHMED et
al., 2016). Dessa forma, a eficácia do conjunto de testes é de suma importância para a
identificação de inconformidades software.

Teste de software é uma atividade intrinsecamente relacionada as metodologias de


desenvolvimento de software. Dessarte que cada metodologia de desenvolvimento exige
abordagens diferentes para a condução da atividade de teste. Com a difusão das meto-
dologias ágeis, tornou-se comum a utilização de ferramentas com intuito de automatizar
atividades do processo, incluindo os testes, visando atingir o dinamismo exigido por tais
filosofias.

Nesse contexto, a automação dos testes consiste na utilização de aplicativos específicos


capazes de testar funcionalidades do sistema e comparar os resultados obtidos com os
22

previstos. Embora os testes automatizados demandem maior esforço na sua fase de criação,
as execuções dos testes manuais representam um custo muito mais elevado do que os testes
automatizados. Como a Figura 11 ilustra.

Figura 1: Comparação de custos nos testes manuais e automatizados

A atividade de teste de software pode demandar uma quantidade significativa de


recursos, tornando-se em uma atividade alto custo computacional e complexa. Dessarte
que se faz necessário métodos que permitam prever a capacidade de detecção de falhas de
uma suíte de testes baseado na própria suíte de testes e na versão atual do sistema. Uma
dos método mais popular para tentar inferir a qualidade do conjunto de teste é o uso da
métrica de cobertura de código, denominada Code Coverage (HILTON; BELL; MARINOV,
2018).

A cobertura de código é uma métrica que expressa em termos percentuais a quantidade


de código fonte realmente exercitado por um conjunto de testes. A principal hipótese
associada com projeto de alta cobertura é que seus testes tem menor chance de conter
bugs não detectados do que um projeto que contém uma baixa cobertura de testes (YANG
et al., 2019).

A cobertura de código é uma reflexão do comportamento dinâmico do sistema, dado


que analisa o exercício de diversas elementos presentes no código fonte como pacotes,
classes, métodos, instruções condicionais, estruturas de controle e instruções como decla-
rações de variáveis. A cobertura de código é baseada nas técnicas de teste caixa branca,
1
https://abstracta.us/blog/test-automation/true-roi-test-automation/
23

dado que examina a estrutura interna do programa.

A literatura reporta várias metodologias para representar a cobertura de código (EL-


BAUM; GABLE; ROTHERMEL, 2001), como statement coverage, branch coverage, function
coverage e path coverage. Statement Coverage representa a proporção de instruções que
são executadas por testes automatizados sobre o número total de instruções no programa.
A branch coverage mede quais branchs do programa foram executadas pelo menos uma
vez durante os testes. Avaliando, portanto, as sub-expressões independentemente e garan-
tindo que toda condição dentro de uma decisão está coberta. Function Coverage mensura
o número de funções ou métodos exercitados pelos testes automatizados. Por fim, Path
Coverage verifica se cada um dos trajetos possíveis em cada função foi seguido.

2.3 Integração contínua

Tradicionalmente, os processos de desenvolvimento de software projetam a integração


das diferentes partes de um software somente após a implementação completa de tais
partes, não sendo raro, a integração isolada delas. Entretanto, devido principalmente ao
aumento na complexidade dos projetos e a popularização das metodologias ágeis, que
demando por ciclos de desenvolvimentos iterativos e incrementais com modificações cons-
tantes, surgiu à necessidade de se aumentar a frequência com que ocorre os processos de
integração entre as partes dos projetos. Nesse cenário, surgiu a metodologia denominada
de Integração contínua (CI).

A Integração contínua (CI) é a prática de desenvolvimento de software que visa auto-


matizar e aumentar a frequência de integração do código fonte de uma aplicação, sendo
comum várias integrações por dia (FOWLER; FOEMMEL, 2006). Uma integração é definida
como qualquer nova atualização no código-fonte do projeto. Cada integração é validada
por um build automatizado que usualmente compila os códigos-fontes, verifica erros de
integração entre componentes do software e executa os testes automatizados (FOWLER;
FOEMMEL, 2006). A Figura 2 ilustra como ocorre as etapas da integração contínua.

O processo se inicia com uma submissão ao gerenciador de repositórios de uma mo-


dificação (integração) no código fonte do projeto. Em geral, o código submetido passa
por três etapas antes de ser incorporado na versão final (release), são elas: build, teste e
geração de relatório. O Build consiste em compilar o código fonte da aplicação a fim de
gerar um arquivo executável. Em caso de sucesso, o processo segue para o estágio de teste.
O estágio de teste executa os testes automatizados a fim de verificar se software não come-
24

Figura 2: Etapas da integração contínua. Fonte: Google Cloud Website (2020).

çou a falhar após a incorporação das mudanças. Finalmente, um relatório da integração


contínua é gerado informado os resultados obtidos nos estágios anteriores. Desse modo, a
integração continua provê aos desenvolvedores feedbacks a cada integração, possibilitando
assim que os erros possam ser detectados rapidamente, facilitando as manutenções e a
evolução do sistema.

A adoção da integração contínua e de suas práticas associadas pode auxiliar na avalia-


ção da qualidade do software e reduzir os riscos inerentes ao seu desenvolvimento (MEYER,
2014). Outro benefício associado a integração contínua é aumento na produtividade da
equipe de desenvolvimento (FOWLER; FOEMMEL, 2006).

No passado, as organizações precisavam provisionar, operar e manter suas próprias


ferramentas de automação. Em geral, os desenvolvedores utilizavam ferramentas genéricas
que não tinham ciência das fases do processo de CI, não ofereciam recursos padronizados
e precisavam ser adaptadas para cada projetos. O que tornava ainda mais desafiador a
adoção de CI.

Felizmente, no mercado atual existem diversas ferramentas para auxiliar a aplicação


dos conceitos de integração contínua nos mais diversos tipos de projetos. Soluções como
Travis-CI, Jenkins e CircleCI fornecem a infraestrutura necessária para implementar a
integração contínua de forma consistente e padronizada.

2.4 Coveralls

O Coveralls é um serviço web para ajudar a rastrear a cobertura de código ao longo do


tempo e garantir que todo o seu novo código seja totalmente coberto (COVERALLS, 2021).
Ele é um cliente que recebe relatórios de coberturas de testes, deixando-os disponíveis
25

para qualquer pessoa acessa-los online. Para utiliza-lo é necessário que o código esteja nos
repositórios onlines: GitHub2 , BitBucket3 ou GitLab4

O serviço Coveralls é independente de idioma e de CI, entretanto ele não apresenta


soluções fáceis para todas as possibilidades de hospedagem de repositórios. O site denota
que criar uma conta é rápido e fácil, basta clicar no botão “Sign in” para seu serviço
git e autorizar o Coveralls a acessar seus repositórios, sem precisar preencher nenhum
formulário (COVERALLS, 2021).

Como principais funcionalidades ao utiliza-lo, os desenvolvedores conseguem 5 :

• Estatística de cobertura do repositório: Ver as estatísticas de cobertura de código


mais recentes em todos os seus repositórios, incluindo as porcentagens totais e linhas
cobertas.

• Relatório de arquivos individuais: O Coveralls divide a cobertura do teste por cada


arquivo do relatório de teste. Nele é possível ver, para cada arquivo, a cobertura
relevante, linhas cobertas/perdidas e as ocorrências por linha.

• Cobertura por linha: Nele é possível navegar pelos arquivos individuais que foram
alterados em um novo commit e ver exatamente o que mudou na cobertura do build,
linha por linha.

• Visão geral do repositório: A visão geral de Coveralls permite que se veja facilmente
os níveis de cobertura atuais dos repositórios e um gráfico das mudanças de cobertura
ao longo do tempo.

• Notificações: Pode enviar informações sobre as alterações de cobertura para os ser-


viços que você usa diariamente. Os alertas podem ser enviados por e-mail, Slack,
Hipchat, Gitter e como um webhook formatado em JSON.

• Atualizações de cobertura: Na página de atualizações mostra-se todos os commits in-


dividuais para todos os repositórios do seu projeto e como essas mudanças afetaram
a cobertura do código.

• Divulgação de relatórios: É possível que outras pessoas tenham acesso aos seus
relatórios de cobertura por meio de requisições na sua API.
2
https://github.com/
3
https://bitbucket.org/
4
https://gitlab.com/
5
https://coveralls.io/features
26

• Não necessidade de adoção de CI: É possível utilizar o Coveralls sem utilizar CI.

O Coveralls permite que um projeto publique de forma aberta os seus resultados de


coberturas de testes já realizados por outras ferramentas de modo que outras pessoas
ou pesquisadores possam utiliza-los. Além disso, garante umas transparência da aplica-
ção sobre o comportamento da cobertura e serve como arquivamento desses valores para
que estes relatórios não acabem se perdendo com o passar do tempo. Apesar de exigir a
adoção de CI, exige-se um trabalho adicional quando o projeto não utiliza uma dessas fer-
ramentas de CI: GitHub CI, Travis CI (open source), Travis Pro (private repos), CircleCI,
Semaphore, JenkinsCI, Codeship, Atlassian Bamboo, AppVeyor, Gitlab CI, Codefresh e
Layer CI. Existe a possibilidade de realizar todas ações por meio de sua API, tanto para
obter os valores ou publicar os valores de cobertura.
27

3 Configurações do Estudo

Este capítulo detalha as configurações adotadas para o estudo conduzido nesta disser-
tação. A seção 3.1 apresenta as questões de pesquisa utilizadas para guiar o andamento
deste trabalho. A seção 3.2 descreve os datasets utilizados no estudo. A seção 3.3 denota
o procedimento conduzido para o estudo, expondo tecnologias utilizadas e critérios para
realização de cada passo. Por último, a seção 3.4 apresenta as considerações finais deste
capítulo.

3.1 Questões de pesquisa

As seguintes questões de pequisa (QPs) são alvos do nosso estudo:

• QP1 - Quais são as tendências de comportamento dos valores de cobertura de testes


de projetos CI e NOCI?

– Justificativa: A resposta dessa questão de pesquisa ajuda a entender o com-


portamento da métrica de cobertura de testes durante um intervalo de tempo.
Valores de cobertura similares podem indicar tendências sobre quais projetos
apresentam comportamentos mais análogos. A presença de valores discrepantes
entre projetos CI e NOCI pode ajudar a entender o impacto da adoção de CI
no valor da cobertura dos testes de um projeto.

• QP2 - Existe uma associação entre as taxas de cobertura de testes dos projetos CI
analisados com as de outros projetos CI advindos do Coveralls?

– Justificativa: A resposta desta questão de pesquisa busca uma relação confron-


tando projetos de origem distinta mas que, por hipótese, deveriam apresentar
comportamentos análogos. Observar projetos CI oriundos de fontes distintas
mas que tenham o mesmo comportamento pode contribuir para a busca da
generalização de resultados. Caso exista uma diferença significativa entre o
28

comportamentos entre as bases de dados utilizadas, este fator motiva mais


estudos em pesquisas futuras nas possíveis causas deste fenômeno.

3.2 Datasets utilizados

Esta seção descreve como os projetos foram selecionados e o processo de coleta dos
dados utilizado na presente pesquisa. No presente trabalho, reaproveitamos o conjunto de
dados disponibilizado por (NERY, 2020). O autor analisa dois grupos de projetos de código
aberto: (I) projetos que adotaram CI em algum momento de sua vida (datasetCI) e (II)
projetos que nunca adotaram CI durante sua vida (datasetN OCI). Nós adicionalmente
criamos mais dois datasets para ajudar a responder as questões de pesquisa propostas,
consistindo no (III) grupo de projeto CI foi elaborado como um subconjunto dos projetos
CI, nos quais foram extraídos apenas os valores de cobertura das versões após a adoção de
CI (datasetP OSCI) e (IV) no grupo de projetos Coveralls que representam os projetos
nos quais seus valores de cobertura foram retirados do Coveralls (datasetCoveralls).

(NERY, 2020) analisou apenas projetos com as linguagens JAVA, Python, PHP, Ruby
e Javascript. Desse modo, o datasetCI, datasetsN OCI e datasetP OSCI apresentam
apenas projetos de uma dessas 5 linguagens, já que eles foram elaborados tomando como
base o dataset de (NERY, 2020). O único diferente é o datasetCoveralls que não apresenta
essa restrição de linguagem. O motivo que levou a não ter a exclusão de projetos de
outras linguagens, motivou-se na opção de se ter uma maior quantidade de projetos que
atendessem aos critérios e também buscar que os resultados encontrados nesse dataset
sejam mais próximos de um ambiente mais realista.

3.2.1 DatasetCI

Esse dataset é composto por projetos com um volume de dados histórico estatistica-
mente relevante e que adotaram CI em algum momento de sua história. O processo pelos
autores utilizado para coletar o conjunto de dados é ilustrado na Figura 3.

O primeiro passo consistiu em selecionar os 3.000 projetos mais populares do GitHub


escritos nas seguintes linguagens de programação: Java, Python, Ruby, PHP e JavaScript.
A popularidade dos projetos foi mensurada através do número de estrelas atribuído pelo
GitHub aos projetos. Em seguida, filtrou-se os projetos que adotam CI. Tal filtragem se
baseou-se no procedimento proposto por Bernardo et al. (BERNARDO; COSTA; KULESZA,
2018). Bernardo et al. (BERNARDO; COSTA; KULESZA, 2018) consideraram apenas os pro-
29

jetos que usam Travis-CI. Os autores evitaram projetos que usam Jenkins, uma vez que
o histórico completo de CI de tais projetos não está disponível. A identificação que um
determinado projeto utiliza o Travis-CI é realizada com base na existência de builds as-
sociados ao projeto no Travis-CI. Portanto, considerou-se como data de adoção do CI,
a data do primeiro build publicado no refrido serviço. Dos 3.000 projetos, 1.784 (59,5%)
usaram Travis-CI.

No passo 3, os pull requests de cada projeto foram agruparam em dois grupos: antes e
depois da data de adoção de CI. Os projetos com menos de 100 pull requests nos intervalos
antes ou depois e CI foram excluídos por não conterem uma quantidade considerável de
dados. Além disso, os projetos considerados toy também foram descartados, restando 87
projetos após a etapa 3.

Finalmente, descartou-se os projetos cujo código de teste não foram encontrados,


resultando em um dataset com 82 projetos habilitados para análises. Desses 82 projetos,
selecionamos 30 projetos aleatoriamente para realizar a coleta dos dados de cobertura.

Figura 3: Visão geral do processo de seleção de projetos CI

Após a coleta dos dados, a base de dados foi dividida em uma matriz bidimensional,
com 31 linhas e 25 colunas. Na primeira coluna está o nome do projeto, já nas próximas
24 colunas são os valores de coberturas coletados para análise, 12 de versões antes de
CI e 12 de versões posteriores ao uso de CI. Os valores de cobertura são organizados de
forma crescente de data, ou seja vão da primeira versão do projeto no período de antes
de adotar CI até a última versão do período de CI. A primeira linha é o cabeçalho com as
informações de cada variável e as próximas 30 linhas são os valores coletados de cobertura
de cada um dos projetos. O apêndice A mostra os valores de cobertura dessa base de
dados.

3.2.2 DatasetN OCI

O DatasetN OCI consiste de projetos que nunca adotaram CI. A Figura 4 apresenta
o processo de construção desse dataset utilizado por Bernardo et al. (BERNARDO; COSTA;
30

KULESZA, 2018). Novamente, os 3.000 projetos mais populares do GitHub escritos nas
linguagens Java, Python, Ruby, PHP e JavaScript foram selecionados. Ressaltamos mais
uma vez que a popularidade é mensurada através do número de estrelas que um projeto
possui no GitHub na data da coleta. Em seguida, os projetos que possuem ao menos um
build no Travis-CI foram descartados. Como explicado anteriormente, a presença de builds
no Travis-CI foi utilizado como critério determinante para caracterizar o uso de CI por
um projeto.

A etapa 3 busca excluir do estudo os projetos inativos e imaturos. De tal sorte que,
essa etapa filtrou os projetos ativos em 2018 e que possuem menos 4 anos de atividade no
GitHub. Ao final desse etapa temos 392 projetos candidatos.

Na etapa 4, selecionamos aleatoriamente 82 projetos dos 392 projetos NOCI obtidos


na Etapa 3. Essa seleção aleatória foi realizada de forma iterativa da seguinte maneira:
Dado que um projeto foi selecionado, verifica-se se tal projeto não é um projeto toy e
se o projeto possui testes disponíveis. Se um determinado projeto não atender a ambos
os critérios, ele é descartado e seleciona-se outro projeto aleatoriamente. Em seguida,
realizou-se uma verificação manual para averiguar se o projeto candidato possui arquivos
de configuração de outros serviços de CI populares, como por exemplo, Jenkins e CircleCI.
Caso algum projeto contenha arquivos de configuração de algum provedor de serviços de
CI conhecido, ele é excluído do dataset. Caso contrário, o projeto é finalmente aceito. Esse
processo é repetido até obter 82 projetos NOCI. Novamente, selecionamos aleatoriamente
30 dos 82 projetos habilitados.

Figura 4: Visão geral do processo de seleção de projetos NOCI

A base de dados é então dividida em uma matriz bidimensional, com 31 linhas e


25 colunas. Na primeira coluna está o nome do projeto, já nas próximas 24 colunas são
os valores de coberturas coletados para análise, 12 de versões antes da data definida
como equivalente a adoção de CI e 12 de versões posteriores a essa data. Os valores de
cobertura são organizados de forma crescente de data, ou seja vão da primeira versão do
projeto no período de antes da data equivalente a adoção de CI até a última versão do
período analisado. A primeira linha é o cabeçalho com as informações de cada variável
31

e as próximas 30 linhas são os valores coletados de cobertura de cada um dos projetos.


Detalhes de como foi definida essa data de adoção de CI para para os projetos NOCI
estão na seção 3.3.1. O apêndice B mostra os valores de cobertura dessa base de dados.

3.2.3 DatasetP OSCI

O datasetP OSCI representa os dados de cobertura dos projetos apenas para o pe-
ríodo após a adoção de integração contínua definido na seção 3.2.1. Desse modo, no lugar
de apresentar 24 valores de coberturas das versões dos projetos como no datasetCI, este
agrupamento apresenta apenas 12 valores de coberturas, que são exatamente aqueles co-
letados apenas após a data definida de CI. Este dataset é um subconjunto do dataset CI
(ver figura 8). A figura 5 mostra todo o processo de escolha do elementos desta base de
dados.

Figura 5: Visão geral do processo de seleção de projetos CI POSCI

A base de dados é dividida em uma matriz bidimensional, com 31 linhas e 13 colunas.


Na primeira coluna está o nome do projeto, já nas próximas 12 colunas são os valores
de coberturas coletados para análise: As 12 de versões posteriores a data de adoção de
integração contínua. Os valores de cobertura são organizados de forma crescente de data,
ou seja vão da primeira versão do projeto após a adoção de CI e vão até a última versão
do período analisado. A primeira linha é o cabeçalho com as informações de cada variável
e as próximas 30 linhas são os valores coletados de cobertura de cada um dos projetos. O
apêndice C mostra os valores de cobertura dessa base de dados.

3.2.4 DatasetCoveralls

Esta base de dados consiste nos dados obtidos por meio do serviço web de divulgação
de coberturas chamado Coveralls. Neste serviço os projetos podem divulgar os valores
de cobertura obtidos de modo a ajudá-lo a rastrear sua cobertura de código ao longo do
tempo e garantir que todo o novo código seja totalmente coberto (COVERALLS, 2021). Os
projetos não precisam utilizar CI para divulgar seus dados no Coveralls, entretanto não
encontramos nenhum projeto que tenha um valor de cobertura divulgado antes da data
32

do primeiro build com sucesso no TravisCI. A figura 6 mostra o processo de criação deste
dataset com os respectivos projetos resultantes de cada etapa.

Figura 6: Visão geral do processo de seleção de projetos Coveralls

No passo 1 buscamos os 1000 primeiros projetos mais estrelados na API do Github


1
no dia 22/03/2021. O número de 1000 foi escolhido por ser a quantidade máxima de
dados recebido por uma consulta (GITHUB, 2021) e a escolha do critério de projetos mais
estrelados do Github foi baseado nos trabalhos de (NERY, 2020) e (BERNARDO, 2017).

O passo 2 consiste em verificar quais dos projetos presentes no Github apresentam


pelo menos 1 build com status de sucesso na API do Travis CI 2 . Nós utilizamos o atributo
full_name presente na resposta da API do Github como chave para busca dos projetos.
Esse atributo representa a união do nome do criador do projeto com o nome escolhido
para o projeto. Escolhemos essa abordagem porque acreditamos que os projetos de grande
importância tendem a manter o mesmo nome de criador e do produto já que isso agrega
identidade. Ao terminar o passo 2, nós tivemos como resultado 611 projetos.

O passo 3 consistiu em utilizar os projetos resultante do passo anterior e buscar se


estes estão presentes na API do Coveralls 3 usando a mesma chave do passo 2. Este passo
resultou em apenas 137 projetos. Por fim, o passo 4 usou o resultado da etapa anterior
e buscou identificar quais os projetos apresentam pelo menos 12 versões com intervalos
mínimos de 30 dias entre si e que durante esse mesmo tempo projeto também esteja
utilizando o Travis CI. Ao fim dessa etapa, resultaram 92 projetos.

3.3 Procedimento do Estudo

Esta seção detalha todos os passos realizados durante o estudo, desde a definição do
conjunto de dados, o tratamento realizado nos dados e os algoritmos utilizados para se
1
https://api.github.com/
2
https://api.travis-ci.org
3
https://coveralls.io/
33

obter os resultados. Este trabalho foi conduzido como um estudo empírico, por meio da
obtenção de dados quantitativos em projetos relevantes de código aberto.

Esta seção é organizada nas seguintes subseções: A subseção 3.3.1 apresenta o pro-
cesso utilizado na coleta de dados. A seção 3.3.2 descreve os procedimentos utilizados para
adequar os dados a forma desejada. Em seguida, a subseção 3.3.3 apresenta quais algo-
ritmos, métodos e classificações foram utilizados para responder as questões de pesquisas
propostas.

Uma visão geral dos passos utilizados na análise das questões de pesquisas e denotando
quais foram os artefatos de entrada e os nomes dos algoritmos utilizados são mostrados,
respectivamente, nas figuras 7 e 8

Figura 7: Procedimentos realizados para QP1

Nos dois procedimentos realizados foram utilizados o mesmo processo, a mudança em


si está no conjunto de dados iniciais utilizados. Para responder a primeira questão de
pesquisa são utilizados uma extensão do dataset do trabalho de (NERY, 2020). O dataset
de projetos CI representa o datasetCI que tem 30 projetos que adotaram integração
contínua e o dataset de projetos NOCI representa o datasetN OCI que tem 30 projetos
que não adotaram integração contínua no período analisado do estudo. Para a resolução
da segunda questão de pesquisa foi extraído o dataset de projetos CI POSCI dos projetos
CI, chamado de datasetP OSCI, em que foram usados apenas os dados de cobertura dos
30 projetos após a adoção de CI, enquanto que o de projeto Coveralls (datasetCoveralls)
representa os valores de coberturas tirados do Coveralls. Detalhes de como foram obtidos
34

Figura 8: Procedimentos realizados para QP2

cada um dos datasets pode ser visto na seção 3.2.

No primeiro momento realizamos uma análise interna para entender o comportamento


dos membros de cada um dos grupos, buscando verificar tendência nos valores de cobertura
ao longo do período analisado. Posterior a essa fase, vem a análise externa, no qual se
realiza uma comparação entre as tendências encontradas nas bases de dados. Nosso intuito
é confrontar os dados para encontrar correlações entre a adoção de CI com a cobertura de
código e entender como a cobertura se comporta em um determinado intervalo de tempo.

3.3.1 Coleta dos dados

O objetivo do presente trabalho é analisar o impacto da adoção de CI na proporção e


cobertura de teste, portanto, é imperativo a coletar dados de teste antes e depois da adoção
de CI para projetos CI. O presente trabalho considera momento em que um projeto de CI
adota a CI como o momento em que o primeiro build no Travis-CI foi gerado, como foi
exposto na seção passada. Contudo, Zhao et. al. (ZHAO et al., 2017) relata que o período
de 30 dias em torno do evento de adoção do CI é um período período instável e que
pode conter dados ruidosos. Portanto, esse trabalho optou por seguir essa recomendação
e ignora os dados coletados nesse intervalo de tempo. A Figura 9 mostra como coletamos
as versões de nossos projetos de CI. Cada seta vermelha indica um checkout do commit
mais próximo a data em questão. Coletamos os dados históricos de 12 meses antes da
adoção da CI e 12 meses após a adoção da CI para cada um de nossos projetos no dataset
35

CI.

Em relação aos nossos projetos NOCI, também precisamos estabelecer um momento


para dividir sua história em dois conjuntos de dados. A presença desses dois conjuntos de
dados é importante para validar as observações que obtemos quando comparamos os dados
antes e depois do uso de CI nos projetos. Se uma tendência de evolução na cobertura de
teste é detectada ao se comparar os diferentes períodos de tempo em ambos os projetos de
CI e NOCI, então não é razoável considerar a adoção de CI como o precursor da tendência
observada.

Figura 9: Visão geral do processo de seleção dos checkouts

Dessa forma, se faz necessário a adoção de um critério que permita dividir o histórico
de dados dos projetos NOCI. O presente trabalho se baseou na proposta apresentada por
(NERY; COSTA; KULESZA, 2019). Os autores optaram por selecionar um ponto no tempo
que é proporcional à vida útil de um projeto. Primeiro, foram selecionados aleatoriamente
10 projetos do conjunto de dados de projetos de CI. Em seguida, calculamos o número
de meses antes da adoção do CI. Identificamos a proporção de tempo (em termos de
porcentagem) que os 10 projetos levaram para adotar a CI em relação ao tempo de
vida dos projetos. Finalmente, calculamos a mediana das proporções. Verificamos que, na
mediana, os projetos amostrados adotaram CI em 27,36% de sua vida. Posteriormente,
clonamos os repositórios de todos os projetos de CI e NOCI. Realizamos uma verificação
de 24 versões para todos os projetos (ou seja, ambos os projetos CI e NOCI) seguindo
o processo descrito na Figura 9. Para projetos de CI, o evento divisor é a adoção de CI,
obviamente, enquanto para projetos NOCI, o evento divisor é 27% do seu tempo de vida
até o dia da coleta.

Em relação aos projetos advindos do Coveralls, nós usamos a ideia de (NERY, 2020)
para obter a quantidade e o intervalo de tempo entre os commits que representam as ver-
sões de cobertura a serem analisadas. Entretanto tomamos algumas decisões diferentes,
como a (i) obrigatoriedade que os projetos precisam utilizar o Travis CI durante todo
o período analisado, (ii) foi contabilizado apenas projetos que obtiveram pelo menos 12
mudanças após a data de adoção de CI (primeiro build no Travis) somados com os 15
dias de intervalo de transição. Cada versão tem que ter no mínimo 30 dias de diferença
entre si e (iii) uso de mais projetos do que apenas apenas 30. A primeira mudança foi
36

motivada pela preocupação de não contabilizar dados de projetos que pararam de utilizar
a integração contínua durante o período analisado. A segunda mudança foi realizada para
não contabilizar um mesmo commit várias vezes, dessa forma garantimos que o valor de
cobertura da próxima versão não é uma repetição da versão antiga mais próxima. A ter-
ceira mudança foi motivada pela necessidade de verificar se a maximização da quantidade
de projetos CI analisados do Coveralls vai fazer com que os dados mudem de forma ra-
dical. Caso exista uma grande diferença entre os resultados coletados pela ferramentas e
os advindos do Coveralls, não seria possível usar o Coveralls para aumentar os dados do
datasetP OSCI.

3.3.2 Tratamento dos dados

Nesta seção iremos denotar os procedimentos necessários utilizados de modelagem dos


dados. Estes procedimentos servem para manter a integridade das análise das informações
e evitar que se faça comparações indevidas com números que não representem a mesma
grandeza.

3.3.2.1 A Coleta de Cobertura

Esse trabalho utilizou uma combinação de de bibliotecas de cobertura de código bem


estabelecidas para analisar a cobertura de uma variedade de linguagens de programação.
Especificamente, esse trabalhou utilizou:

• Openclover4 para Java

• Istanbul5 para Javascript

• Coverage.py6 para Python

• SimpleCov7 para Ruby

• PHPUnit8 para PHP

Na busca em garantir uma replicação dos resultados de (NERY, 2020), nós utilizamos
as mesmas ferramentas que ele utilizou para as linguagens Java (Openclover), JavaScript
4
https://openclover.org/
5
https://istanbul.js.org/
6
https://coverage.readthedocs.io/en/coverage-5.5/
7
https://github.com/simplecov-ruby/simplecov
8
https://phpunit.de/
37

(Istanbul) e Python (Coverage.py). Para obter o valor de cobertura em Ruby, nós uti-
lizamos a SimpleCov, uma ferramenta bastante popular que está presente em mais de
100.000 repositórios Ruby no Github 9 . Nos projetos em PHP, nós utilizamos o PHPUnit
por também se tratar de um projeto maplamente utilizado pela comunidade. Ele está
presente em mais de 1.400.000 projetos 10
.

A fim de endereçar o desafio estrutural de unificar os resultados de cada ferramenta,


todas as bibliotecas de cobertura foram configuradas para produzir saídas nos formatos
cobertura ou clover. O primeiro formato é bem conhecido e utilizado por diversas fer-
ramentas e apresenta uma estrutura bem padronizada entre as ferramentas. Contudo, o
formato clover é implementado de forma diferente entre as ferramentas que o produzem.
Portanto, se fez necessário desenvolver uma solução para ler os diferentes tipos do for-
mato clover e produzir uma a saída unificada. O apêndice E apresenta o algoritmo para
extração da cobertura. Basicamente, selecionamos todas as linhas do projeto em questão
e computamos a cobertura como a: P C = EL/V L, em que EL indica o número de linhas
executadas e V L indica o número de linhas válidas (ignorando comentários e linhas em
branco).

3.3.3 Obtenção dos resultados

Utilizou-se a linguagem de programação R (R, 2020) para executar as funções neces-


sárias para obter os dados necessários para este estudo. A linguagem foi escolhida por
apresentar como principal proposta a computação estatística e gráficos, além de apre-
sentar as bibliotecas necessárias para os algoritmos utilizados neste estudo. O algoritmo
completo em R utilizado nesse estudo está disponível no apêndice F.

3.3.3.1 Gap statistic

A proposta da etapa de análise dos dados deste estudo é agrupar os projetos em


subgrupos de acordo com um critério de similaridade dos valores das coberturas de testes
obtidos nas amostras. Entretanto, primeiramente é necessário definir a quantidade ideal
de grupos necessários que os projetos podem se dividir. Para definir esse número ideal foi
utilizado o abordagem Gap Statistic (TIBSHIRANI; WALTHER; HASTIE, 2001).

A ideia por trás dessa abordagem é encontrar uma maneira de comparar a compacta-
ção de agrupamentos, clusters, de uma distribuição de referência nula dos dados, ou seja,
9
https://github.com/simplecov-ruby/simplecov
10
https://github.com/sebastianbergmann/phpunit/
38

uma distribuição sem agrupamento óbvio. Sua estimativa para o número ideal de agrupa-
mentos (clusters) é o valor para o qual a a estrutura de agrupamento está mais longe da
distribuição de referência. Em linhas gerais, o algoritmo realiza os seguintes passos:

• Agrupe os dados observados variando o número de agrupamentos de k = 1, ..., kmax ,


e calcule o total correspondente dentro da variação intra-agrupamento Wk .

• Gere conjuntos de dados de referência, denominado B com uma distribuição uni-


forme aleatória. Agrupe cada um desses conjuntos de dados de referência com nú-
mero variável de clusters k = 1, ..., k + max e calcule o total correspondente dentro
da variação intra-cluster Wkb .

• Calcule a distância estatística Gap Statistic estimada como o desvio do valor Wk


observado de seu valor Wwb esperado sob a hipótese nula:
B
1 X ∗
GAP (k) = log(Wkb ) − log(Wk )
B b=1

Calcule também o desvio padrão das estatísticas.

• Escolha o número de clusters como o menor valor de k, de forma que o Gap Statistic
esteja dentro de uma unidade de desvio padrão k + 1, ou seja: GAP (k) ≥ GAP (k +
1) − sk+1 .

A abordagem Gap Statistic é computada pela função clusGap do pacote cluster (MA-
ECHLER, 2021) da linguagem de programação R. A equação 3.1 mostra a função utilizada
para computar a Gap Statistic. Os parâmetros de entradas que não estão na equação são
opcionais e estes foram utilizados com os respectivos valores padrões.

clusGap(dataset,
F U N = kmeans,
nstart = 25,
(3.1)
iter.max = 50,
K.max = dataset.nrow − 1,
B = 599)

O parâmetro dataset representa o conjunto de dados em forma de matriz bidimensio-


nal, em que cada coluna representa uma variável e cada linha uma observação. O segundo
39

parâmetro é o F U N que define a função de clusterização, a utilizada nesse estudo foi a do


algoritmo kmeans (WONG; HARTIGAN, 1979) (TEAM; CONTRIBUTORS, 2020). O terceiro
parâmetro é o nstart que define a quantidade de configurações iniciais do algoritmo do
kmeans, sendo que este utiliza a melhor dentre essas. Esta abordagem é frequentemente
recomendada (GALILI, 2013) (TEAM; CONTRIBUTORS, 2020) e nstart = 25 foi utilizado
por (NERY; COSTA; KULESZA, 2019). No atributo iter.max denotamos a quantidade de
iterações máximas até haver convergência. Nós escolhemos iter.max = 50 por meio de
experimentos com os dados. O parâmetro de K.max representa a quantidade máxima
de clusters que o algoritmo considera na procura do melhor número. Por definição, te-
mos que 1 < K.max < dataset.nrow, que dataset.nrow é um atributo que representa a
quantidade de observações existentes no dataset. Por causa da sua definição e no intuito
de buscar o valor de ótimo global no número de clusters, nós utilizamos o valor máximo
permitido (dataset.nrow − 1). O último parâmetro B representa o valor de número de
amostras Monte Carlo ("bootstrap"). O valor de B = 599 é o recomendado para uso
geral (WILCOX, 2010).

3.3.3.2 Dynamic Time Warping

Devido a natureza dos dados de serem amostras em intervalos mínimos de tempo,


esses valores podem ser interpretados como séries temporais, tornando com que os algo-
ritmos de comparação que utilizem séries temporais sejam os mais adequados a serem
utilizados neste estudo. Vez que, a tradicional distância Euclidiana é capaz de identificar
a distância entre duas séries temporais de mesmo tamanho, porém, não é capaz de lidar
com deslocamento no tempo ou velocidade entre as séries, por exemplo. Portanto, para
identificar a tendência dominante da evolução da cobertura de testes para os dados deste
estudo foi utilizado o algoritmo Dynamic Time Warping DTW . O algoritmo DTW é
capaz de medir a similaridade entre séries temporais de diferentes tamanhos mesmo que
estejam deslocadas no tempo. A Figura 10 ilustra o contraste da análise entre os dois
métodos. As duas séries temporais são semelhantes, porém apenas o DTW é capaz de
detectar essa semelhança. Isso ocorre devido aos diferentes tamanhos e ao deslocamento
no tempo.

Originalmente, o DTW foi usado no reconhecimento automático de fala, gestos, ca-


ligrafia, assinaturas digitais e outros. Em áreas como mineração de dados e recuperação
de informações, o algoritmo DTW tem sido aplicado por ser extremamente eficiente na
minimização dos efeitos decorrentes de distorções temporais ou de velocidade.
40

Figura 10: Diferenças entre os métodos Distância Euclidiana e DTW (MÜLLER, 2007)

Resumidamente, o algoritmo de DTW alinha duas séries temporais minimizando a


distância entre elas (BERNDT; CLIFFORD, 1994) (MÜLLER, 2007). Intuitivamente, o algo-
ritmo é uma forma eficiente de mensuração de similaridades baseado em transformações
não lineares que minimizam os efeitos de distorções das séries cronológicas para detectar
com precisão formas similares com diferentes fases.

A definição formal desta técnica é a seguinte: Suponha que investiguemos duas séries
temporais: A = a1 , a2 , ..., an , e B = b1 , b2 , ..., bm , com comprimentos n e m, respectiva-
mente. Para alinhar essas sequências, construímos uma matriz nxm onde elemento (i, j)
da matriz contém a distância d(ai , bj ) entre os pontos ai e bj . Neste contexto, a distân-
cia euclidiana é normalmente usada. Cada elemento da matriz (i, j) agora corresponde a
um alinhamento entre os pontos ai e bj , e um caminho de alinhamento W , formado por
conjunto contíguo de elementos de matriz, define um mapeamento entre as sequências A
e B. Formalmente, W = w1, w2, ..., wk com wk = (i, j)k e max(m, n) ≤ k < m + n − 1.
O objetivo do algoritmo é encontrar o caminho W ideal, ou seja, aquele que minimiza o
custo de alinhamento DT W (A, B) entre A e B:
v
u K
1u X
DT W (A, B) = min( t wk )
K k=1

A abordagem do DTW é computada pela função tscluster do pacote dtwclust (SARDA,


2017) da linguagem de programação R. A equação 3.2 mostra a função utilizada para
computar a Gap Statistic utilizando o algoritmo DTW como forma de medir a distância.
41

Os parâmetros de entradas que não estão na equação são opcionais e estes foram utilizados
com os respectivos valores padrões.

tsclust(dataset,
type = f uzzy,
seed = 123, (3.2)
k = clusters,
distance = dtw)

O parâmetro dataset representa o conjunto de dados em forma de matriz bidimensio-


nal, em que cada coluna representa uma variável e cada linha uma observação. O segundo
parâmetro é o type que define o tipo de método de agrupamento a ser utilizado, usamos
o tipo fuzzy por ser um tipo de agrupamento já utilizado em outras pesquisas e também
porque este foi o utilizado por (NERY, 2020). O terceiro parâmetro é o seed que define a
semente para definição da sequência pseudo-aleatória para reprodutibilidade, nós escolhe-
mos a semente 123 para todos os algoritmos. O quarto parâmetro é o k que determina a
quantidade máxima de grupos que os projetos vão se dividir, o valor dele é determinado
pelo uso do dataset aplicado na função 3.1 de clusGap. O último parâmetro distance que
representa a função de cálculo da distância utilizada. Nós escolhemos utilizar a função
padrão dtw por ser a implementação mais simples e por ter sido a utilizada por (NERY,
2020).

3.3.3.3 Trend categories

Ao se agrupar dados tende-se naturalmente a encontrar comportamentos ou padrões


que representem todo o grupo. Esse tipo de análise é sucinta e ajuda a melhorar o enten-
dimento de um grande conjunto de dados. Nessa linha de entendimento, nós utilizamos a
classificação definida por (NERY; COSTA; KULESZA, 2019) para se analisar tendências de
um grupo. (NERY; COSTA; KULESZA, 2019) definiram três categorias:

• Raising: Consiste nos grupos dos centroides que representam um crescimento con-
tínuo no analisado período de tempo.

• Decreasing: Consiste em grupos dos quais os centroides representam uma diminuição


contínua no período de tempo analisado
42

• Maintaining: Grupos dos quais os centroides representam uma manutenção ou cres-


cimento/decrescimento insignificante no período de tempo analisado.

Em acréscimo a sua classificação, nós estabelecemos um intervalo de significância


para os valores de cada categoria. Isso foi feito para diminuir possíveis dúvidas de qual
classificação o grupo pertence. A classificação de Raising vai para os grupos em que o
centroide tenha uma tendência de crescimento maior que 0.2, a de Decreasing com cen-
troides com tendência de queda maior que 0.2. Por último, a classificação de Maintaining
que vai para os centroides que tenham tido manutenção dos seus respectivos valores ou
crescimento/decrescimento de cobertura que cheguem no máximo a 0.2.

3.3.3.4 Obtenção dos dados da RQ1

Esta questão de pesquisa busca identificar a variação da cobertura de testes em pro-


jetos CI e NOCI durante um intervalo de tempo. Para melhor analisar os resultados, os
projetos foram divididos no (1) grupo CI (datasetCI ) no qual estão os projetos que adota-
ram CI em algum momento do seu ciclo de vida e no (2) grupo NOCI (datasetNOCI ), que
engloba os projetos em que não se identificou que houve a adoção de integração continua
em algum momento do seu ciclo de vida. Realizamos uma análise comparativa local para
cada grupo, que consiste em comparar os valores obtidos entre projetos de um mesmo
agrupamento e uma análise comparativa entre grupos, no qual se confronta os resultados
obtidos de cada grupo entre si. Para explicação mais detalhada dos tratamentos utilizados
nos dados deve-se olhar a seção 3.3.2.

Os dois datasets apresentam 30 projetos CI e de 30 projetos NOCI. Estes são dois


dos quatros datasets definidos como resultado do passo de tratamento dos dados da seção
3.2. Primeiramente foi utilizado o algoritmo 1 que apresenta um pseudo-código da função
que calcula o melhor número de clusters a partir de valores de um dataset. Ele utiliza a
função definida na equação 3.1.
43

Algoritmo 1 Obter melhor número de clusters de um dataset


Entrada:
dataset : Matriz bidimensional com as observações
seed : Inteiro com a semente para utilizar em sequências pseudo-aleatórias
Saída:
num_clusters : Inteiro com o melhor número de clusters
1: função get_clusters_number(dataset, seed) → Inteiro
2: set.seed(seed) . Garantir reprodutibilidade
3: only_dataset_numbers ← dataset[, 2 : dataset.ncol]
4: gap_stat ← clusGap(only_dataset_numbers, kmeans, 25, dataset.nrow−1, 599)
5: num_clusters ← maxSE(gap_stat$T ab[, “gap”], gap_stat$T ab[, “SE.sim”])
6: return num_clusters
7: fim função

As entradas do algoritmos são o dataset com os valores a serem computados e o valor


de seed com o valor de semente para sequências pseudo-aleatórias. A fim de simplificação,
adicionamos dois atributos a variável dataset: dataset.nrow e dataset.ncol. Eles signifi-
cam, respectivamente, o número de variáveis (colunas) e o número de observações (linhas).
Como saída o algoritmo retorna um inteiro com o melhor número de clusters.

Na linha 2 está a instrução de definição da semente para que as funções que depende de
geração de números pseudo-aleatórios sempre retornem os mesmo resultados. Fazem uso
desse mecanismo de geração o algoritmo de kmeans utilizado na função clusGap. A linha
3 descreve a instrução para realizar uma cópia do dataset que não tenha a coluna com os
nomes do projetos, para que sejam utilizados apenas os valores numéricos. A função da
linha 4 é a função para computar o algoritmo de Gap Statistic descrita na seção 3.3.3.1.
A linha 5 descreve a função maxSE que também faz parte do pacote de cluster e serve
para determinar qual dos números de clusters analisados apresenta maior valor e deve
ser escolhido como o mais adequado. Na linha 6 é a instrução de retorno do número de
clusters mais adequado.

Obtido o número ideal de clusters, o próximo passo do estudo foi computar o algoritmo
de DTW descrito na seção 3.3.3.2 para cada um dos datasets. O algoritmo 2 mostra
um pseudo-código com as instruções utilizadas para obter a imagem com os grupos das
observações (projetos).
44

Algoritmo 2 Algoritmo de agrupamento DTW


Entrada:
dataset : Matriz bidimensional com as observações
seed : Inteiro com a semente para utilizar em sequências pseudo-aleatórias
num_clusters : Inteiro com o melhor número de clusters
Saída:
groups_img : Imagem com os grupos das observações
1: função get_groups(dataset, seed, num_clusters) → Image
2: only_dataset_numbers ← dataset[, 2 : dataset.ncol]
3: dtw ← tsclust(only_dataset_numbers, “f uzzy”, seed, clusters, “dtw”)
4: groups_img ← plot(dtw)
5: return gropus_img
6: fim função

Como entrada o algoritmo tem o dataset com os dados com os valores das observações,
a seed com a semente para a sequência pseudo-aleatória e num_clusters com o número
de clusters nos quais os projetos estarão agrupados.

Na linha 3 está a instrução para realizar uma cópia do dataset que não tenha a coluna
com os nomes do projetos, para que sejam utilizados apenas os valores numéricos A linha
4 denota a função que computa a equação 3.2 que computa o algoritmo DTW descrito
na seção 3.3.3.2. Na linha 4, tem o armazenamento do gráfico com os agrupamentos dos
projetos presentes na variável dtw. Por último, tem o retorno da imagem gravada na
variável groups_img.

3.3.3.5 Obtenção dos dados da RQ2

Nesta questão de pesquisa tentamos verificar como a cobertura de projetos que ado-
taram integração contínua se comportam após a respectiva data de adoção. Para isso,
definimos dois conjuntos de dados: (I) Projetos CI do dataset de (NERY, 2020) que apre-
senta apenas as versões coletadas após a data de adoção de CI, chamamos esse conjunto
de datasetP OSCI e (II) projetos que adotaram CI e que os seus valores de coberturas
foram divulgados no Coveralls, chamamos esse conjunto de dados de datasetCoveralls.
Nós realizamos uma análise comparativa local para cada grupo, que consiste em comparar
os valores obtidos entre projetos de um mesmo agrupamento e uma análise comparativa
entre grupos, no qual se confronta os resultados obtidos de cada grupo entre si.
45

O datasetP OSCI apresentam 30 projetos CI enquanto que o datasetCoveralls apre-


senta 92 projetos. Estes são dois dos quatros datasets definidos como resultado do passo
de tratamento dos dados da seção 3.2. Diferentemente das bases de dados utilizadas na
QP1, os datasets da QP2 apresentam apenas 12 versões distintas de cobertura analisadas
por projeto (Na QP1 foram 24 versões). Esse fato ocorreu pela necessidade de se utilizar
apenas as versões após a adoção de CI.

Os procedimentos e algoritmos utilizados foram os mesmo da QP1, primeiramente foi


utilizado o algoritmo 1 que apresenta um pseudo-código da função que calcula o melhor
número de clusters a partir de valores de um dataset. Ele utiliza a função definida na
equação 3.1. O próximo passo do estudo foi computar o algoritmo de DTW descrito na
seção 3.3.3.2 para cada um dos datasets.

3.4 Considerações

Este capítulo buscou explicar a metodologia utilizada neste trabalho e explicar um


pouco sobre as bases e algoritmos utilizadas para análise. Pelo fato de se utilizar duas
bases de dados distintas foi necessário ter 2 processos de obtenção de dados, um advindo
do trabalho de (NERY, 2020) e outra base advinda de uma extração de dados da API do
Coveralls. Tentamos adaptar e deixar menos abstrato o processo de escolha dos projetos
a serem analisados, além de utilizar de algumas condições adicionais, como a de garantia
do uso de CI durante o período de coleta, para garantir que não houve influência de dados
de coberturas de períodos sem CI na base de dados de projetos CI. Outra preocupação
foi uma possível repetição de uma mesma versão nos dados. Isso poderia perpetuar uma
ideia de que o projetos gerou novas versões sendo que na prática ele não gerou uma nova
versão, houve apenas uma repetição da antiga versão já existente.
46

4 Resultados

Este capítulo apresenta e discute os resultados obtidos do nosso estudo. Ele é organi-
zado de acordo com as questões de pesquisa propostas. Ao final da apresentação de cada
questão de pesquisa, nós apresentamos discussões e implicações relacionadas as respostas.

4.1 QP1 - Quais são as tendências do comportamento


da cobertura de testes de projetos CI e NOCI?

Esta seção apresenta os resultados do procedimento definido na seção 3.3.3.4. Esta


questão de pesquisa buscou identificar tendências de comportamento de cobertura de
testes em projetos CI e NOCI. Para responder essa pergunta, foram utilizados os datasets
CI e NOCI resultantes da etapa de tratamento dos dados da seção 3.3.2. Inicialmente foi
realizada uma análise comparativa local de padrões entre cada grupo, que consiste em
comparar os valores obtidos entre projetos de um mesmo agrupamento e, em seguida, foi
feita uma análise comparativa no qual se confronta os resultados obtidos para cada grupo.

Aplicando dataset = datasetCI e seed = 123 no algoritmo 1 obtemos como resul-


tado que a melhor quantidade de grupos usando o Gap Statistic é 3. A Figura 11 mos-
tra a imagem gerada usando o algoritmo 2 de agrupamento DTW tendo como entrada:
dataset = datasetCI, seed = 123 e num_clusters = 3 e a tabela 1 mostra a quantidade
de observações em cada um dos grupos e sua respectiva classificação de Trend.

Tabela 1: Grupos do datasetCI


Grupo Quantidade Trend
Grupo 1 7 Maintaining
Grupo 2 13 Maintaining
Grupo 3 10 Raising
Total 30

Foi observado que houve uma pequena quantidade de grupos (3 grupos) retornadas
47

Figura 11: Imagem com os projetos em seus respectivos grupos

pelo uso do algoritmo 1, em relação ao intervalo possível de grupos que vão de 2 à 29. Essa
baixa quantidade de grupos evidencia que as observações apresentam comportamentos
mais parecidos entre si. Os centroides dos grupos (linhas tracejadas nos gráficos) ilustram
a forma como as observações se comportam de maneira geral e, desse modo, servem para
analisar a tendência do grupo. Os grupos 1 e 2 foram classificados como de tendência
Maintaining (manutenção da cobertura) e o grupo 3 como de tendência Raising (aumento
da cobertura).

Os grupos 1 e 2 apresentaram a mesma tendência, mas com valores bem distintos de


cobertura. O grupo 1 tem valores próximos de 0.25 (25%) de cobertura, enquanto que o
grupo 2 tem valores próximos de 0.85 (85%). O grupo 3 se diferenciou dos demais por
apresentar uma tendência de raising, apresentando crescimento acima de 0.25 (25%) no seu
centroide. Em números absolutos, houve 7 (23,3%) observações no grupo 1, 13 (43,3%)
observações no grupo 2 e 10 (33,3%) no grupo 3. Esses valores evidenciam que quase
48

metade dos projetos (13/30) tem uma cobertura com valor alto e tendendo a estabilizar
seus valores durante o tempo, quase todos os valores de cobertura do grupo 2 foram acima
de 0.5.

Aplicando dataset = datasetN OCI e seed = 123 com o algoritmo 1 obtemos como
resultado que a melhor quantidade de grupos usando o Gap Statistic é 25. A Figura 12
mostra a imagem gerada usando o algoritmo 2 de agrupamento DTW tendo como entrada:
dataset = datasetN OCI, seed = 123 e num_clusters = 25 e a tabela 2 mostra a quan-
tidade de observações em cada um dos grupos estipulados e a sua respectiva classificação
de tendência.

Figura 12: Imagem com os projetos em seus respectivos grupos

Houve um total de 25 grupos retornados pelo algoritmo 1 para o datasetN OCI. Este
é um valor bem próximo do máximo possível que é 29. A alta quantidade de grupos
(25 dos 29 possíveis) nos diz que os projetos apresentam valores de coberturas bastante
distintos entre si. Os centroides obtidos se comportam, em sua maioria, de forma análoga
49

Tabela 2: Grupos do datasetN OCI


Grupo Quantidade Trend
Grupo 1 1 Raising
Grupo 2 1 Maintaining
Grupo 3 1 Maintaining
Grupo 4 1 Maintaining
Grupo 5 1 Maintaining
Grupo 6 3 Maintaining
Grupo 7 1 Maintaining
Grupo 8 1 Decreasing
Grupo 9 1 Maintaining
Grupo 10 2 Maintaining
Grupo 11 1 Raising
Grupo 12 1 Decreasing
Grupo 13 1 Maintaining
Grupo 14 1 Maintaining
Grupo 15 2 Maintaining
Grupo 16 1 Maintaining
Grupo 17 1 Maintaining
Grupo 18 1 Maintaining
Grupo 19 1 Raising
Grupo 20 2 Maintaining
Grupo 21 1 Maintaining
Grupo 22 1 Maintaining
Grupo 23 1 Maintaining
Grupo 24 1 Maintaining
Grupo 25 1 Maintaining
Total 30

aos projetos pertencentes aos grupos. Fato esse ocorre porque existe apenas uma variação
entre 1 e 3 na quantidade de membros de cada grupo. Nós observamos que apenas três
grupos (1, 11 e 19) tiveram tendência de Raising (aumento da cobertura), apenas dois
grupos (8 e 12) tiveram tendência de Decreasing (redução da cobertura) e, por fim, um
total de vinte grupos (grupos 2, 3, 4, 5, 6, 7, 9, 10, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23,
24 e 25) tiveram a classificação de Maintaning (manutenção da cobertura).

Os grupos de Raising representam 3 projetos (10% do total) e apresentam crescimento,


mas os valores não ultrapassam nem 0.5 (50%) do valor de cobertura. Já os grupos de
Decreasing representam 2 projetos (6,6%) apresentam uma queda brusca de valores de
cobertura. No grupo 12, a cobertura chegou a cair mais de 0.5 (50%). A tendência que
mais obteve grupos classificados foi a de Maintaning que totalizou 25 (83,3%) projetos.
Dentre os projetos com a tendência de Maintaning, 6 projetos (grupos 3, 15, 17, 21 e 23)
50

apresentaram o centroide com coberturas iguais ou abaixo de 0.25 (25%). Já 9 projetos


dos grupos 2, 4, 10, 13, 14, 22, 24 e 25 apresentaram coberturas maiores que 0.25 (25%)
e menores ou iguais a 0.5 (50%). 3 projetos do grupo 6 apresentam valores de cobertura
acima de de 0.5 (50%) e menor ou igual a 0.75 (75%). Por fim, apenas 7 projetos dos
grupos 5, 7, 9, 16, 18 e 20 apresentaram a cobertura igual ou maior que 0.75 (75%).

Conseguimos identificar que existe maior tendência de estabilidade com cobertura


menor que 75% com 18 projetos do que com valores de cobertura alta (acima de 0.75%)
com 7 projetos. Esse fenômeno implica que os projetos do datasetN OCI mantém uma
cobertura estável mas esta tende a ter valores abaixos de 75%.

Comparando os resultados obtidos entre os projetos CI e projetos NOCI podemos


perceber que os projetos CI apresentam mais homogeneidade entre si do que os projetos
NOCI. Esse fator é evidenciado pela quantidade de grupos denotados pelo algoritmo de
Gap Statistic. Existe uma diferença bastante acentuada na quantidade de clusters de
projetos CI e NOCI que foram gerados, sendo 3 grupos para CI e 25 grupos para NOCI.

Nós também observamos que tanto projetos CI como NOCI tendem a manter o valor
de cobertura com o passar do tempo, com a distinção que os projetos CI geralmente
apresentam valores de cobertura maiores do que 75% do que os projetos NOCI. Esse
fato é embasado pela alta quantidade de projetos pertencentes a tendência Maintaining
presente nos projetos CI e NOCI, representando 66,6% (20 projetos) do datasetCI e 83%
(25 projetos) do datasetN OCI. Comparando os valores de cada grupo que foi classificado
como Maintaining observamos que o centroide do grupo 2 dos projetos CI com 13 projetos
e os centroides dos grupos 5, 7, 9, 16, 18, 20 dos projetos NOCI são as observações que
apresentam valores acima de 0.75 (75%). Desse modo, a proporção entre projetos da classe
Maintaining que apresentam o valor de cobertura alto e o total de projetos desta classe é
13/20 (65%) para o datasetCI e (28%) para o datasetN OCI. Essa distinção de valores
nas proporções permite observar que existe uma diferença significante (acima de 25%) de
valores entre a tendência de Maintaining entre as bases de dados.

Outra constatação é que projetos CI tem uma tendência de ter aumento no valor de
cobertura com o passar do tempo em relação a projetos NOCI. Essa afirmação é embasada
na tendência de Raising encontrada para muitos dos projetos. Enquanto que no datasetCI
observamos o grupo 1 com 10 projetos na classe Raising, no datasetN OCI vimos que para
a mesma classe obtemos os grupos 1, 11 e 19 com apenas 3 projetos.

Considerando a adoção de CI e a cobertura de testes ao longo do período analisado,


nossos resultados mostram uma tendência de aumento ou manutenção da cobertura dos
51

testes para projetos que adotam CI. A seguir apresentamos uma visão geral sobre os
resultados encontrados:

• DatasetCI:

– Na maior parte existe a manutenção de cobertura (20/30 projetos) e esse valor


tende a ser acima de 75% em 13 dos 30 projetos.

– Existe uma possibilidade alta de aumento de cobertura (10/30 projetos).

– Tende a impedir quedas acimas de 20% da cobertura (Não se encontrou projetos


com esse comportamento).

• DatasetN OCI:

– Dificilmente apresenta crescimento de cobertura (3/30 projetos).

– Normalmente se tem manutenção de cobertura (25/30 projetos) e esta é geral-


mente abaixo dos 75% (18/30 projetos).

– Existe uma pequena possibilidade queda de pelo menos 20% cobertura (2/30
projetos).

4.2 QP2 - Existe uma associação entre as taxas de co-


bertura de testes de projetos CI com as de outros
projetos CI advindos do Coveralls?

Esta questão de pesquisa analisa a existência de relação entre as taxas de cobertura de


projetos CI advindos da base de dados de (NERY; COSTA; KULESZA, 2019) e de projetos
CI advindos do Coveralls (COVERALLS, 2021). Nós buscamos comparar os resultados
dos projetos, considerando apenas as medições que ocorreram após a adoção de CI. Isso
ocorreu pelo fato de que nenhum dos projetos extraídos do Coveralls e que utilizam CI, foi
possível coletar valores para a cobertura antes do período de adoção de CI. Diferentemente
da questão de pesquisa 1, foram considerados apenas o intervalo de 12 meses após a adoção
de CI, o que nos dá um conjunto de 12 amostras por projetos.

A abordagem utilizada foi bastante similar ao da proposta da questão de pesquisa


1, com a distinção da quantidade de amostras usadas. No caso dos dados provenientes
do Coveralls é possível obter mais facilmente as amostras através de requisições via API
do Coveralls. Essa mudança na obtenção de observações de coberturas é menos custosa
52

e apresenta menor complexidade de ser realizada, pois não necessita da execução dos
projetos.

Nós utilizamos um subconjunto do datasetCI definido na seção 3.2. Chamamos esse


subconjunto de datasetP osCI que compreende apenas os valores das amostras que são de
datas após a data de integração contínua. Das 24 amostras disponíveis, apenas 12 delas
foram escolhidas. O outro conjunto utilizada para resolução desta questão de pesquisa é
o datasetCoveralls definido na seção 3.2. Aplicamos o algoritmo 1 e 2 nas bases de dados
e realizamos comparações nos aspectos similares e distintos dos resultados obtidos.

Aplicando dataset = datasetP osCI e seed = 123 no algoritmo 1 obtemos como resul-
tado que a melhor quantidade de grupos usando o Gap Statistic é 16. A Figura 13 mostra
a imagem gerada usando o algoritmo 2 tendo como entrada: dataset = datasetP osCI,
seed = 123 e num_clusters = 16 e a tabela 2 mostra a quantidade de observações em
cada um dos grupos estipulados e a sua respectiva classificação de tendência.

Figura 13: Imagem com os projetos em seus respectivos grupos


53

Tabela 3: Grupos do datasetP osCI


Grupo Quantidade Trend
Grupo 1 1 Maintaining
Grupo 2 1 Maintaining
Grupo 3 1 Maintaining
Grupo 4 1 Maintaining
Grupo 5 1 Maintaining
Grupo 6 1 Maintaining
Grupo 7 1 Decreasing
Grupo 8 7 Maintaining
Grupo 9 4 Maintaining
Grupo 10 3 Maintaining
Grupo 11 1 Maintaining
Grupo 12 2 Maintaining
Grupo 13 1 Maintaining
Grupo 14 1 Maintaining
Grupo 15 3 Maintaining
Grupo 16 1 Maintaining
Total 30

Nós observamos que o algoritmo de Gap Statistic resultou em uma quantidade de


grupos alta, com 16 grupos. Isso implica que as observações apresentam valores distintos
entre si. Os centroides obtidos nos grupos tenderam a ter um comportamento bastante
similar, o que acarretou na classificação de tendência Maintaining em quase todos eles,
com exceção do centroide do grupo 7 que o fez ser classificado com Decreasing. A tendência
de Maintaining representa 29 (96,6%) do total de projetos, enquanto que a Decreasing
representa 1 (3,33%) das observações.

Apesar de haver a tendência de Maintaining nos grupos, o que significa que o com-
portamento deles tendem a serem mais parecido, os valores absolutos das coberturas dos
centroides foram distintos. Os centroides do grupos 8, 9, 10 e 12 apresentaram valores
acima de 0.75 (75%), e estes grupos englobam 16 (53,3%) projetos. Apenas os grupos
1, 6 e 15 apresentam valores baixos de cobertura, abaixo de 25%. Eles compreendem 5
projetos (16,6%) do total de 30 projetos analisados desta base de dados. Tais resultados
nos fazem observar que as amostras de cobertura após a adoção de CI tende a manter o
valor de cobertura e esse valor normalmente é alto.

Nós classificamos apenas o grupo 7 como Decreasing, que representa apenas 1 projeto
(3,3% do total) . Não houve nenhum grupo classificado com Raising. Analisando os resul-
tados obtidos, o fato de não ter ocorrido uma tendência de crescimento de cobertura nos
permitiu observar que o uso de CI não melhorou a cobertura dos projetos citados. O que
54

pode ter acontecido é que os projetos já tenham conseguido garantir uma alta cobertura
dos testes na etapa de transição para CI ou mesmo antes de adotar CI.

A cobertura de projetos após a adoção de CI são mais similares entre si quando o


seu valor de cobertura é acima de 75%. Os grupos que apresentam mais observações são
os do grupo 8 (7 projetos) e grupo 9 (4 projetos). Ambos apresentam valores altos de
cobertura bem próxima ou acima de 0.75 (75%). Esses projetos determinam um padrão
que é repetido por outros, então ele pode ser replicado. Se os desenvolvedores buscam
um padrão de cobertura acima de 75% e estabilidade durante o tempo em projetos CI
que seja replicável, esses projetos são os melhores candidatos a apresentar a se buscar as
condições necessárias para isso.

O passo seguinte da resolução desta questão de pesquisa é analisar os dados advindos


do datasetCoveralls. Nós aplicamos o dataset = datasetCoveralls e seed = 123 no
algoritmo 1 e obtemos como resultado que a melhor quantidade de grupos usando o
Gap Statistic é 34. A Figura 14 mostra a imagem gerada usando o algoritmo 2 tendo
como entrada: dataset = datasetCoveralls, seed = 123 e num_clusters = 34. A tabela 4
mostra a quantidade de observações em cada um dos grupos estipulados e a sua respectiva
classificação de tendência. Os grupos 2, 3, 4, 12, 13, 15, 16, 17, 19, 21, 22, 23, 25, 30, 31
e 32 foram ocultados da tabela por não apresentarem nenhuma observação, ou seja, são
grupos vazios.

O algoritmo 1 retornou um número alto (34 grupos) na melhor quantidade de clusters.


Muitos conjuntos distintos nos dizem que os dados apresentam uma grande variação do
valor de cobertura entre si. Nós contabilizamos 16 dos 34 grupos com nenhum projeto
associado, fator que fez com que tivermos apenas 18 grupos a serem analisados e clas-
sificados pela sua tendência. Os grupos 33 foi o único que apresentou o centroide com
tendência de Raising, englobando 2 (2,2%) dos projetos. Os outros grupos foram classi-
ficados como Maintaining, apresentando 90 (97,8%) das observações. Houve uma grande
predominância da classificação de Maintaining na base de dados datasetCoveralls. Não
encontramos nenhum centroide com a tendência de Decreasing. Nós consideramos que os
projetos CI advindos do Coveralls apresentaram estabilidade no valor de cobertura ao
longo do tempo. Os valores de coberturas encontrados foram bastante altos, dados que
os grupos 7, 8, 9, 10, 20, 26, 28, 29 apresentaram cobertura acima de 0.75 (75%). Eles
representam 68 (73,9%) dos 92 projetos.

Outro padrão percebido foi de similaridade entre grupos com coberturas acima de
75%, nós notamos que estes também representam os grupos com mais membros. Estes
55

Figura 14: Imagem com os projetos em seus respectivos grupos do datasetCoveralls

são os grupos 10, 20 e 26, que totalizaram 51 (55,4%) observações. Isso implica que as
condições adotadas por esses projetos no datasetCoveralls para manter esse nível de
cobertura durante o ciclo de desenvolvimento devem ser estudadas de forma a prover
informações uteis para gerentes de projetos que quiserem aplicações que mantenham uma
alta cobertura dos seus testes.

Entendido como se comportam os projetos internamente por meios dos centroides dos
grupos nas bases datasetP osCI e datasetCoveralls, nós buscamos analisar uma possível
relação entre eles. A Tabela 5 denota a comparação de alguns dos principais pontos
alavancados em cada uma das bases de dados utilizadas para resolução desta questão
de pesquisa.

As bases de dados presentes nos projetos apresentaram comportamentos parecidos


em relação a similaridade entre os projetos (quanto mais próximo do valor máximo de
grupo, mais distintos os membros são entre si), tendência geral dos grupos e no valor de
56

Tabela 4: Grupos do datasetCoverallsCI


Grupo Quantidade Trend
Grupo 1 3 Maintaining
Grupo 5 3 Maintaining
Grupo 6 2 Maintaining
Grupo 7 3 Maintaining
Grupo 8 3 Maintaining
Grupo 9 2 Maintaining
Grupo 10 16 Maintaining
Grupo 11 3 Maintaining
Grupo 14 1 Maintaining
Grupo 18 1 Maintaining
Grupo 20 25 Maintaining
Grupo 24 3 Maintaining
Grupo 26 10 Maintaining
Grupo 27 3 Maintaining
Grupo 28 3 Maintaining
Grupo 29 6 Maintaining
Grupo 33 2 Raising
Grupo 34 3 Maintaining
Total 92

Tabela 5: Analise comparativa entre datasetP osCI e datasetCoveralls


Critério datasetP osCI datasetCoveralls
Quantidade de membros 30 92
Quantidade de grupos com membros 25 18
16 grupos de 34 grupos de
Similaridade entre projetos
29 possíveis 91 possíveis
Tendência geral dos grupos Maintaining Maintaining
Cobertura dos grupos mais populosos Alta Alta

cobertura dos grupos que apresentam mais observações. Esses acontecimentos ocorreram
mesmo com uma grande diferença na quantidade de projetos analisados (30 e 92). Outro
critério que teve resultados equivalentes foram os da quantidade de grupos com membros,
com datasetP osCI com 25 grupos e datasetCI com 18, isso visto a disparidade de valores
absolutos das observações.

4.2.1 Discussão dos resultados

Esta seção discute os resultados obtidos nas questões de pesquisas propostas, apresen-
tando as hipóteses que se confirmaram ou não se confirmaram. As respostas das questões
de pesquisas permitiram entender mais sobre o comportamento da cobertura de testes
57

de projetos CI e NOCI, incluindo períodos de adoção da integração contínua no caso da


QP1. Além disso, permitiu comparar os comportamentos de projetos que adotaram CI
mas que são de bases diferentes.

Ao responder a QP1 nós conseguimos identificar que os projetos CI apresentam um


comportamento mais uniforme que os projetos NOCI no que diz respeito a cobertura dos
testes, podendo a integração contínua ter contribuído para este fator. Percebemos a partir
dos nossos resultados que existe uma correlação entre a uniformidade do comportamento
da métrica de cobertura dos projetos com a adoção de CI. Outro fator que identificamos
é que, independente do projeto adotar CI ou não, houve uma tendência geral em manter
a estabilidade da cobertura dos testes. Entretanto, o percentual no qual se encontra a
estabilidade de cobertura da maior parte dos projetos CI são bem mais elevados (acima
de 75%) que o percentual presente nos projetos NOCI (próximos de 50%).

Na QP2 comparamos os valores de duas bases de dados de origem distintas que fo-
ram obtidas em épocas distintas. O dataset de (NERY, 2020) apresentou que houve um
crescimento significante de cobertura em projetos CI, entretanto nós não conseguimos
identificar esse comportamento analisando apenas as coberturas após a a adoção de CI
para a base de dados do Coveralls. Acreditamos que essa diferença se deu porque (NERY,
2020) utilizou como base de comparação os dados de antes e depois de CI e nós utili-
zamos apenas os dados após a adoção de CI. Considerando apenas o datasetP OSCI,
notamos um padrão de estabilidade na cobertura, algo muito parecido com o encontrado
no datasetCoveralls.

As respostas das questões de pesquisas nos ajudaram a entender o comportamento das


bases de dados e motivam a investigar se os acontecimentos encontrados são fenômenos
comuns em projetos que adotam integração contínua. No geral, percebemos que houve
uma diferença das tendências de Raiting entre os projetos, tivemos 10 projetos CI com
essa tendência enquanto que no de projetos que não usam CI temos apenas 3 projetos. Os
projetos advindos do Coveralls mesmo sendo coletados em um momento posterior a coleta
de (NERY, 2020), contínua com alguns comportamentos análogos como a similaridade
interna, tendência geral e comportamento de subgrupos mais populosos. Esse tipo de
acontecimento nos faz pensar que existe a possibilidade que o modo como CI influência
esses aspectos dos projetos tendeu a sofrer poucas variações.
58

4.3 Ameaças a Validade do trabalho

Esta seção discute as ameaças à validade de nosso estudo.

4.3.1 Ameaças de Construção

As ameaças de construção estão vinculadas a possíveis erros provenientes dos procedi-


mentos utilizados na montagem do banco de dados de projetos e na coleta dos resultados.
As amostras foram coletadas utilizando as APIs do GitHub e Travis CI. Buscamos por
projetos populares em diversas linguagens utilizadas pela indústria de software. Qual-
quer eventual erro dessas APIs podem afetar nossos resultados. Contudo, aceitamos os
riscos inerentes a esse procedimento, uma vez que tais APIs são amplamente utilizadas
pela academia em pesquisas similares. Outro ponto de preocupação são as ferramentas
utilizadas para coleta dos dados de cobertura. Os riscos relacionados a esse ponto foram
mitigados através do uso de ferramentas cujo uso é amplamente difundido na academia e
na indústria.

A seleção dos projetos NOCI também apresentam algumas ameaças. A seleção dos
projetos foi realizada por meio da análise de projetos não suportados pelo Travis CI. No
entanto, reconhecemos que os projetos podem usar outras ferramentas para integração
contínua (ex: Jenkins, Circle CI e Gitlab CI).

Finalmente, existe uma ameaça na forma como delimitamos o tempo de vida do


projeto. Consideramos que a data de criação dos projetos coincide com a data da primeira
contribuição (commit) no GitHub, no entanto, podem existir projetos que migraram seu
código fonte de outro sistema de controle de versão. Nesse casos, estamos desconsiderando
o tempo antes da adoção do GitHub. Para mitigar esse problema, foi feita uma análise dos
primeiros commits dos projetos, e concluído que boa parte dos projetos NOCI devem ter
sido criados em momentos muito próximo da primeira contribuição (commit) no Github.

4.3.2 Ameaças internas

As ameaças internas estão relacionadas com a precisão de nossos resultados e com a


forma como coletamos e analisamos as informações a fim de aferir a capacidade da pesquisa
em tirar conclusões a partir dos dados coletados. Mitigamos tais ameaças escolhendo
projetos que foram usados em pesquisas anteriores, e ampliamos o número de amostras
analisadas através da coleta de um amplo conjunto de projetos coletados no Coveralls e
59

no GitHub.

Para garantir que não distorcemos os resultados e permitir um maior escrutínio, dis-
ponibilizamos todos os dados que coletamos nessa pesquisa.

Existe a possibilidade dos projetos advindos do Coveralls não utilizarem o mesmo


cálculo para denotar o porcentagem de cobertura. O valor de cobertura não é coletado
pelo Coveralls, mas apenas obtido pela ferramenta de cobertura utilizada no projeto. Esse
é um risco que nós aceitamos por se tratar de um problema que não foi confirmado e ainda
assim não impactar nos resultados gerais.

Existe a possibilidade, principalmente na QP1, de que as mudanças realizadas para


execução do build possam ter impacto nos resultados de cobertura dos projetos. Para
tentar identificar se houve um impacto pelas mudanças no build necessárias para execução
das aplicações, nós utilizamos a resposta da QP2. Pelo fato de não termos encontrado
distinções gerais nos valores de cobertura, acreditamos que as modificações feitas para
execução da aplicação não obteve impacto significativo nos valores de cobertura. Dessa
maneira, a resolução da QP2 ajudou a validar os resultados obtidos na QP1.

4.3.3 Ameaças Externas

As ameaças externas estão relacionadas a capacidade de generalizar dos resultados


apresentados. Embora nossos resultados não possam ser generalizados, nós selecionamos
um grande e diversificado conjunto de projetos de várias linguagens de programação e de
diferentes domínios que estão entre os mais populares no GitHub e Coveralls.

Nosso conjunto de dados é mais amplo e mais diverso do que os estudos anteriores
encontrados sobre o tema. Por fim, uma vez que todos os projetos analisados nesse estudo
são de código aberto, não podemos fazer nenhuma afirmação sobre como nossos resultados
podem ser generalizados para projetos de software proprietário.
60

5 Trabalhos Relacionados

Este capítulo confronta este trabalho com outras pesquisas e estudos que analisam a
relação entre a integração contínua e cobertura de testes. A seção 5.1 destaca os pontos
principais de trabalhos relacionados de análise da cobertura de projetos que adotaram
integração contínua. A seção 5.2 apresenta uma análise comparativa entre nosso estudo e
os trabalhos relacionados.

5.1 Análise da Evolução da Cobertura em Projetos CI

(MARINESCU; HOSEK; CADAR, 2014) apresentam uma ferramenta e um conjunto de


dados de cobertura de código. Para avaliar a ferramenta, o artigo usa seis sistemas imple-
mentados em C e C++. Diferentemente do nosso trabalho, tais autores focam especifica-
mente na cobertura de patches. No nosso trabalho examinamos a cobertura de commits
em projetos CI de maneira mais ampla, além de usarmos um conjunto de dados signifi-
cativamente maior.

(HILTON; BELL; MARINOV, 2018) realizaram uma avaliação em larga escala da co-
bertura de código em 7816 builds de 47 projetos escritos nas linguagens Java, Python e
Scala. Os autores observaram que as linhas cobertas variam amplamente entre os pro-
jetos, mesmo quando a cobertura geral parece permanecer inalterada. Nos experimentos
conduzidos pelos autores, considerou-se os últimos 250 commits dos projetos como janela
temporal para analisar a evolução da cobertura de código. O trabalho apresentado pelos
citados autores também focam na cobertura de patches assim como ocorre com relatado
pelo trabalho de (MARINESCU; HOSEK; CADAR, 2014), contudo (HILTON; BELL; MARINOV,
2018) apresentam um dataset maior. Entretanto, os 250 últimos commits podem não re-
presentar substancialmente a evolução da cobertura de código ao longo do tempo. O nosso
estudo aborda esse ponto ao investigar a evolução da cobertura de código em uma janela
de tempo de 2 anos. Nesse sentido, o estudo de 2 anos de cobertura de código nos permite
fornecer uma visão geral mais ampla da evolução da cobertura dos testes.
61

(ZHAO et al., 2017) apresentaram um estudo sobre o impacto do Travis CI em projetos


de código aberto. Os autores descobriram que o número de testes por build tende a au-
mentar após a adoção do Travis CI. Complementar ao trabalho desses autores, estudamos
o impacto da adoção de CI nas métricas de cobertura, realizando comparações entre os
períodos de tempo antes e depois da adoção de CI. Através das análises conduzidas na
presente pesquisa, podemos entender melhor o impacto da adoção de CI na evolução das
taxas de cobertura dos projetos.

(NERY; COSTA; KULESZA, 2019) apresentam um estudo empírico sobre a relação entre
a adoção de integração contínua e o evolução do código de teste dos softwares. Os autores
compararam 82 projetos que adotaram CI com 82 outros projetos que nunca usaram CI.
Ao todo, os pesquisadores avaliaram 3936 versões de diferentes projetos a fim de estudar as
tendências no volume e cobertura do código de teste. Os resultados apresentados indicam
que 40.2% dos projetos de CI possuem uma tendência de aumento da taxa de teste-código,
enquanto apenas 17% dos projetos de NOCI têm uma tendência de aumento. O estudo
também reporta evidências de que os projetos de CI melhoraram a cobertura geral de
teste, enquanto os projetos de NOCI não apresentam melhorias nesse aspecto. Contudo, o
estudo sobre cobertura foi realizado com uma quantidade restrita de projetos. Os autores
estudaram as tendências de cobertura em apenas 20 projetos, sendo 10 projetos CI e 10
projetos NOCI. A presente pesquisa completa o trabalho de (NERY; COSTA; KULESZA,
2019) no que tange a análise da tendência de cobertura. Uma vez que analisamos as
tendências de cobertura em projetos CI e NOCI em uma base de dados bem mais ampla
tanto no volume de dados quanto na diversidade de linguagens.

(BERNARDO; COSTA; KULESZA, 2018) investigam empiricamente o impacto da adoção


de CI no tempo de entrega das solicitações de integração de código merged pull requests
(PRs). Os autores analisaram 162.653 PRs de 87 projetos do GitHub, sendo 33 em Ja-
vaScript, 23 em Python, 11 em Java, 10 em Ruby e 10 em PHP, para explorar os fatores
que afetam o tempo de entrega dos PRs. Os autores reportam que em 71.3% dos projetos,
os PRs são integrados mais rapidamente antes da adoção do CI. Além disso, em 54%
(47/87) dos projetos estudados, as solicitações de PR enviadas possuem uma vida útil
mais longa. Os autores apontam que o aumento considerável no número de envios de PR
como principal fator para o aumento no tempo de entrega de PRs. O presente trabalho
difere da pesquisa em questão por analisar outros aspectos relativos a adoção do CI. Por-
tanto, apesar de ambos os trabalhos buscarem evidências empíricas que validem ou não
afirmações comumente relacionadas a adoção de CI e compartilharem um subconjunto de
de dados, atuam investigando aspectos diferentes.
62

5.2 Análise Comparativa

Foram encontrados alguns trabalhos que estudam o tema de integração contínua no


contexto de projetos de código aberto. Entretanto, apenas o trabalho de (NERY, 2020)
analisa a cobertura de testes de projetos que adotaram a prática de CI. Consideramos
que essa é uma área importante que merece mais estudos investigativos. As contribuições
de parte dos estudos apresentados neste capítulo serviram como base, principalmente, na
definição de quais metodologias e técnicas de análise de dados a serem utilizadas no nosso
trabalho. A tabela 6 denota a comparação levando em consideração se os estudos analisam
projetos que adotam CI, se analisam cobertura, tipo do estudo e também quantifica o
período dos dados das coletas. Já a tabela 7 confronta os estudos por meio da quantidade
de versões/projetos analisados e a linguagem suportadas nos respectivos projetos alvo.

Apesar de todos os trabalhos denotados na Tabela 6 terem a proposta de serem um


estudo empírico, eles apresentaram temas e tempos de análises distintos. O trabalho do
(HILTON; BELL; MARINOV, 2018) focou seu estudo na cobertura de código, enquanto que
as propostas de (BERNARDO; COSTA; KULESZA, 2018) e (ZHAO et al., 2017) focaram em
CI. O Nosso trabalho e o (NERY; COSTA; KULESZA, 2019) analisaram ambos os aspectos
de tanto em relação ao impacto de CI, quanto a análise de cobertura dos projetos.

Os trabalhos apresentaram perspectivas diferentes das métricas utilizadas para análise.


Os trabalhos de (NERY; COSTA; KULESZA, 2019) e (BERNARDO, 2017) utilizaram uma
medida de intervalo temporal. Houve um embasamento em intervalos restritos como a
quantidade de anos e datas de eventos impactantes, como a data de adoção de CI até a
data de coleta dos dados. Já os trabalhos de (HILTON; BELL; MARINOV, 2018) e (ZHAO et
al., 2017) consideraram uma quantidade limitada de commits.

Os trabalhos denotados nesta seção se distinguem também pela quantidade de proje-


tos e versões utilizadas para as suas respectivas análises. O trabalho do (HILTON; BELL;
MARINOV, 2018) apresentou a maior quantidade de versões e projetos analisados (47 pro-
jetos, totalizando 7816 versões), mesmo denotando que não conseguiram obter os dados
de todas as versões por limitação da quantidade de requisições da API do Coveralls. Tal
problema também foi encontrado no nosso trabalho e se tornou a maior dificuldade em se
usar os dados do Coveralls. Apesar disso, o projeto se limitou as linguagens Java, Python e
Scala, enquanto que nós observamos mais linguagens, como PHP e Javascript. O trabalho
que apresentou a menor quantidade de versões foi o de (BERNARDO; COSTA; KULESZA,
2018) com 87 projetos. Entretanto, (BERNARDO; COSTA; KULESZA, 2018) buscam analisar
63

todos os pull requests do começo de CI até uma determinada data, o que faz com que a
quantidade de dados a serem analisadas sejam bem consideráveis, já que foram, no total,
163.653 pull requests.

O trabalho de (NERY; COSTA; KULESZA, 2019) apresentou analise de 20 projetos, tota-


lizando 480 versões analisadas. Já o nosso trabalho estendeu essa quantidade (totalizando
2544 versões) e adicionou projetos de outras linguagens que não estavam presentes na sua
análise de cobertura, como Ruby e PHP. Por término, (ZHAO et al., 2017) analisaram 2500
versões entre 25 projetos mas apenas para a linguagem de programação Java.

Este trabalho se propôs a explorar um caminho que não foi visto nos trabalhos relaci-
onados descrito nessa seção (exceção para o trabalho de (NERY; COSTA; KULESZA, 2019))
que foi o de analisar CI e a cobertura procurando relacioná-las. Buscamos abranger proje-
tos de várias linguagens de programações diferentes, ter um intervalo temporal de coleta
de dados de anos e ter vários projetos de perspectivas distintas. O conjunto das caracte-
rísticas distintas ditas anteriormente faz com que esse trabalho tenha sua importância no
ramo de pesquisa sobre a relação de integração contínua e cobertura de código, agregando
conhecimento e servindo como um trabalho de base para novas pesquisas na área.

Tabela 6: Comparação entre os projetos por CI, cobertura, tipo do estudo e tempo
Analisa Analisa Tipo de
Trabalho\Tópicos Tempo
CI cobertura estudo
CI/NOCI : 2 anos
Nosso trabalho X X Empírico
Coveralls : 1 ano
(HILTON, 2018) X Empírico 250 últimos commits
(ZHAO, 2017) X Empírico 100 últimos builds
(NERY, 2019) X X Empírico 2 anos
(BERNARDO, 2018) X Empírico Adoção de CI à 11/11/2016

Tabela 7: Comparação entre os projetos por versões analisadas e linguagens suportadas


Quantidade de
Trabalho\Tópicos Linguagens
projetos/Versões
CI/NOCI : 60/1440
Nosso trabalho Java, Python, Ruby, PHP e JavaScript
Coveralls : 92/1104
(HILTON, 2018) 47/7816 Java, Python e Scala.
(ZHAO, 2017) 25/2500 Java
(NERY, 2019) 20/480 Java, Python, Javascript
(BERNARDO, 2018) 87 Java, Python, Ruby, PHP e JavaScript
64

6 Considerações finais

Os efeitos e os impactos da adoção de CI no desenvolvimento de software motivaram


diversas pesquisas nos últimos anos. A seção 5 listamos algumas pesquisas nesse sentido.
Esse trabalho de pesquisa fornece informações valiosas sobre o impacto da adoção de CI
nos resultados da cobertura de testes em software de código aberto. A fim de atingir esse
objetivo, realizamos uma revisão da literatura sobre avaliação de testes de software no
contexto de projetos que adotaram CI em projetos código aberto.

Verificamos que ainda existem muitas suposições no comunidade que permanece em-
piricamente inexplorada, principalmente, em relação aos efeitos de CI na cobertura de
código. O trabalho conduzido por (NERY, 2020) dar um primeiro passo sobre essa ques-
tão. Contudo, o referido trabalho realizou o estudo de cobertura em um conjunto rela-
tivamente pequeno de projetos, sendo necessário, portanto, um estudo mais robusto em
termos de volume de dados. Nesse contexto, a presente pesquisa estende o trabalho de
(NERY, 2020), realizando uma investigação mais ampla e voltada especificamente a ques-
tão da cobertura em projetos código aberto. Além disso, esse pesquisa investiga se existe
alguma similaridade de comportamentos entre as coberturas de projetos CI e dos proje-
tos retirados do Coveralls. Observar se projetos CI oriundos de fontes distintas possuem
comportamentos similares contribui na validação de generalização dos resultados. No res-
tante deste capítulo, delineamos as contribuições desta pesquisa e discutimos possíveis
trabalhos futuros.

6.1 Contribuições da dissertação

A principal contribuição dessa dissertação foi promover um melhor entendimento,


através da condução de um estudo empírico, sobre como a cobertura de código se com-
porta em projetos que adotaram CI e em projetos que não adotaram CI. Delimitamos as
contribuições abaixo de acordo com os resultados de cada análise:
65

• Encontramos que os projetos do datasetCI apresentam mais similaridade entre si,


já que a melhor quantidade de grupos denotado pelo algoritmo foram 3.

• A tendência mais comum nos datasetCI foram a de Maintaining com 20 dos 30


projetos analisados. A tendência de raising apresentou 10 de 30 projetos e não
tivemos nenhum grupo com a tendência de decreasing.

• Encontramos que os projetos pertencentes ao datasetN OCI não apresentam com-


portamento similar entre si em relação a cobertura dos testes, já que a melhor
quantidade de grupos foi de 25 clusters.

• Percebemos que a tendência de Maintaining é a mais comum no datasetN OCI


representando 25 dos 30 projetos analisados. A de raising com 3 projetos e a de
decreasing com apenas 2 projetos.

• Levando em consideração apenas as versões coletadas após CI, chamadas nesse es-
tudo de datasetP OSCI, percebemos que também não existe uma similaridade entre
o comportamento das coberturas dos projetos, já que o algoritmo de melhor quan-
tidade de clusters retornou 16.

• Analisando os dados obtidos do datasetP OSCI podemos observar que ele teve uma
tendência dominante de maintaining com 29 projetos. Decreasing apresentou apenas
1 projeto e raising não foi identificado em nenhum projeto.

• Utilizando a base de dados de projetos CI advindos do Coveralls(datasetCoveralls),


nós conseguimos identificar que eles também não apresentam similaridade de com-
portamento da cobertura durante o período analisado, pois o algoritmo de definição
de melhor número de grupos retornou 34 grupos.

• Maintaining foi a tendência mais presente no datasetCoveralls com 90 projetos dos


92 analisados nesse conjunto. Raising apresentou apenas 2 projetos, enquanto que
decreasing não apresentou amostras.

• Pelos resultados, identificamos que projetos CI tendem a manter a sua respectiva


cobertura durante pelo menos 1 ano e esta tende a ter uma valor elevado, acima de
75%.

• Identificamos pelos nossos resultados que projetos NOCI também apresentam a


manutenção da cobertura, mas esta tende a ser baixa, com valores abaixo de 50%.
66

• De acordo com os resultados obtidos, os projetos CI tendem a obter maior chance


de aumentar a porcentagem de cobertura do os projetos NOCI.

• Os dados do datasetP OSCI de (NERY, 2020) apresenta bastante semelhança com


o datasetCoveralls, tanto na similaridade interna de projetos, quanto em tendência
da cobertura no geral e nos subgrupos mais populosos.

• Acreditamos que foi o comportamento da cobertura de antes da adoção de CI o


principal responsável pela alta similaridade datasetCI. Isso implica que houve uma
variação significativa da cobertura no momento que o projeto adotou CI, ou seja,
existe um forte indicativo que CI realmente ajudou alguns dos projetos a aumenta-
rem a cobertura e a forma que isso aconteceu foi bastante parecida entre os projetos.

• Recomendamos fortemente que os pesquisadores, que desejam analisar cobertura de


código fonte, utilizem o Coveralls para obter dos dados de cobertura para projetos
que utilizam CI, ao invés de realizar o build, execução e coleta das cobertura por
meio de aplicações ou frameworks de testes. A escolha de uso dos dados advin-
dos do Coveralls pode reduzir consideravelmente o tempo de condução do estudo.
Entretanto, nem sempre dados relevantes e que atendem ao estudo podem estar
disponíveis em tais repositórios.

6.1.1 QP1 - Quais são as tendências de comportamento dos valo-


res de cobertura de testes de projetos CI e NOCI?

Identificamos que projetos CI tendem a manter a sua respectiva cobertura durante


pelo menos 1 ano em valores elevados de cobertura, acima de 75%. Enquanto que, apesar
dos projetos que nunca adotaram CI (projetos NOCI) também apresentam a manutenção
da cobertura, essa tendência se estabelece em níveis menores de cobertura, valores abaixo
de 50%. Diante dos valores citados, concluímos que os projetos CI tendem a ter maior
probabilidade de aumentar a porcentagem de cobertura do que os projetos NOCI. E além
disso, tais projetos conseguem estabilizar os valores de cobertura em patamares superiores
aos projetos não CI
67

6.1.2 QP2 - Existe uma associação entre as taxas de cobertura de


testes dos projetos CI analisados com as de outros projetos
CI advindos do Coveralls?

Os dados relativos ao datasetP OSCI indicam que existe uma relação de similaridade
de comportamento, tendência geral e tendência dos subgrupos mais populosos com o
datasetCoveralls. Notou-se que a tendência predominante no datasetCoveralls foi a de
manutenção da cobertura (90/92 projetos). Os demais projetos apresentaram tendência
de alta, enquanto que ninguém apresentou tendência de queda nas amostras.

De acordo com os nossos resultados nós concluímos que as coberturas do datasetP OSCI
e datasetCoveralls se comportam de forma bastante análoga, ou seja, acreditamos que
existe uma grande possibilidade de que os dados advindos do Coveralls possam substituir
os dados obtidos dos projetos CI de (NERY, 2020). Entretanto, é necessário uma verificação
estatística para validação.

Outro ponto denotado pelos resultados é que os projetos CI mantiveram um com-


portamento bem parecido desde a criação do dataset de (NERY, 2020) até a extração dos
dados realizada nesse estudo do Coveralls. Isso nos faz pensar que existe a possibilidade
de existir um padrão de comportamento da cobertura em projetos que adotaram CI. Esse
tópico merece análises futuras, mas este trabalho serve como passo inicial para definição
dessa conjectura.

6.2 Trabalhos Futuros

Esta dissertação contribui para diminuir a falta de compreensão empírica do impacto


da adoção de integração contínua na cobertura dos testes. No entanto, mais trabalho de
pesquisa é necessário para melhor compreender e melhorar as atividades de integração e
a evolução da cobertura. Nós delineamos alguns locais para trabalhos futuros abaixo.

Trabalhos futuros podem replicar as análises que são realizadas nesta dissertação
usando projetos e linguagens de programação adicionais. Além disso, a replicação deste
estudo usando projetos privados é necessária (ou seja, deve-se estudar o impacto de CI
na cobertura em projetos da iniciativa privada em vez de projetos de código aberto).
Esses estudos de replicação são importantes para chegar a conclusões mais generalizáveis
sobre o impacto de CI na cobertura de testes. Para fins de replicação, publicamos nossos
conjuntos de dados para o pesquisador interessado. Além disso, pesquisas podem ser
68

realizadas incluindo outros serviços de integração contínua além do Travis CI.

Uma proposta de extensão desse trabalho pode ser a utilização de análise estatística
para comparar os valores do datasetP OSCI e datasetCoveralls. Nesse trabalho descobri-
mos que estes datasets são equivalentes para alguns aspectos. Entretanto, uma análise com
base estatística pode garantir de forma estatística que realmente estes conjuntos são da
mesma população. Testes estatísticos de hipóteses não paramétricos podem ser utilizados
para esse fim.
69

Referências

ABERDOUR, M. Achieving quality in open-source software. IEEE software, IEEE,


v. 24, n. 1, p. 58–64, 2007.

AHMED, I. et al. Can testedness be effectively measured? In: . New York, NY,
USA: Association for Computing Machinery, 2016. (FSE 2016), p. 547–558. ISBN
9781450342186. Disponível em: <https://doi.org/10.1145/2950290.2950324>.

BECK, K. Test-driven development: by example. [S.l.]: Addison-Wesley Professional,


2003.

BELLER, M.; GOUSIOS, G.; ZAIDMAN, A. Oops, my tests broke the build: An analysis
of travis ci builds with github. [S.l.], 2016.

BERNARDO, J. a. H.; COSTA, D. A. da; KULESZA, U. Studying the impact of


adopting continuous integration on the delivery time of pull requests. In: Proceedings
of the 15th International Conference on Mining Software Repositories. New York,
NY, USA: Association for Computing Machinery, 2018. (MSR ’18), p. 131–141. ISBN
9781450357166. Disponível em: <https://doi.org/10.1145/3196398.3196421>.

BERNARDO, J. H. J. d. A. The impact of adopting continuous integration on the


delivery time of merged pull requests: an empirical study. Dissertação (Mestrado) —
Brasil, 2017.

BERNARDO, P. C.; KON, F. A importância dos testes automatizados. Engenharia de


Software Magazine, v. 1, n. 3, p. 54–57, 2008.

BERNDT, D. J.; CLIFFORD, J. Using dynamic time warping to find patterns in time
series. In: SEATTLE, WA, USA:. KDD workshop. [S.l.], 1994. v. 10, n. 16, p. 359–370.

BERTOLINO, A. Software testing research: Achievements, challenges, dreams. In: IEEE.


Future of Software Engineering (FOSE’07). [S.l.], 2007. p. 85–103.

BOEHM, B. W.; BROWN, J. R.; LIPOW, M. Quantitative evaluation of software


quality. In: Proceedings of the 2nd international conference on Software engineering. [S.l.:
s.n.], 1976. p. 592–605.

CHOW, T.; CAO, D.-B. A survey study of critical success factors in agile software
projects. Journal of systems and software, Elsevier, v. 81, n. 6, p. 961–971, 2008.

COVERALLS, L. Getting started. Jul 2021. Disponível em: <https://docs.coveralls.io/>.


Acesso em 19 de Julho, 2021.

CROWSTON, K.; ANNABI, H.; HOWISON, J. Defining open source software project
success. 2003.
70

DUVALL, P. M.; MATYAS, S.; GLOVER, A. Continuous integration: improving software


quality and reducing risk. [S.l.]: Pearson Education, 2007.

ELBAUM, S.; GABLE, D.; ROTHERMEL, G. The impact of software evolution on


code coverage information. In: Proceedings IEEE International Conference on Software
Maintenance. ICSM 2001. [S.l.: s.n.], 2001. p. 170–179.

FITZPATRICK, R. Software quality: definitions and strategic issues. Staffordshire


University, School of Computing Report, Citeseer, 1996.

FOWLER, M.; FOEMMEL, M. Continuous integration. Thought-Works) http://www.


thoughtworks. com/Continuous Integration. pdf, v. 122, p. 14, 2006.

GALILI, T. K-means Clustering (from "R in Action"). ago. 2013. Disponível em:
<https://www.r-statistics.com/2013/08/k-means-clustering-from-r-in-action/>. Acesso em
17 de Junho, 2021.

GITHUB, I. Search. Jul 2021. Disponível em: <https://docs.github.com/en/rest/


reference/search#about-the-search-api>. Acesso em 19 de Julho, 2021.

GORTON, I.; LIU, A. Software component quality assessment in practice: successes and
practical impediments. In: Proceedings of the 24th international conference on software
engineering. [S.l.: s.n.], 2002. p. 555–558.

HILTON, M.; BELL, J.; MARINOV, D. A large-scale study of test coverage evolution.
In: Proceedings of the 33rd ACM/IEEE International Conference on Automated Software
Engineering. [S.l.: s.n.], 2018. p. 53–63.

HILTON, M. et al. Usage, costs, and benefits of continuous integration in open-source


projects. In: IEEE. 2016 31st IEEE/ACM International Conference on Automated
Software Engineering (ASE). [S.l.], 2016. p. 426–437.

LABUSCHAGNE, A.; INOZEMTSEVA, L.; HOLMES, R. Measuring the cost of


regression testing in practice: A study of java projects using continuous integration. In:
Proceedings of the 2017 11th Joint Meeting on Foundations of Software Engineering.
[S.l.: s.n.], 2017. p. 821–830.

LEE, S.-Y. T.; KIM, H.-W.; GUPTA, S. Measuring open source software success. Omega,
Elsevier, v. 37, n. 2, p. 426–438, 2009.

LI, Y. et al. A class-level test selection approach toward full coverage for continuous
integration. In: SEKE. [S.l.: s.n.], 2019. p. 49–70.

LUZ, W. P.; PINTO, G.; BONIFÁCIO, R. Building a collaborative culture: a


grounded theory of well succeeded devops adoption in practice. In: Proceedings of the
12th ACM/IEEE International Symposium on Empirical Software Engineering and
Measurement. [S.l.: s.n.], 2018. p. 1–10.

MAECHLER, M. Gap Statistic for Estimating the Number of Clusters. Abr 2021.
Disponível em: <https://stat.ethz.ch/R-manual/R-devel/library/cluster/html/clusGap.
html>. Acesso em 17 de Junho, 2021.
71

MAHDIEH, M. et al. Incorporating fault-proneness estimations into


coverage-based test case prioritization methods. Information and Soft-
ware Technology, v. 121, p. 106269, 2020. ISSN 0950-5849. Disponível em:
<https://www.sciencedirect.com/science/article/pii/S0950584920300197>.

MARINESCU, P.; HOSEK, P.; CADAR, C. Covrig: A framework for the analysis of code,
test, and coverage evolution in real software. In: Proceedings of the 2014 International
Symposium on Software Testing and Analysis. New York, NY, USA: Association for
Computing Machinery, 2014. (ISSTA 2014), p. 93–104. ISBN 9781450326452. Disponível
em: <https://doi.org/10.1145/2610384.2610419>.

MÅRTENSSON, T.; HAMMARSTRÖM, P.; BOSCH, J. Continuous integration is not


about build systems. In: IEEE. 2017 43rd Euromicro Conference on Software Engineering
and Advanced Applications (SEAA). [S.l.], 2017. p. 1–9.

MÅRTENSSON, T.; STÅHL, D.; BOSCH, J. Continuous integration impediments in


large-scale industry projects. In: IEEE. 2017 IEEE International Conference on Software
Architecture (ICSA). [S.l.], 2017. p. 169–178.

MÅRTENSSON, T.; STÅHL, D.; BOSCH, J. Test activities in the continuous integration
and delivery pipeline. Journal of Software: Evolution and Process, Wiley Online Library,
v. 31, n. 4, p. e2153, 2019.

MEYER, M. Continuous integration and its tools. IEEE software, IEEE, v. 31, n. 3, p.
14–16, 2014.

MÜLLER, M. Dynamic time warping. Information retrieval for music and motion,
Springer, p. 69–84, 2007.

NERY, G. S. Understanding the relationship between continuous integration and its


effects on software quality outcomes. Universidade Federal do Rio Grande do Norte,
2020.

NERY, G. S.; COSTA, D. A. da; KULESZA, U. An empirical study of the relationship


between continuous integration and test code evolution. In: IEEE. 2019 IEEE
International Conference on Software Maintenance and Evolution (ICSME). [S.l.], 2019.
p. 426–436.

PINTO, G. et al. Work practices and challenges in continuous integration: A survey with
travis ci users. Software: Practice and Experience, Wiley Online Library, v. 48, n. 12, p.
2223–2236, 2018.

PINTO, G.; REBOUÇAS, M.; CASTOR, F. Inadequate testing, time pressure, and
(over) confidence: a tale of continuous integration users. In: IEEE. 2017 IEEE/ACM 10th
International Workshop on Cooperative and Human Aspects of Software Engineering
(CHASE). [S.l.], 2017. p. 74–77.

PRESSMAN, R. Software Engineering: A Practitioner’s Approach. 7. ed. USA:


McGraw-Hill, Inc., 2009. ISBN 0073375977.

R. Feb 2020. Versão 3.6.3. Disponível em: <https://www.r-project.org/>.


72

REEL, J. S. Critical success factors in software projects. IEEE software, IEEE, v. 16,
n. 3, p. 18–23, 1999.

ROGERS, R. O. Scaling continuous integration. In: SPRINGER. International conference


on extreme programming and agile processes in software engineering. [S.l.], 2004. p.
68–76.

SARDA, A. tsclust: Time series clustering. Feb 2017. Disponível em: <https:
//www.rdocumentation.org/packages/dtwclust/versions/3.1.1/topics/tsclust>. Acesso em
19 de Julho, 2021.

STAMELOS, I. et al. Code quality analysis in open source software development.


Information systems journal, Wiley Online Library, v. 12, n. 1, p. 43–60, 2002.

TEAM, R. C.; CONTRIBUTORS. kmeans: K-Means Clustering. fev. 2020. Disponível


em: <https://rdrr.io/r/stats/kmeans.html>. Acesso em 17 de Junho, 2021.

TEAM, R. core. Rscript: Scripting Front-End for R. Feb 2020. Disponível em:
<https://www.rdocumentation.org/packages/utils/versions/3.6.2/topics/Rscript>. Acesso
em 19 de Julho, 2021.

TIBSHIRANI, R.; WALTHER, G.; HASTIE, T. Estimating the number of clusters


in a data set via the gap statistic. Journal of the Royal Statistical Society: Series B
(Statistical Methodology), Wiley Online Library, v. 63, n. 2, p. 411–423, 2001.

VASILESCU, B. et al. Quality and productivity outcomes relating to continuous


integration in github. In: Proceedings of the 2015 10th Joint Meeting on Foundations of
Software Engineering. [S.l.: s.n.], 2015. p. 805–816.

WIDDER, D. G. et al. A conceptual replication of continuous integration pain points


in the context of travis ci. In: Proceedings of the 2019 27th ACM Joint Meeting on
European Software Engineering Conference and Symposium on the Foundations of
Software Engineering. [S.l.: s.n.], 2019. p. 647–658.

WILCOX, R. R. Fundamentals of modern statistical methods: Substantially improving


power and accuracy. [S.l.]: Springer, 2010.

WONG, M. A.; HARTIGAN, J. Algorithm as 136: A k-means clustering algorithm.


Journal of the Royal Statistical Society. Series C (Applied Statistics), v. 28, n. 1, p.
100–108, 1979.

YANG, Y. et al. Hunting for bugs in code coverage tools via randomized differential
testing. In: IEEE. 2019 IEEE/ACM 41st International Conference on Software
Engineering (ICSE). [S.l.], 2019. p. 488–499.

ZHAO, Y. et al. The impact of continuous integration on other software development


practices: A large-scale empirical study. In: 2017 32nd IEEE/ACM International
Conference on Automated Software Engineering (ASE). [S.l.: s.n.], 2017. p. 60–71.
73

APÊNDICE A -- DatasetCI

Project/Version 1 2 3 4 5 6 7 8
AnalyticalGraphicsInc/cesium 0.85 0.82 0.84 0.87 0.86 0.94 0.95 0.95
Leaflet/Leaflet 0.46 0.46 0.46 0.46 0.46 0.46 0.46 0.46
Marak/faker.js 1.0 1.0 1.0 1.0 0.95 0.96 0.96 0.96
Netflix/Hystrix 0.31 0.31 0.31 0.28 0.28 0.62 0.79 0.8
Pylons/pyramid 0.99 0.99 0.99 0.99 0.99 0.99 0.99 0.99
Yelp/mrjob 0.81 0.82 0.82 0.82 0.82 0.83 0.82 0.82
aframevr/aframe 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
ansible/ansible 0.55 0.6 0.6 0.6 0.6 0.6 0.6 0.04
bcit-ci/CodeIgniter 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
cakephp/cakephp 0.75 0.75 0.75 0.0 0.84 0.84 0.85 0.85
craftyjs/Crafty 0.33 0.32 0.32 0.34 0.37 0.39 0.47 0.47
cython/cython 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9
dropwizard/dropwizard 0.43 0.44 0.45 0.45 0.46 0.46 0.39 0.5
dropwizard/metrics 0.69 0.68 0.66 0.66 0.66 0.66 0.67 0.67
fog/fog 0.12 0.62 0.61 0.07 0.61 0.62 0.63 0.64
gollum/gollum 0.86 0.85 0.82 0.85 0.86 0.9 0.9 0.9
jashkenas/backbone 0.92 0.93 0.93 0.93 0.94 0.94 0.96 0.97
jashkenas/underscore 0.96 0.96 0.96 0.96 0.97 0.96 0.96 0.96
kivy/kivy 0.09 0.09 0.17 0.09 0.08 0.08 0.08 0.08
loomio/loomio 0.71 0.58 0.5 0.51 0.46 0.45 0.46 0.43
matplotlib/matplotlib 0.0 0.37 0.46 0.46 0.47 0.47 0.46 0.48
mozilla/pdf.js 0.16 0.27 0.27 0.21 0.21 0.21 0.2 0.19
request/request 0.66 0.65 0.65 0.67 0.84 0.84 0.84 0.84
robolectric/robolectric 0.68 0.71 0.71 0.72 0.72 0.72 0.73 0.73
scipy/scipy 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.18
sensu/sensu 0.0 0.0 0.0 0.0 0.0 0.0 0.54 0.78
serverless/serverless 0.0 0.0 0.0 0.0 0.22 0.14 0.23 0.22
square/picasso 0.0 0.29 0.56 0.54 0.56 0.48 0.48 0.56
sympy/sympy 0.74 0.75 0.73 0.75 0.75 0.76 0.76 0.77
yiisoft/yii 0.26 0.26 0.26 0.26 0.26 0.26 0.26 0.26

Tabela 8: Dataset CI - Parte 1/3


74

Project/Version 9 10 11 12 13 14 15 16
AnalyticalGraphicsInc/cesium 0.95 0.95 0.95 0.95 0.95 0.94 0.94 0.94
Leaflet/Leaflet 0.46 0.46 0.46 0.47 0.5 0.47 0.57 0.57
Marak/faker.js 1.0 1.0 1.0 1.0 0.86 0.85 0.86 0.85
Netflix/Hystrix 0.79 0.79 0.79 0.8 0.76 0.75 0.74 0.74
Pylons/pyramid 0.99 1.0 1.0 0.99 1.0 1.0 1.0 1.0
Yelp/mrjob 0.82 0.82 0.82 0.82 0.82 0.83 0.83 0.83
aframevr/aframe 0.5 0.39 0.63 0.61 0.24 0.75 0.79 0.86
ansible/ansible 0.05 0.05 0.05 0.05 0.05 0.05 0.06 0.06
bcit-ci/CodeIgniter 0.0 0.0 0.0 0.0 0.1 0.12 0.18 0.19
cakephp/cakephp 0.85 0.86 0.86 0.86 0.81 0.86 0.86 0.86
craftyjs/Crafty 0.47 0.52 0.54 0.64 0.69 0.7 0.73 0.73
cython/cython 0.9 0.9 0.9 0.9 0.9 0.9 0.91 0.91
dropwizard/dropwizard 0.5 0.5 0.5 0.61 0.61 0.65 0.66 0.66
dropwizard/metrics 0.67 0.67 0.67 0.76 0.75 0.75 0.74 0.74
fog/fog 0.63 0.65 0.19 0.64 0.66 0.66 0.66 0.51
gollum/gollum 0.58 0.58 0.57 0.57 0.45 0.83 0.83 0.83
jashkenas/backbone 0.97 0.98 0.98 0.98 0.97 0.97 0.98 0.98
jashkenas/underscore 0.97 0.97 0.97 0.97 0.97 0.97 0.97 0.97
kivy/kivy 0.08 0.08 0.08 0.09 0.09 0.09 0.28 0.28
loomio/loomio 0.41 0.41 0.41 0.41 0.22 0.21 0.13 0.13
matplotlib/matplotlib 0.49 0.49 0.5 0.5 0.56 0.57 0.58 0.57
mozilla/pdf.js 0.19 0.16 0.16 0.16 0.16 0.16 0.16 0.16
request/request 0.84 0.84 0.85 0.85 0.84 0.84 0.84 0.84
robolectric/robolectric 0.73 0.69 0.67 0.7 0.74 0.74 0.74 0.75
scipy/scipy 0.18 0.18 0.18 0.18 0.18 0.18 0.17 0.17
sensu/sensu 0.52 0.75 0.74 0.74 0.51 0.69 0.69 0.67
serverless/serverless 0.2 0.13 0.06 0.26 0.37 0.88 0.92 0.91
square/picasso 0.56 0.56 0.56 0.56 0.56 0.58 0.6 0.6
sympy/sympy 0.77 0.78 0.78 0.79 0.27 0.27 0.26 0.26
yiisoft/yii 0.28 0.28 0.28 0.28 0.29 0.32 0.33 0.33

Tabela 9: Dataset CI - Parte 2/3


75

Project/Version 17 18 19 20 21 22 23 24
AnalyticalGraphicsInc/cesium 0.94 0.94 0.94 0.94 0.93 0.94 0.95 0.95
Leaflet/Leaflet 0.57 0.57 0.57 0.58 0.57 0.61 0.53 0.5
Marak/faker.js 0.86 0.85 0.86 0.86 0.86 0.87 0.96 0.96
Netflix/Hystrix 0.76 0.74 0.74 0.75 0.74 0.74 0.74 0.73
Pylons/pyramid 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99
Yelp/mrjob 0.83 0.83 0.82 0.8 0.81 0.8 0.81 0.81
aframevr/aframe 0.86 0.86 0.81 0.67 0.84 0.84 0.84 0.82
ansible/ansible 0.06 0.06 0.07 0.08 0.08 0.08 0.08 0.08
bcit-ci/CodeIgniter 0.19 0.19 0.46 0.46 0.49 0.53 0.17 0.17
cakephp/cakephp 0.86 0.86 0.86 0.86 0.86 0.0 0.86 0.86
craftyjs/Crafty 0.73 0.73 0.74 0.74 0.74 0.72 0.75 0.72
cython/cython 0.91 0.91 0.91 0.91 0.91 0.91 0.91 0.91
dropwizard/dropwizard 0.66 0.66 0.64 0.65 0.65 0.65 0.66 0.66
dropwizard/metrics 0.74 0.74 0.74 0.74 0.74 0.73 0.72 0.73
fog/fog 0.67 0.67 0.66 0.66 0.66 0.67 0.67 0.67
gollum/gollum 0.82 0.86 0.86 0.86 0.79 0.79 0.79 0.79
jashkenas/backbone 0.97 0.97 0.97 0.97 0.97 0.97 0.98 0.97
jashkenas/underscore 0.97 0.97 0.97 0.97 0.97 0.97 0.97 0.97
kivy/kivy 0.28 0.28 0.28 0.31 0.31 0.31 0.31 0.31
loomio/loomio 0.0 0.13 0.14 0.13 0.13 0.38 0.38 0.39
matplotlib/matplotlib 0.58 0.57 0.61 0.56 0.52 0.55 0.55 0.55
mozilla/pdf.js 0.16 0.16 0.15 0.15 0.15 0.15 0.0 0.0
request/request 0.85 0.85 0.85 0.85 0.85 0.85 0.86 0.87
robolectric/robolectric 0.75 0.76 0.76 0.77 0.77 0.77 0.78 0.78
scipy/scipy 0.17 0.17 0.17 0.17 0.17 0.0 0.17 0.17
sensu/sensu 0.7 0.81 0.61 0.61 0.6 0.22 0.27 0.27
serverless/serverless 0.94 0.94 0.96 0.95 0.96 0.96 0.97 0.97
square/picasso 0.59 0.59 0.59 0.59 0.61 0.61 0.62 0.63
sympy/sympy 0.27 0.27 0.27 0.27 0.27 0.27 0.27 0.27
yiisoft/yii 0.38 0.4 0.34 0.39 0.4 0.41 0.41 0.42

Tabela 10: Dataset CI - Parte 3/3


76

APÊNDICE B -- DatasetN OCI

Project/Version 1 2 3 4 5 6 7 8
BorisMoore/jsrender 0.96 0.96 0.94 0.94 0.94 0.94 0.91 0.92
MyCATApache/Mycat-Server 0.24 0.26 0.24 0.24 0.23 0.23 0.23 0.24
Shopify/liquid 0.25 0.25 0.25 0.25 0.24 0.25 0.24 0.25
Voog/wysihtml 0.47 0.46 0.5 0.5 0.49 0.49 0.49 0.48
alibaba/cobar 0.34 0.34 0.34 0.34 0.34 0.34 0.34 0.34
alibaba/jstorm 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.02
ankane/ahoy 0.27 0.27 0.27 0.27 0.28 0.0 0.31 0.31
bup/bup 0.56 0.56 0.56 0.56 0.56 0.65 0.65 0.64
chriskiehl/Gooey 0.34 0.34 0.35 0.26 0.22 0.24 0.24 0.23
cowbell/sharedrop 0.0 0.0 0.0 0.0 0.0 0.0 0.4 0.2
dataarts/dat.gui 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
fxsjy/jieba 0.72 0.73 0.76 0.75 0.79 0.68 0.68 0.75
hankcs/HanLP 0.0 0.14 0.45 0.46 0.14 0.13 0.12 0.13
httpie/httpie 0.94 0.93 0.94 0.94 0.93 0.93 0.92 0.89
idank/explainshell 0.28 0.2 0.2 0.2 0.2 0.2 0.2 0.2
jubos/fake-s3 0.29 0.29 0.29 0.29 0.29 0.29 0.29 0.29
julianshapiro/velocity 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
kennethreitz/grequests 0.95 0.95 0.95 0.95 0.98 0.98 0.98 0.98
lmenezes/elasticsearch-kopf 0.0 0.9 0.16 0.15 1.0 0.26 0.29 0.34
maxwellito/vivus 0.76 0.91 0.91 0.98 0.98 0.98 0.98 0.98
mleibman/SlickGrid 0.43 0.43 0.43 0.43 0.43 0.44 0.44 0.43
mojombo/chronic 0.86 0.86 0.86 0.86 0.86 0.86 0.86 0.86
mrniko/netty-socketio 0.32 0.32 0.31 0.31 0.31 0.27 0.27 0.26
powmedia/backbone-forms 0.7 0.67 0.67 0.67 0.67 0.67 0.67 0.56
psf/requests 0.58 0.59 0.61 0.61 0.63 0.63 0.64 0.64
pybrain/pybrain 0.3 0.3 0.3 0.3 0.3 0.29 0.29 0.29
serratus/quaggaJS 0.0 0.0 0.26 0.27 0.26 0.26 0.26 0.22
symfony/process 0.61 0.6 0.61 0.72 0.62 0.66 0.65 0.67
symfony/routing 0.78 0.79 0.78 0.78 0.78 0.78 0.78 0.79
symfony/var-dumper 0.57 0.58 0.57 0.0 0.63 0.65 0.6 0.65

Tabela 11: Dataset NOCI - Parte 1/3


77

Project/Version 9 10 11 12 13 14 15 16
BorisMoore/jsrender 0.92 0.92 0.91 0.91 0.91 0.91 0.91 0.91
MyCATApache/Mycat-Server 0.24 0.23 0.22 0.22 0.21 0.2 0.2 0.19
Shopify/liquid 0.25 0.25 0.27 0.27 0.27 0.27 0.27 0.27
Voog/wysihtml 0.48 0.47 0.46 0.46 0.46 0.46 0.42 0.46
alibaba/cobar 0.34 0.34 0.34 0.34 0.34 0.34 0.34 0.34
alibaba/jstorm 0.02 0.02 0.02 0.02 0.14 0.14 0.14 0.14
ankane/ahoy 0.31 0.31 0.31 0.33 0.33 0.33 0.33 0.33
bup/bup 0.65 0.65 0.65 0.65 0.66 0.66 0.66 0.66
chriskiehl/Gooey 0.23 0.23 0.29 0.26 0.28 0.28 0.28 0.28
cowbell/sharedrop 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2
dataarts/dat.gui 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
fxsjy/jieba 0.79 0.68 0.79 0.68 0.71 0.79 0.75 0.75
hankcs/HanLP 0.13 0.13 0.13 0.11 0.11 0.11 0.11 0.11
httpie/httpie 0.88 0.6 0.61 0.9 0.9 0.9 0.9 0.9
idank/explainshell 0.2 0.22 0.22 0.22 0.22 0.22 0.22 0.22
jubos/fake-s3 0.29 0.31 0.31 0.31 0.32 0.32 0.32 0.32
julianshapiro/velocity 0.45 0.45 0.45 0.45 0.45 0.45 0.45 0.45
kennethreitz/grequests 0.98 0.95 0.95 0.95 0.98 0.98 0.99 0.99
lmenezes/elasticsearch-kopf 0.4 0.43 0.46 0.55 0.56 0.55 0.55 0.54
maxwellito/vivus 0.98 0.98 0.98 0.98 0.98 0.98 0.98 0.98
mleibman/SlickGrid 0.41 0.41 0.41 0.41 0.41 0.4 0.4 0.4
mojombo/chronic 0.86 0.86 0.85 0.85 0.85 0.86 0.86 0.86
mrniko/netty-socketio 0.27 0.27 0.27 0.27 0.23 0.23 0.24 0.23
powmedia/backbone-forms 0.54 0.59 0.59 0.59 0.59 0.59 0.59 0.59
psf/requests 0.64 0.63 0.63 0.63 0.65 0.65 0.65 0.67
pybrain/pybrain 0.29 0.29 0.29 0.29 0.29 0.29 0.29 0.29
serratus/quaggaJS 0.23 0.25 0.25 0.17 0.17 0.17 0.17 0.17
symfony/process 0.7 0.69 0.69 0.69 0.72 0.72 0.72 0.74
symfony/routing 0.79 0.79 0.78 0.79 0.79 0.82 0.78 0.81
symfony/var-dumper 0.65 0.63 0.65 0.69 0.68 0.68 0.67 0.68

Tabela 12: Dataset NOCI - Parte 2/3


78

Project/Version 17 18 19 20 21 22 23 24
BorisMoore/jsrender 0.91 0.91 0.91 0.91 0.92 0.92 0.92 0.92
MyCATApache/Mycat-Server 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.19
Shopify/liquid 0.27 0.27 0.28 0.28 0.28 0.28 0.28 0.28
Voog/wysihtml 0.41 0.41 0.4 0.41 0.41 0.36 0.36 0.36
alibaba/cobar 0.34 0.34 0.34 0.34 0.34 0.34 0.34 0.34
alibaba/jstorm 0.14 0.14 0.14 0.14 0.14 0.11 0.11 0.12
ankane/ahoy 0.33 0.33 0.33 0.33 0.32 0.32 0.32 0.31
bup/bup 0.66 0.66 0.66 0.66 0.66 0.66 0.65 0.65
chriskiehl/Gooey 0.28 0.29 0.3 0.28 0.29 0.29 0.29 0.29
cowbell/sharedrop 0.0 0.2 0.2 0.2 0.2 0.2 0.2 0.2
dataarts/dat.gui 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
fxsjy/jieba 0.72 0.76 0.8 0.8 0.77 0.75 0.73 0.73
hankcs/HanLP 0.11 0.11 0.11 0.17 0.11 0.16 0.16 0.12
httpie/httpie 0.9 0.93 0.93 0.0 0.0 0.93 0.93 0.93
idank/explainshell 0.22 0.22 0.22 0.22 0.22 0.22 0.22 0.22
jubos/fake-s3 0.32 0.32 0.32 0.32 0.32 0.32 0.33 0.33
julianshapiro/velocity 0.45 0.45 0.45 0.45 0.45 0.45 0.45 0.45
kennethreitz/grequests 0.99 0.97 0.94 0.94 0.94 0.98 0.98 0.98
lmenezes/elasticsearch-kopf 0.55 0.56 0.56 0.56 0.56 0.56 0.57 0.57
maxwellito/vivus 0.98 0.97 0.97 0.97 0.97 0.97 0.97 0.97
mleibman/SlickGrid 0.4 0.4 0.4 0.22 0.39 0.39 0.4 0.39
mojombo/chronic 0.92 0.92 0.92 0.95 0.95 0.95 0.14 0.14
mrniko/netty-socketio 0.23 0.23 0.04 0.02 0.02 0.02 0.02 0.02
powmedia/backbone-forms 0.59 0.6 0.6 0.6 0.6 0.6 0.59 0.6
psf/requests 0.67 0.67 0.67 0.68 0.69 0.69 0.69 0.69
pybrain/pybrain 0.29 0.29 0.29 0.28 0.28 0.28 0.28 0.29
serratus/quaggaJS 0.17 0.2 0.2 0.2 0.2 0.2 0.22 0.0
symfony/process 0.73 0.18 0.18 0.18 0.18 0.18 0.18 0.11
symfony/routing 0.78 0.87 0.87 0.87 0.86 0.92 0.92 0.92
symfony/var-dumper 0.67 0.68 0.68 0.67 0.68 0.7 0.7 0.71

Tabela 13: Dataset NOCI - Parte 3/3


79

APÊNDICE C -- DatasetP OSCI

Project/Version v1 v2 v3 v4 v5 v6
AnalyticalGraphicsInc/cesium 0.95 0.94 0.94 0.94 0.94 0.94
Leaflet/Leaflet 0.5 0.47 0.57 0.57 0.57 0.57
Marak/faker.js 0.86 0.85 0.86 0.85 0.86 0.85
Netflix/Hystrix 0.76 0.75 0.74 0.74 0.76 0.74
Pylons/pyramid 1.0 1.0 1.0 1.0 1.0 1.0
Yelp/mrjob 0.82 0.83 0.83 0.83 0.83 0.83
aframevr/aframe 0.24 0.75 0.79 0.86 0.86 0.86
ansible/ansible 0.05 0.05 0.06 0.06 0.06 0.06
bcit-ci/CodeIgniter 0.1 0.12 0.18 0.19 0.19 0.19
cakephp/cakephp 0.81 0.86 0.86 0.86 0.86 0.86
craftyjs/Crafty 0.69 0.7 0.73 0.73 0.73 0.73
cython/cython 0.9 0.9 0.91 0.91 0.91 0.91
dropwizard/dropwizard 0.61 0.65 0.66 0.66 0.66 0.66
dropwizard/metrics 0.75 0.75 0.74 0.74 0.74 0.74
fog/fog 0.66 0.66 0.66 0.51 0.67 0.67
gollum/gollum 0.45 0.83 0.83 0.83 0.82 0.86
jashkenas/backbone 0.97 0.97 0.98 0.98 0.97 0.97
jashkenas/underscore 0.97 0.97 0.97 0.97 0.97 0.97
kivy/kivy 0.09 0.09 0.28 0.28 0.28 0.28
loomio/loomio 0.22 0.21 0.13 0.13 0.0 0.13
matplotlib/matplotlib 0.56 0.57 0.58 0.57 0.58 0.57
mozilla/pdf.js 0.16 0.16 0.16 0.16 0.16 0.16
request/request 0.84 0.84 0.84 0.84 0.85 0.85
robolectric/robolectric 0.74 0.74 0.74 0.75 0.75 0.76
scipy/scipy 0.18 0.18 0.17 0.17 0.17 0.17
sensu/sensu 0.51 0.69 0.69 0.67 0.7 0.81
serverless/serverless 0.37 0.88 0.92 0.91 0.94 0.94
square/picasso 0.56 0.58 0.6 0.6 0.59 0.59
sympy/sympy 0.27 0.27 0.26 0.26 0.27 0.27
yiisoft/yii 0.29 0.32 0.33 0.33 0.38 0.4

Tabela 14: Dataset POSCI - Parte 1/2


80

Project/Version v7 v8 v9 v10 v11 v12


AnalyticalGraphicsInc/cesium 0.94 0.94 0.93 0.94 0.95 0.95
Leaflet/Leaflet 0.57 0.58 0.57 0.61 0.53 0.5
Marak/faker.js 0.86 0.86 0.86 0.87 0.96 0.96
Netflix/Hystrix 0.74 0.75 0.74 0.74 0.74 0.73
Pylons/pyramid 1.0 1.0 1.0 1.0 1.0 0.99
Yelp/mrjob 0.82 0.8 0.81 0.8 0.81 0.81
aframevr/aframe 0.81 0.67 0.84 0.84 0.84 0.82
ansible/ansible 0.07 0.08 0.08 0.08 0.08 0.08
bcit-ci/CodeIgniter 0.46 0.46 0.49 0.53 0.17 0.17
cakephp/cakephp 0.86 0.86 0.86 0.0 0.86 0.86
craftyjs/Crafty 0.74 0.74 0.74 0.72 0.75 0.72
cython/cython 0.91 0.91 0.91 0.91 0.91 0.91
dropwizard/dropwizard 0.64 0.65 0.65 0.65 0.66 0.66
dropwizard/metrics 0.74 0.74 0.74 0.73 0.72 0.73
fog/fog 0.66 0.66 0.66 0.67 0.67 0.67
gollum/gollum 0.86 0.86 0.79 0.79 0.79 0.79
jashkenas/backbone 0.97 0.97 0.97 0.97 0.98 0.97
jashkenas/underscore 0.97 0.97 0.97 0.97 0.97 0.97
kivy/kivy 0.28 0.31 0.31 0.31 0.31 0.31
loomio/loomio 0.14 0.13 0.13 0.38 0.38 0.39
matplotlib/matplotlib 0.61 0.56 0.52 0.55 0.55 0.55
mozilla/pdf.js 0.15 0.15 0.15 0.15 0.0 0.0
request/request 0.85 0.85 0.85 0.85 0.86 0.87
robolectric/robolectric 0.76 0.77 0.77 0.77 0.78 0.78
scipy/scipy 0.17 0.17 0.17 0.0 0.17 0.17
sensu/sensu 0.61 0.61 0.6 0.22 0.27 0.27
serverless/serverless 0.96 0.95 0.96 0.96 0.97 0.97
square/picasso 0.59 0.59 0.61 0.61 0.62 0.63
sympy/sympy 0.27 0.27 0.27 0.27 0.27 0.27
yiisoft/yii 0.34 0.39 0.4 0.41 0.41 0.42

Tabela 15: Dataset POSCI - Parte 2/2


81

APÊNDICE D -- DatasetCoveralls

Project/Version 1 2 3 4 5 6
vuejs/vue 0.96 0.95 0.94 0.94 0.94 0.94
facebook/react 0.87 0.87 0.95 0.88 0.37 0.76
twbs/bootstrap 0.89 0.89 0.89 0.89 0.89 0.89
flutter/flutter 0.67 0.7 0.71 0.71 0.72 0.72
iluwatar/java-design-patterns 0.86 0.85 0.85 0.86 0.83 0.85
nvbn/thefuck 0.92 0.92 0.91 0.91 0.9 0.9
webpack/webpack 0.84 0.87 0.88 0.88 0.89 0.89
chartjs/Chart.js 0.72 0.75 0.84 0.84 0.85 0.84
expressjs/express 1.0 1.0 1.0 1.0 1.0 1.0
bitcoin/bitcoin 0.59 0.41 0.4 0.48 0.95 0.41
ElemeFE/element 0.35 0.92 0.91 0.89 0.89 0.88
lodash/lodash 0.98 1.0 1.0 1.0 1.0 0.93
gin-gonic/gin 0.88 0.92 0.94 0.93 0.93 0.93
moment/moment 0.92 1.0 0.95 0.95 0.95 0.95
scikit-learn/scikit-learn 0.95 0.95 0.94 0.94 0.94 0.94
jekyll/jekyll 0.87 0.86 0.87 0.85 0.83 0.84
neovim/neovim 0.0 0.57 0.56 0.56 0.56 0.57
scrapy/scrapy 0.52 0.74 0.3 0.85 0.94 0.47
serverless/serverless 0.87 0.87 0.88 0.88 0.88 0.88
nestjs/nest 0.91 0.94 0.95 0.95 0.95 0.95
mermaid-js/mermaid 0.53 0.53 0.53 0.54 0.54 0.49
JuliaLang/julia 0.81 0.12 1.0 0.29 0.5 0.64
hexojs/hexo 0.48 0.92 0.94 0.34 0.95 0.95
gulpjs/gulp 0.93 1.0 1.0 1.0 1.0 1.0
huginn/huginn 0.88 0.88 0.88 0.88 0.34 0.34
Continued on next page
82

Tabela 16 – continued from previous page


Project/Version 1 2 3 4 5 6
videojs/video.js 0.77 0.8 0.81 0.8 0.82 0.82
bumptech/glide 0.85 0.87 0.86 0.82 0.83 0.77
php/php-src 0.86 1.0 0.64 0.97 0.79 0.99
localstack/localstack 0.4 0.76 0.77 0.77 0.77 0.77
ethereum/go-ethereum 0.54 0.37 0.43 0.44 0.5 0.49
preactjs/preact 0.99 1.0 1.0 1.0 0.98 1.0
certbot/certbot 0.99 0.99 0.99 0.99 0.99 0.99
getsentry/sentry 0.67 0.66 0.67 0.66 0.67 0.67
react-boilerplate/react-boilerplate 0.99 0.99 0.99 0.99 1.0 1.0
pingcap/tidb 0.7 0.69 0.73 0.73 0.73 0.73
caolan/async 0.94 0.95 0.97 0.97 0.97 0.97
jashkenas/underscore 0.96 0.97 0.97 0.97 0.97 0.97
skylot/jadx 0.14 0.75 0.75 0.77 0.78 0.78
PowerShell/PowerShell 0.46 0.42 0.47 0.4 0.4 0.49
date-fns/date-fns 0.96 0.98 0.98 0.98 0.98 0.98
request/request 0.88 0.88 0.89 0.92 0.85 0.89
ReactiveX/rxjs 0.96 0.96 0.97 0.97 0.97 0.98
ctripcorp/apollo 0.39 0.49 0.45 0.42 0.48 0.49
laravel/framework 0.78 0.47 0.3 0.47 0.36 1.0
nlohmann/json 0.0 0.0 1.0 1.0 0.99 1.0
rapid7/metasploit-framework 0.56 0.5 0.94 0.92 0.35 0.81
mobxjs/mobx 1.0 0.92 0.93 0.93 0.93 0.93
sentsin/layui 0.3 0.31 0.3 0.3 0.3 0.3
vim/vim 0.58 0.58 0.58 0.6 0.61 0.62
JedWatson/react-select 0.95 0.39 0.95 0.81 0.94 0.94
GoogleChrome/lighthouse 0.62 0.86 0.89 0.89 0.27 0.87
mitmproxy/mitmproxy 0.99 0.99 0.97 0.97 0.97 0.97
Tencent/wepy 0.86 0.86 0.6 0.6 0.6 0.59
mochajs/mocha 0.77 0.88 0.88 0.88 0.88 0.88
psf/black 0.96 0.96 0.96 0.96 0.96 0.96
paularmstrong/normalizr 1.0 1.0 1.0 1.0 1.0 1.0
Continued on next page
83

Tabela 16 – continued from previous page


Project/Version 1 2 3 4 5 6
tornadoweb/tornado 0.59 0.85 0.85 0.85 0.84 0.86
curl/curl 0.0 0.74 0.75 0.73 0.74 0.74
go-kit/kit 0.81 0.79 0.79 0.79 0.79 0.78
jlmakes/scrollreveal 0.45 0.36 0.35 0.33 0.35 0.36
labstack/echo 0.78 0.92 0.84 0.96 0.95 0.95
nsqio/nsq 0.65 0.71 0.71 0.62 0.62 0.63
facebook/rocksdb 0.7 0.56 0.95 0.52 0.82 0.83
lovell/sharp 0.96 0.96 0.97 0.97 0.97 0.97
stedolan/jq 0.85 0.85 0.85 0.85 0.85 0.86
keon/algorithms 0.88 0.91 0.71 0.72 0.71 0.72
avajs/ava 0.95 0.97 0.97 0.97 0.97 0.97
jaredhanson/passport 0.84 1.0 0.31 1.0 1.0 1.0
eslint/eslint 0.99 0.99 0.99 0.99 0.99 0.99
nicolargo/glances 0.29 0.28 0.27 0.27 0.27 0.24
fastify/fastify 0.99 0.98 0.97 0.95 0.95 0.96
SnapKit/Masonry 0.63 1.0 1.0 1.0 0.97 0.97
uglide/RedisDesktopManager 0.51 0.51 0.51 0.45 0.44 0.44
tqdm/tqdm 1.0 0.96 1.0 0.99 1.0 1.0
graphql/graphql-js 0.99 0.99 0.99 0.99 0.99 0.99
npm/npm 0.61 0.85 0.86 0.86 0.86 0.86
celery/celery 0.5 0.92 0.92 0.92 0.92 0.92
HelloZeroNet/ZeroNet 0.53 0.54 0.57 0.55 0.54 0.53
nuysoft/Mock 0.8 0.79 1.0 1.0 1.0 1.0
mysqljs/mysql 0.96 0.78 0.96 0.97 0.97 0.97
chalk/chalk 1.0 1.0 1.0 1.0 1.0 1.0
websockets/ws 0.93 0.97 0.98 0.98 0.97 0.99
svg/svgo 0.94 0.94 0.94 0.95 0.94 0.94
hubotio/hubot 0.73 0.74 0.75 0.75 0.85 0.75
apollographql/apollo-client 0.9 0.93 0.94 0.96 0.97 0.97
apache/flink 0.49 0.81 0.24 0.78 0.84 0.55
dgraph-io/dgraph 0.53 0.5 0.56 0.55 0.54 0.5
Continued on next page
84

Tabela 16 – continued from previous page


Project/Version 1 2 3 4 5 6
dvajs/dva 0.7 0.94 0.94 0.94 0.95 0.95
mybatis/mybatis-3 0.81 0.81 0.81 0.81 0.81 0.81
bower/bower 0.63 0.67 0.67 0.67 0.68 0.77
yabwe/medium-editor 0.95 0.95 0.94 0.95 0.95 0.95
openssl/openssl 0.54 0.55 0.56 0.56 0.57 0.57
Tabela 16: Dataset Coveralls - Parte 1/2

Project/Version 7 8 9 10 11 12
vuejs/vue 0.94 0.94 1.0 1.0 1.0 1.0
facebook/react 0.87 0.88 0.88 0.85 0.83 0.81
twbs/bootstrap 0.91 0.91 0.91 0.91 0.91 0.91
flutter/flutter 0.72 0.79 0.82 0.84 0.84 0.83
iluwatar/java-design-patterns 0.88 0.91 0.91 0.9 0.89 0.89
nvbn/thefuck 0.91 0.91 0.91 0.91 0.91 0.92
webpack/webpack 0.9 0.9 0.9 0.9 0.9 0.9
chartjs/Chart.js 0.87 0.88 0.9 0.91 0.91 0.92
expressjs/express 1.0 1.0 1.0 1.0 1.0 1.0
bitcoin/bitcoin 0.61 0.86 0.78 0.03 1.0 0.04
ElemeFE/element 0.88 0.88 0.88 0.87 0.87 0.87
lodash/lodash 1.0 0.99 1.0 0.99 1.0 1.0
gin-gonic/gin 0.93 0.94 0.93 0.94 0.94 0.94
moment/moment 0.95 0.95 0.95 0.95 0.94 0.88
scikit-learn/scikit-learn 0.94 0.94 0.94 0.95 0.95 0.95
jekyll/jekyll 0.87 0.28 0.93 0.43 0.95 1.0
neovim/neovim 0.05 0.62 0.62 0.63 0.63 0.64
scrapy/scrapy 0.87 0.8 0.85 0.71 0.85 0.52
serverless/serverless 0.88 0.89 0.89 0.89 0.87 0.88
nestjs/nest 0.94 0.95 0.95 0.95 0.95 0.94
mermaid-js/mermaid 0.49 0.45 0.47 0.45 0.45 0.45
JuliaLang/julia 0.72 0.95 0.92 0.78 0.81 0.81
hexojs/hexo 0.95 0.95 0.95 0.95 0.95 0.93
Continued on next page
85

Tabela 17 – continued from previous page


Project/Version 7 8 9 10 11 12
gulpjs/gulp 0.98 1.0 1.0 1.0 1.0 1.0
huginn/huginn 0.34 0.88 0.88 0.88 0.88 0.88
videojs/video.js 0.82 0.83 0.83 0.84 0.83 0.83
bumptech/glide 0.77 0.83 0.75 0.83 0.83 0.75
php/php-src 0.87 0.6 0.9 0.9 0.58 0.59
localstack/localstack 0.77 0.77 0.77 0.7 0.7 0.7
ethereum/go-ethereum 0.49 0.51 0.5 0.47 0.47 0.92
preactjs/preact 1.0 1.0 0.98 1.0 1.0 1.0
certbot/certbot 0.99 0.99 0.99 0.99 0.99 0.99
getsentry/sentry 0.67 0.68 0.74 0.52 0.87 0.28
react-boilerplate/react-boilerplate 1.0 1.0 1.0 1.0 1.0 1.0
pingcap/tidb 0.72 0.72 0.72 0.54 0.5 0.67
caolan/async 0.97 0.97 1.0 0.97 0.98 0.98
jashkenas/underscore 0.97 0.97 0.97 0.96 0.95 0.97
skylot/jadx 0.8 0.81 0.75 0.74 0.74 0.74
PowerShell/PowerShell 0.5 0.5 0.5 0.91 0.47 0.73
date-fns/date-fns 0.98 0.97 0.97 0.97 0.98 0.97
request/request 0.89 0.94 0.89 0.89 0.9 0.9
ReactiveX/rxjs 0.98 0.98 0.98 0.98 0.98 0.98
ctripcorp/apollo 0.49 0.47 0.46 0.5 0.5 0.5
laravel/framework 0.94 1.0 0.95 0.4 0.63 0.97
nlohmann/json 1.0 1.0 1.0 1.0 1.0 1.0
rapid7/metasploit-framework 0.45 0.92 0.85 0.85 1.0 0.75
mobxjs/mobx 0.96 0.96 0.96 0.53 0.97 0.96
sentsin/layui 0.3 0.3 0.3 0.29 0.28 0.28
vim/vim 0.62 0.62 0.6 0.65 0.67 0.69
JedWatson/react-select 0.91 0.91 0.9 0.91 0.92 0.92
GoogleChrome/lighthouse 0.84 0.81 0.81 0.81 0.81 0.82
mitmproxy/mitmproxy 0.97 0.96 0.93 0.93 0.96 0.93
Tencent/wepy 0.59 0.59 0.1 0.69 0.69 0.69
mochajs/mocha 0.88 0.89 0.89 0.9 0.9 0.9
Continued on next page
86

Tabela 17 – continued from previous page


Project/Version 7 8 9 10 11 12
psf/black 0.96 0.96 0.96 0.96 0.96 0.96
paularmstrong/normalizr 1.0 1.0 1.0 1.0 1.0 1.0
tornadoweb/tornado 0.86 0.86 0.86 0.85 0.86 0.86
curl/curl 0.74 0.75 0.0 0.75 0.75 0.75
go-kit/kit 0.75 0.77 0.76 0.77 0.77 0.81
jlmakes/scrollreveal 0.34 0.33 0.33 0.28 0.29 0.29
labstack/echo 0.94 0.92 0.91 0.9 0.92 0.81
nsqio/nsq 0.61 0.62 0.63 0.63 0.63 0.63
facebook/rocksdb 0.33 0.52 0.83 0.94 0.42 0.06
lovell/sharp 0.4 0.96 0.97 0.97 0.97 0.97
stedolan/jq 0.85 0.86 0.86 0.86 0.85 0.85
keon/algorithms 0.68 0.68 0.65 0.67 0.75 0.76
avajs/ava 0.97 0.97 0.97 0.97 0.96 0.97
jaredhanson/passport 1.0 1.0 1.0 1.0 1.0 1.0
eslint/eslint 0.99 0.99 1.0 0.99 0.99 1.0
nicolargo/glances 0.23 0.25 0.25 0.26 0.26 0.26
fastify/fastify 0.96 0.96 0.96 0.99 0.99 0.99
SnapKit/Masonry 0.94 0.95 0.0 0.0 0.0 0.0
uglide/RedisDesktopManager 0.43 0.43 0.43 0.43 0.43 0.41
tqdm/tqdm 1.0 0.93 1.0 0.99 0.81 0.93
graphql/graphql-js 0.99 0.99 0.99 0.98 0.98 0.98
npm/npm 0.85 0.88 0.78 0.86 0.86 0.85
celery/celery 0.91 0.91 0.47 0.68 0.9 0.92
HelloZeroNet/ZeroNet 0.55 0.57 0.57 0.57 0.56 0.57
nuysoft/Mock 1.0 1.0 1.0 1.0 1.0 1.0
mysqljs/mysql 0.97 0.97 0.97 0.96 0.96 0.96
chalk/chalk 1.0 1.0 1.0 1.0 1.0 1.0
websockets/ws 0.99 0.99 0.99 0.99 0.99 0.99
svg/svgo 0.95 0.93 0.93 0.93 0.93 0.93
hubotio/hubot 0.75 0.75 0.75 0.75 0.75 0.75
apollographql/apollo-client 0.97 0.96 0.96 0.96 0.96 0.96
Continued on next page
87

Tabela 17 – continued from previous page


Project/Version 7 8 9 10 11 12
apache/flink 0.62 0.63 0.91 0.48 0.77 0.5
dgraph-io/dgraph 0.41 0.44 0.44 0.27 0.52 0.51
dvajs/dva 0.95 0.95 0.94 0.95 0.95 0.95
mybatis/mybatis-3 0.81 0.83 0.83 0.83 0.83 0.83
bower/bower 0.69 0.71 0.87 0.85 0.85 0.85
yabwe/medium-editor 0.95 0.95 0.82 0.94 0.95 0.95
openssl/openssl 0.57 0.58 0.58 0.59 0.57 0.6
Tabela 17: Dataset Coveralls - Parte 2/2
88

APÊNDICE E -- Extração de dados dos


formatos Clover

Neste apêndice está o algoritmo em python utilizado para extração da cobertura em


formato do clover. No qual tem como entrada a estrutura padrão do relatório do clover
de uma versão do projeto e tem como resultado a sua respectiva cobertura.

Listing E.1 : Extração da cobertura em formatos Clover

1 d e f g e t _ p r o j e c t _ c o v e r a g e _ f r o m _ c l o v e r ( r o o t : ElementTree ) −> f l o a t :
coverage : f l o a t = 0
3 p r o j e c t : ElementTree = r o o t . f i n d ( ’ p r o j e c t ’ )
a l l _ f i l e s : L i s t [ ElementTree ] = l i s t ( p r o j e c t . i t e r ( " f i l e " ) )
5 d i c t _ f i l e s : D i c t [ s t r , D i c t ] = {}
#
7 for f i l e in a l l _ f i l e s :
f i l e n a m e : s t r = f i l e . g e t ( ’ path ’ ) o r f i l e . g e t ( ’ name ’ )
9 l i n e s : L i s t [ ElementTree ] = l i s t ( f i l e . i t e r ( ’ l i n e ’ ) )
d i c t _ l i n e s : D i c t [ i n t , b o o l ] = {}
11 #
for l i n e in l i n e s :
13 number : i n t = i n t ( l i n e . g e t ( ’num ’ ) )
type : s t r = l i n e . g e t ( ’ type ’ )
15 coverage_count : b o o l = F a l s e
i f ( type == ’ cond ’ ) :
17 coverage_count = i n t ( l i n e . g e t ( ’ f a l s e c o u n t ’ ) ) > 0 o r i n t (
l i n e . get ( ’ truecount ’ ) ) > 0
else :
19 coverage_count = i n t ( l i n e . g e t ( ’ count ’ ) ) > 0
#
21 i f number not i n d i c t _ l i n e s . k e y s ( ) :
d i c t _ l i n e s [ number ] = coverage_count
23 else :
d i c t _ l i n e s [ number ] = d i c t _ l i n e s [ number ] o r coverage_count
89

25

count_covered_lines : f l o a t = 0
27 #
for covered_line in dict_lines . values () :
29 i f covered_line :
count_covered_lines = count_covered_lines + 1
31

i f l e n ( l i n e s ) == 0 :
33 d i c t _ f i l e s [ filename ] = {
’ covered_lines ’ : 0 ,
35 ’ valid_lines ’ : 0 ,
’ coverage ’ : 1
37 }
else :
39 d i c t _ f i l e s [ filename ] = {
’ covered_lines ’ : count_covered_lines ,
41 ’ valid_lines ’ : len ( dict_lines ) ,
’ coverage ’ : count_covered_lines / len ( d i c t _ l i n e s )
43 }

45 count_valid_lines : f l o a t = 0
count_covered_lines : f l o a t = 0
47 for f i l e in d i c t _ f i l e s . values () :
count_covered_lines = count_covered_lines + f i l e [ ’ covered_lines ’ ]
49 count_valid_lines = count_valid_lines + f i l e [ ’ valid_lines ’ ]
#
51 coverage = count_covered_lines / count_valid_lines
return coverage
90

APÊNDICE F -- Algoritmo para obtenção dos


dados

Neste apêndice está o algoritmo em R utilizado para extração das informações presen-
tes no csvs das coberturas dos projetos. Utilizamos o RScript (TEAM, 2020) para executar
esse algoritmo.

Listing F.1 : Extração das informações das bases de dados

main <− f u n c t i o n ( ) {
2

a r g s <− commandArgs ( t r a i l i n g O n l y = TRUE)


4

i f ( l e n g t h ( a r g s ) == 2 ) {
6 r e q u i r e d P a c k a g e s = c ( " proxy " , " g g p l o t 2 " , "dtw" , " f a c t o e x t r a " , " d t w c l u s t " ,
" cluster ")
i n s t a l l _packpages ( r e q u i r e d P a c k a g e s )
8 c r e a t e_dtw ( a r g s [ 1 ] , a r g s [ 2 ] )
} else {
10 parameter_e r r o r ( )
}
12 }

14 i n s t a l l _packpages <− f u n c t i o n ( packpages ) {


f o r ( packpage i n packpages ) {
16 i f ( packpage %i n% rownames ( i n s t a l l e d . p a c k a g e s ( ) ) == FALSE) {
i n s t a l l . p a c k a g e s ( packpage )
18 }
l i b r a r y ( packpage , c h a r a c t e r . o n l y = TRUE)
20 }
}
22

c r e a t e_dtw <− f u n c t i o n ( f i l e n a m e , s e e d ) {
24
91

c a t ( p a s t e 0 ( p a s t e ( " Reading " , f i l e n a m e ) , " . . . " ) )


26

i n s t a n c e s <− r e a d . c s v ( f i l e = f i l e n a m e , h e a d e r = TRUE)
28

c a t ( "OK\n" )
30

cat ( paste0 ( paste ( " Setting seed " , seed ) , " . . . " ) )
32

set . seed ( seed )


34

c a t ( "OK\n" )
36

38 name <− s t r s p l i t ( f i l e n a m e , " . c s v " ) [ [ 1 ] ]

40 c a t ( "Get b e s t number o f c l u s t e r s : \ n" )

42 c a t ( " I n i t gap method . . . " )

44 gap_s t a t <− clusGap ( i n s t a n c e s [ , 2 : n c o l ( i n s t a n c e s ) ] , FUN = kmeans , n s t a r t


= 2 5 , i t e r . max = 5 0 , K. max = nrow ( i n s t a n c e s ) −1, B = 5 9 9 )

46 c l u s t e r s <− maxSE( f = gap_s t a t $Tab [ , " gap " ] , SE . f = gap_s t a t $Tab [ , "SE .
sim " ] )

48 ggp <− f v i z_gap_s t a t ( gap_s t a t )


c a t ( "OK\n" )
50

gap_f i l e n a m e <− p a s t e 0 ( p a s t e 0 ( name , "_gap " ) , " . png" )


52 png ( gap_f i l e n a m e , width = 1 4 4 0 )
p l o t ( ggp )
54 dev . o f f ( )
c a t ( " Save gap c h a r t i n " )
56 c a t ( gap_f i l e n a m e )
c a t ( " \n" )
58

c a t ( " Best c l u s t e r number : " )


60 cat ( c l u s t e r s )
c a t ( " \n" )
62

c a t ( " I n i t t s c l u s t method . . . " )


64
92

t s c l u s t <− t s c l u s t ( i n s t a n c e s [ , 2 : n c o l ( i n s t a n c e s ) ] , type = " f u z z y " , s e e d=


seed , k=c l u s t e r s , d i s t a n c e="dtw" )
66 c a t ( "OK\n" )

68 t s c l u s t_f i l e n a m e <− p a s t e 0 ( p a s t e 0 ( p a s t e 0 ( name , "_t s c l u s t_" ) , c l u s t e r s ) , " .


png" )

70 gg <− p l o t ( t s c l u s t , p l o t = FALSE) + g g p l o t 2 : : c o o r d_c a r t e s i a n ( ylim = c


( 0 , 1 ) , xlim = c ( 0 , n c o l ( i n s t a n c e s ) −1) ) + g g p l o t 2 : : l a b s ( t i t l e = " C l u s t e r s
" ) + theme ( p a n e l . s p a c i n g = u n i t ( 2 , " l i n e s " ) )

72 png ( t s c l u s t_f i l e n a m e , h e i g h t = 9 6 0 , width = 9 6 0 )


p l o t ( gg )
74 dev . o f f ( )

76 c a t ( " Save t s c l u s t c h a r t i n " )


c a t ( t s c l u s t_f i l e n a m e )
78 c a t ( " \n" )

80 cat ( " Instance c l u s t e r s : " )


cat ( t s c l u s t @ c l u s t e r )
82 c a t ( " \n" )
}
84

parameter_e r r o r <− f u n c t i o n ( ) {
86 c a t ( "ERROR: Quantidade e r r a d a de e n t r a d a s ( Deve s e r 3 ) \n" )
c a t ( " Entrada 1 − Nome d e s t e a r q u i v o \n" )
88 c a t ( " Entrada 2 − Nome do a r q u i v o . c s v a s e r u t i l i z a d o \n" )
c a t ( " Entrada 3 − I n t e i r o com v a l o r da semente \n" )
90 c a t ( "Ex : R s c r i p t dtw .R n o c i_p r o j e c t s . c s v 123 \n" )
}
92

main ( )

Você também pode gostar