COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade...

101
UNIVERSIDADE FEDERAL FLUMINENSE RODRIGO AGAPE VIEIRA MAGINA COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE UMA APLICAÇÃO. TÉCNICAS E FERRAMENTAS PARA DESENVOL- VER UM SOFTWARE SEGURO E ESTÁVEL Niterói 2017

Transcript of COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade...

Page 1: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

UNIVERSIDADE FEDERAL FLUMINENSE

RODRIGO AGAPE VIEIRA MAGINA

COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE UMA APLICAÇÃO. TÉCNICAS E FERRAMENTAS PARA DESENVOL-

VER UM SOFTWARE SEGURO E ESTÁVEL

Niterói 2017

Page 2: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

RODRIGO AGAPE VIEIRA MAGINA

COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE UMA APLICAÇÃO. TÉCNICAS E FERRAMENTAS PARA DESENVOL-

VER UM SOFTWARE SEGURO E ESTÁVEL

Trabalho de Conclusão de Curso subme-

tido ao Curso de Tecnologia em Siste-

mas de Computação da Universidade

Federal Fluminense como requisito par-

cial para obtenção do título de Tecnólogo

em Sistemas de Computação.

Orientadora: HELGA DOLORICO BALBI

NITERÓI

2017

Page 3: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

Ficha Catalográfica elaborada pela Biblioteca da Escola de Engenharia e Instituto de Computação da UFF

M194 Magina, Rodrigo Agape Vieira

Como reduzir o número de bugs e vulnerabilidades de uma

aplicação : técnicas e ferramentas para desenvolver um software

seguro e estável / Rodrigo Agape Vieira Magina. – Niterói, RJ :

[s.n.], 2017.

100 f.

Projeto Final (Tecnólogo em Sistemas de Computação) –

Universidade Federal Fluminense, 2017.

Orientador: Helga Dolorico Balbi.

1. Desenvolvimento de software. 2. Engenharia de software. I.

Título.

CDD 005.1

Page 4: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

RODRIGO AGAPE VIEIRA MAGINA

COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE UMA APLICAÇÃO. TÉCNICAS E FERRAMENTAS PARA DESENVOL-

VER UM SOFTWARE SEGURO E ESTÁVEL

Trabalho de Conclusão de Curso subme-

tido ao Curso de Tecnologia em Siste-

mas de Computação da Universidade

Federal Fluminense como requisito par-

cial para obtenção do título de Tecnólogo

em Sistemas de Computação.

Niterói, 5 de Junho de 2017.

Banca Examinadora:

_________________________________________

Profa Helga Dolorico Balbi, Msc. – Orientadora

UFF – Universidade Federal Fluminense

_________________________________________

Prof. Jean de Oliveira Zahn, Msc. – Avaliador

UFF – Universidade Federal Fluminense

Page 5: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

Dedico esse trabalho a minha companheira

Suelen Alves, que mesmo nos momentos di-

fíceis sempre esteve ao meu lado me dando

força para que sempre seguisse em frente.

Sem você eu não teria conseguido. Aos

meus pais, meus verdadeiros mestres, obri-

gado pelo apoio, carinho e amor.

Page 6: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

AGRADECIMENTOS

A Deus, que sempre iluminou a minha cami-

nhada.

A minha Orientadora Helga Dolorico Balbi pe-

lo suporte e atenção.

A todos meus familiares pelo apoio, carinho e

paciência.

A todos que acreditaram em mim, o meu mui-

to obrigado.

Page 7: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

“Força, foco e fé”.

Page 8: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

RESUMO

Cada vez mais é comum usuários reclamarem de instabilidade em aplicações ou a mídia divulgar notícias sobre vulnerabilidades ou vazamentos de dados privados em algum tipo de software. Tendo em vista estas questões, ao longo dos anos medidas foram estudadas para aprimorar o desenvolvimento de software. Este trabalho apre-senta abordagens para melhorar a qualidade da aplicação, através da redução das suas falhas e vulnerabilidades. As abordagens que serão apresentadas foram retira-das de referências bibliográficas e artigos. Verificou-se que, através das técnicas descritas, é possível reduzir os problemas apresentados, deixando o software mais robusto. Porém, apesar de as abordagens contribuírem para o aumento da qualida-de do software, ainda será necessário um aprofundamento em pesquisas para che-gar ao software perfeito.

Palavras-chaves: qualidade de software, desenvolvimento de software, programa-

ção de software, correção de bugs, falha e brecha.

Page 9: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

ABSTRACT

More and more users are complaining about instability in applications or the media are releasing news about vulnerabilities or private data leaks in some type of software. Given these issues, solutions have been studied over the years to improve software development. This work presents approaches to improve the quality of applications, through the reduction of its failures and vulnerabilities. The approaches that will be presented have been taken from bibliographical references and articles. It was verified that through the presented techniques it is possible to reduce the target problems, making the software more robust. But, although the approaches contribute to the increase of the quality of the software, it will still be necessary to deepen in researches to arrive at the perfect software.

Key words: software quality, software development, bugs, fix, failure and hack.

Page 10: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

LISTA DE ILUSTRAÇÕES

Figura 1: Exemplos de arquiteturas monolítica (à esquerda) e de micro serviços (à

direita) [28]. ............................................................................................................... 31

Figura 2: Exemplo baixo nível de arquitetura micro serviços (à esquerda) e

arquitetura monolítica (à direita) [29] ......................................................................... 32

Figura 3: Exemplo de pirâmides de automação. [45] ................................................ 51

Figura 4: Exemplo de formato de user story no BDD ................................................ 58

Figura 5: Exemplo de formato de critério de aceitação no BDD ............................... 59

Figura 6: Exemplo do painel do SonarQube [70] ...................................................... 69

Figura 7: Exemplo do widget de bugs potencias e regras de código ........................ 70

Figura 8: Exemplo do widget de cobertura e testes .................................................. 71

Figura 9: Exemplo do widget de comentário ............................................................. 72

Figura 10: Exemplo do widget de duplicação de código ........................................... 73

Figura 11: Exemplo do widget de arquitetura e design ............................................. 74

Figura 12: Exemplo do widget de complexibilidade .................................................. 75

Figura 13: Exemplo da pirâmide de Maslow. [81] ..................................................... 84

Page 11: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

LISTA DE ABREVIATURAS E SIGLAS

API – Application Programming Interface.

BDD – Behavior-Driven Design

CPU – Central Processing Unit

CVE – Common Vulnerabilities and Exposures.

DDD – Domain Driven Design

DSL – Domain-Specific Language

GUI – Graphical User Interface.

IDE – Integrated Development Environment

IEEE - Institute of Electrical and Electronics Engineers

ROI – Return on Investment.

RUP – Rational Unified Process

TDD – Test Driven Development.

UI – User Interface

XP – Extreme Programming

Page 12: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

12

SUMÁRIO

RESUMO ..................................................................................................................... 8

ABSTRACT ................................................................................................................. 9

LISTA DE ILUSTRAÇÕES ......................................................................................... 10

LISTA DE ABREVIATURAS E SIGLAS ...................................................................... 11

1 INTRODUÇÃO ................................................................................................... 13

2 HISTÓRICO ....................................................................................................... 15

3 ARQUITETURA E IMPLEMENTAÇÃO .............................................................. 23

4 REVISÕES DE SOFTWARE .............................................................................. 36

5 TESTES ............................................................................................................. 42

6 MÉTODOS FORMAIS ........................................................................................ 64

7 ABORDAGENS NÃO TÉCNICAS ...................................................................... 81

CONCLUSÕES E TRABALHOS FUTUROS ............................................................. 88

REFERÊNCIAS BIBLIOGRÁFICAS .......................................................................... 90

Page 13: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

13 13

1 INTRODUÇÃO

A demanda por qualidade é um fator que está sendo perseguido por todas

as áreas, não apenas pela engenharia de software. Comumente, empreendedores

querem oferecer um produto ou serviço de qualidade ao cliente. A qualidade na en-

genharia de software é obtida pela criação de software estável, fácil de usar, seguro,

íntegro e que atenda bem ao usuário final e aos seus objetivos finais. Um software

de qualidade é capaz de oferecer serviços de comunicação, segurança, localização,

entretenimento, além de oferecer competividade entre empresas.

De forma geral, quando um software deixa de funcionar ou apresenta

qualquer tipo de falha, as consequências geram transtornos sociais e econômicos.

Um problema gerado por uma falha de software pode deixar milhões de pessoas

sem comunicação, podem fazer bancos ficar fora do ar e seus clientes sem dinheiro.

Isso tudo devido a uma falha, também conhecida como bug1. Essas falhas também

podem ser exploradas por pessoas ou empresas mal-intencionadas, utilizando bre-

chas ou vulnerabilidades nos sistemas para obter informações privadas, recursos

monetários ou simplesmente gerar caos.

Diante de todos os fatos, será que é possível construir um software segu-

ro e estável? A engenharia de software busca essas metas há anos através de pes-

quisas, metodologias e conscientização, mas, devido à complexidade, ainda é um

problema nos dias atuais. Até termos coloquiais são utilizados na literatura para dar

ênfase ao tamanho do problema, como a expressão “bala de prata”, que faz analo-

gia a um software sem problemas.

Tendo em vista que eliminar completamente bugs e vulnerabilidades é um

trabalho complexo, o objetivo e foco deste trabalho será apresentar soluções desen-

volvidas para diminuir a incidência de falhas e vulnerabilidades, através de aborda-

gens técnicas e não técnicas na criação de um software. Nesse contexto, a propos-

1 É um erro em um programa de computador ou sistema que produz um resultado incorreto ou ines-perado.

Page 14: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

14

ta de trabalho visa apresentar metodologias, ferramentas e conceitos que possibili-

tam a criação de softwares de maior qualidade.

Para o desenvolvimento do trabalho, foram utilizadas referências biblio-

gráficas, artigos e publicações científicas. Devido à complexidade da questão, di-

versas referências de diversos autores foram consultadas. As ferramentas apresen-

tadas, em sua grande maioria, são de código aberto e não possuem custos, deixan-

do o estudo mais fácil de ser aplicado de forma prática.

Este trabalho de conclusão do curso está estruturado em 7 capítulos que

apresentam os seguintes conteúdos: o segundo Capítulo apresenta uma abordagem

histórica de bugs e vulnerabilidades que ficaram famosos devido ao seu prejuízo,

aumentando o entendimento e urgência ao problema. Além disso, mostra um resu-

mo das metodologias e processos de software; no terceiro Capítulo é apresentada

uma arquitetura de software para se construir uma aplicação mais robusta com me-

nor complexidade e maior resistência a falhas, e também são descritas característi-

cas e sugestões de linguagens de programação com recursos para diminuir possí-

veis falhas em uma aplicação; o quarto Capítulo é dedicado às revisões de software,

abordagem importante para aumentar a qualidade da aplicação, tornando-a mais

segura além de aumentar o conhecimento técnico do time de desenvolvedores; no

Capítulo cinco, são mostradas metodologias para aumentar a qualidade dos testes

de software, deixando claro os benefícios da sua automatização. Além disso, des-

creve como realiza-los e que ferramentas utilizar; no sexto Capítulo, é descrito como

utilizar ferramentas de análise estática e dinâmica para detectar possíveis bugs e

vulnerabilidades. Também são descritas ferramentas especializadas em buscar bre-

chas de segurança; no sétimo Capítulo é apresentada outra visão da engenharia de

software. Como o desenvolvimento de software envolve pessoas, o objetivo deste

capítulo é mostrar como alguns fatores pessoais como por exemplo a motivação afe-

ta na qualidade da aplicação. Por fim, são apresentadas as conclusões e ideias para

trabalhos futuros.

Page 15: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

15

2 HISTÓRICO

Bugs em computadores existem desde a criação do computadores elétri-

cos, e através da historia ficará claro a necessidade de atenção ao assunto. Nas se-

ções seguintes, serão mostrados a historia da definição do termo bug e vulnerabili-

dade e prejuízos causados. E também uma breve descrição da evolução das meto-

dologias no processo de desenvolvimento de software.

2.1 BUG

Em 09 de setembro de 1947, o computador Mark II na Universidade de

Harvard (EUA) quebrou. Após a inspeção, os engenheiros diagnosticaram a causa -

uma mariposa havia entrado na máquina, talvez atraída pela luz e calor, e causou

um curto circuito nos relés. Os técnicos registraram o incidente em seu caderno com

uma entrada às 15:45 em que eles anexaram o bug na página com fita adesiva e

observaram: "Primeiro caso real de bug encontrado". Hoje a folha é mantida no Mu-

seu Nacional de História Americana da Smithsonian Institution em Washington [1] [2].

Apesar de a história ser muito popular, como qualquer outra história con-

tada, foi distorcida pelos anos. Não foi esse episódio que descreveu a palavra "bug"

para erros de computadores. A verdade é que bem antes desse incidente a palavra

já era utilizada para referenciar mal função em máquinas, como foi evidenciada pe-

las notas do inventor Thomas Edison em 1870. Apesar de fontes do Institute of Elec-

trical and Electronics Engineers (IEEE) terem dado o crédito do termo à Thomas

Edison, este se tornou popular pelos engenheiros de Harvard na era do Mark II [3].

Grace Hopper deveria ter ganho o crédito pela introdução do termo na

linguagem da computação e, em particular, a programação. Ela descreveu os even-

tos que cercam o infame inseto como segue:

When we were debugging Mark II, it was over in another building, and the

windows had no screens on them and we were working on it at night, of

Page 16: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

16

course, and all the bugs in the world came in. And, one night she [Mark II]

conked out and we went to look for the bug and found an actual large moth,

about four inches wing span, in one of the relays beaten to death, and we

took it out and put it in the log book and pasted Scotch tap over it. [4]

No entanto uma coisa pode ser afirmada: O incidente serviu para popula-

rizar o uso da expressão "bug" sendo aplicada aos computadores, que hoje em dia é

o principal uso do termo. E também não há dúvidas sobre quem foi o responsável

por isso: Grace Hopper, matemática nascida em Nova York em 1906, soldado da

Marinha dos EUA e pioneira em tecnologia da informação.

Mais de 60 anos depois, os bugs ainda fazem parte da nossa realidade, e

não há previsão para a solução deste tipo de problema. Eles não habitam apenas

nossos sistemas operacionais e aplicativos - hoje eles se escondem dentro de nos-

sos telefones celulares, marca-passos, usinas, equipamentos médicos e até mesmo

em nossos carros. Seguem alguns exemplos de bugs ocorridos que também entra-

ram para a história [5] [6] [7]:

- 1962 - Mariner I, sonda espacial. Um bug no software de voo faz com que o

foguete se desvie do caminho pretendido no lançamento. O controle da mis-

são destruiu o foguete sobre o Oceano Atlântico. A investigação do acidente

descobriu que uma fórmula escrita em papel a lápis foi incorretamente trans-

crita em código de computador, fazendo com que o computador calculasse er-

roneamente a trajetória do foguete.

- 1982 - Gasoduto soviético. Funcionários que trabalharam para a Agência

Central de Inteligência alegaram plantar um bug em um sistema de computa-

dor canadense comprado para controlar o gasoduto transiberiano. Os soviéti-

cos obtiveram o sistema como parte de um amplo esforço para comprar ou

roubar secretamente tecnologia sensível dos EUA. O evento resultante foi a

maior explosão não-nuclear da história do planeta.

- 1985-1987 - Therac-25. Era uma máquina de radioterapia controlada por

computador, muito moderna para sua época, por permitir a utilização do

mesmo equipamento para a aplicação de diversas doses de radiação nos pa-

cientes. Houve uma série de pelo menos 6 acidentes entre 1985 e 1987, nos

quais os pacientes receberam overdose de radiação. Pelo menos cinco mor-

Page 17: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

17

tes aconteceram devido aos acidentes, causados por um erro de condição de

corrida2 no software que controlava a máquina.

- 2000 - O bug do Milênio. No século passado, os desenvolvedores de software

nunca tinham pensado que seu código e criações sobreviveriam para o novo

milênio. Por esta razão, muitos assumiram que escrever "19" antes da variá-

vel "ano" era um desperdício desnecessário de memória. A maioria decidiu

omitir esses dois dígitos. Bilhões de dólares foram gastos a fim de atualizar os

sistemas de computador em todo o mundo.

- 2012 - Knight Capital. Uma das maiores corretoras de ações do mercado

americano lutou para permanecer à tona depois que um bug de software pro-

vocou uma perda de US $ 440 milhões em apenas 30 minutos. As ações da

empresa perderam 75% em dois dias depois que uma falha no software inun-

dou o mercado com transações indevidas.

2.2 VULNERABILIDADE

Em 2 de Novembro de 1988, o primeiro worm3 da Internet (o chamado

Morris Worm) infectou entre 2.000 e 6.000 computadores em menos de um dia,

aproveitando-se de uma simples vulnerabilidade chamada buffer overflow4. O código

específico era uma função na rotina de biblioteca de entrada/saída padrão chamada

gets() projetada para obter uma linha de texto sobre a rede. Infelizmente, a instrução

não tinha condição para limitar a sua entrada, e uma entrada excessivamente gran-

de permitia que o worm assumisse qualquer máquina [8] [9].

2 Falha no sistema onde o resultado do processo depende da sequencia ou sincronia de processos simultâneos. 3 São programas de computadores que se replicam de sistema para sistema sem a utilização de ar-quivos existentes. 4 Defeito ocasionado quando o programa de computador recebe mais dados que esteja preparado a receber, causando o corrompimento dos dados, travamento da aplicação, ou violação de segurança. Uma vez explorada pode permitir mudar o comportamento do programa e executar outras instruções permitindo ao atacante controlar o sistema.

Page 18: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

18

Há muitas definições diferentes do termo "vulnerabilidade" abrangendo

várias combinações de conceitos, incluindo conhecimento, ataques, exploração, ris-

co, intenção, ameaça, escopo e tempo de introdução. Seguem algumas definições:

1. Em Matt Bishop e Dave Bailey [10]:

A computer system is composed of states describing the current configura-

tion of the entities that make up the computer system. The system computes

through the application of state transitions that change the state of the sys-

tem. All states reachable from a given initial state using a set of state transi-

tions fall into the class of authorized or unauthorized, as defined by a securi-

ty policy. In this paper, the definitions of these classes and transitions is con-

sidered axiomatic.

A vulnerable state is an authorized state from which an unauthorized state

can be reached using authorized state transitions. A compromised state is

the state so reached. An attack is a sequence of authorized state transitions

which end in a compromised state. By definition, an attack begins in a vul-

nerable state.

A vulnerability is a characterization of a vulnerable state which distinguishes

it from all non- vulnerable states. If generic, the vulnerability may character-

ize many vulnerable states; if specific, it may characterize only one...

2. Em Data & Computer Security Dictionary of Standards, Concepts, and Terms

[11]:

1) In computer security, a weakness in automated systems security proce-

dures, administrative controls, Internet controls, etc., that could be exploited

by a threat to gain unauthorized access to information of to disrupt critical

processing. 2) In computer security, a weakness in the physical layout, or-

ganization, procedures, personnel, management, administration, hardware

or software that may be exploited to cause harm to the ADP system activity.

The presence of vulnerability does not itself cause harm. A vulnerability is

merely a condition or set of conditions that may allow the ADP system or ac-

tivity to be harmed by an attack. 3) In computer security, any weakness or

aw existing in a system. The attack or harmful event, or the opportunity

available to a threat agent to mount that attack.

Page 19: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

19

Diante dessas definições podemos resumidamente afirmar que uma vul-nerabilidade é uma fraqueza em um produto que pode permitir que um invasor

comprometa a integridade, a disponibilidade ou a confidencialidade de um produto.

Algumas outras vulnerabilidades também entraram para história como [12]:

- OpenSSL Heartbleed Vulnerability (CVE-2014-0160) - O Heartbleed Bug na

biblioteca criptográfica OpenSSL expôs websites e softwares baseados em

SSL a ataques que permitiriam roubo de informações em uma escala sem

precedentes. Cerca de um terço de todos os principais sites foram considera-

dos vulneráveis à questão quando o Heartbleed foi divulgado pela primeira

vez em abril de 2014.

- DNS Cache Poisoning: Kaminsky Bug (CVE-2008-1447) - A descoberta de

2008 de Dan Kaminsky desencadeou a preocupação generalizada com a se-

gurança da Internet, levou a uma campanha de patches simultâneos sem

precedentes, por dezenas de fornecedores de tecnologia em todo o mundo. A

falha fundamental, no nível do protocolo DNS, oferecia aos atacantes uma

maneira relativamente direta de usar dados falsificados para redirecionar o

tráfego da Web para os destinos de sua escolha.

- GNU Bash Remote Code Execution Vulnerability: Shellshock (CVE-2014-6271)

- A vulnerabilidade do Shellshock foi um bug que competiu com o Heartbleed

pela duvidosa distinção de ser o pior de todos, afetou a maioria das versões

do Unix, Linux e Mac OS X e permitiu que os invasores executassem códigos

maliciosos em sistemas vulneráveis. Alguns analistas estimaram que cerca

de meio bilhão de dispositivos conectados à Internet e servidores web esta-

vam vulneráveis ao problema no momento em que o bug foi revelado, incluin-

do servidores web, dispositivos Android, OpenBSD, clientes DHCP, servidores

SSH e dispositivos Mac OSX.

Grandes avanços foram feitos na definição de vulnerabilidades de softwa-

res, catalogando-os e compreendendo-os, e também na educação da comunidade

de software, patches de correção e defeitos. Vulnerabilidades significativas são en-

contradas rotineiramente. Muitas delas foram descobertas há anos, mas as corre-

Page 20: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

20

ções não são aplicadas frequentemente. É necessária uma nova abordagem com

uma maior conscientização da comunidade de software.

2.3 METODOLOGIAS DE DESENVOLVIMENTO

Modelos de processos de desenvolvimento foram originalmente propostos

para trazer ordem ao caos no desenvolvimento de software. A história indica que

estes modelos trouxeram uma certa quantidade de estruturas úteis para o trabalho

de engenharia de software e forneceram um roteiro eficaz para equipes de software.

Seguem alguns modelos para exemplificar [13]:

2.3.1 Modelo Cascata

O modelo cascata consiste nas seguintes fases:

- Especificação de requisitos (análise de requisitos).

- Design de software.

- Implementação e Integração.

- Teste (ou Validação).

- Implantação (ou instalação).

- Manutenção.

Tradicionalmente, com esse modelo, só se pode começar a próxima fase

quando a fase anterior for concluída, sendo o paradigma mais antigo para a enge-

nharia de software.

Page 21: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

21

2.3.2 Modelo Incremental

O desenvolvimento incremental corta a funcionalidade do sistema em

porções. Em cada porção, uma fatia de funcionalidade é entregue através de traba-

lho interdisciplinar, desde os requisitos até a implantação. As interações são agrupa-

das em fases: início, elaboração, construção e transição. A filosofia incremental é

também usada para todos os processos ágeis (Seção 2.3.3).

2.3.3 Desenvolvimento Ágil

É um grupo de métodos de desenvolvimento de software baseados em

desenvolvimento interativo e incremental.

As características desse tipo de processo de desenvolvimento são:

- Abordagem iterativa.

- Incremental: Software disponível para clientes a cada 2-4 semanas.

- Equipes auto organizadas e multifuncionais.

- Refatoração. Prática que busca aprimorar o design e legibilidade de um códi-

go.

Exemplos de métodos ágeis populares:

- Scrum. Metodologia ágil associada a gestão de projetos onde são divididos

em ciclos chamados de Sprints.

- Programação eXtreme (XP). Metodologia que compartilha as práticas do ma-

nifesto ágil com maior foco nas atividades de desenvolvimento de software.

Page 22: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

22

2.4 MELHORIA DO PROCESSO DE SOFTWARE

A existência de um processo de software não garante que o software será

entregue a tempo, que satisfará as necessidades do cliente ou que exibirá as carac-

terísticas técnicas que levarão a características de qualidade de longo prazo. Os

padrões de processos devem ser combinados com uma sólida prática de engenharia

de software. Além disso, o processo em si pode ser avaliado para garantir que ele

atende a um conjunto de critérios de processo básicos que se mostraram essenciais

para uma engenharia de software bem-sucedida.

Várias abordagens diferentes para avaliação e melhoria de processos de

software têm sido propostas nas últimas décadas, conforme abaixo [14]:

- SCAMPI: Prova um modelo de avaliação de processo de cinco etapas que in-

corpora cinco fases: iniciando, diagnosticando, estabelecendo, agindo e

aprendendo. O método SCAMPI utiliza o SEI CMMI como base para avalia-

ção.

- CBA IPI: Fornece uma técnica de diagnóstico para avaliar a maturidade relati-

va de uma organização de software; utiliza o SEI CMM como base para a

avaliação.

- SPICE (ISO / IEC15504): Um padrão que define um conjunto de requisitos

para a avaliação de processos de software. A intenção do padrão é auxiliar as

organizações no desenvolvimento de uma avaliação objetiva da eficácia de

qualquer processo de software definido.

- ISO 9001: 2000 para Software. Um padrão genérico que se aplica a qualquer

organização que queira melhorar a qualidade geral dos produtos, sistemas ou

serviços que ela fornece. Portanto, o padrão é diretamente aplicável a organi-

zações de software e empresas.

As técnicas mostradas nos próximos capítulos são práticas da metodolo-

gia ágil, mas podem ser aplicadas a qualquer metodologia escolhida para o projeto,

visando o aumento de qualidade do software.

Page 23: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

23

3 ARQUITETURA E IMPLEMENTAÇÃO

A arquitetura de um software é um processo criativo onde se cria uma or-

ganização que irá satisfazer os requisitos funcionais e não funcionais de um sistema.

Por ser um processo criativo, as atividades dentro do processo dependem do tipo de

sistema que está sendo desenvolvido e dos requisitos específicos para ele. Este

processo é de grande importância porque afeta o desempenho, robustez, distribui-

ção e manutenção de um sistema [15].

Nas seções a seguir serão mostradas propostas de arquitetura e design,

visando manutenção, segurança e proteção do sistema, assim como linguagens de

programação para implementação da arquitetura apresentada.

3.1 DESIGN DE SOFTWARE

Um design de software é uma representação, ou modelo do software a

ser construído. Seu objetivo é permitir aos programadores implementar os requisitos

designando as partes projetadas da implementação. É um conjunto de documentos

contendo texto e diagramas para servir como a base na qual um aplicativo pode ser

totalmente programado. Um projeto de software completo deve ser tão explícito que

um programador poderia codificar o aplicativo dele sem a necessidade de quaisquer

outros documentos. Quando o modelo é construído, ele poderá ser avaliado quanto

à qualidade e melhorado antes que o código seja gerado, sendo o primeiro passo

para a qualidade do software [16].

Uma das abordagens para o design de software é o DDD (Domain-Driven

Design), que será mostrado a seguir.

Page 24: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

24

3.1.1 Domain-Driven Design (DDD)

Inicialmente é necessário que se entenda corretamente o que é um domí-

nio de negócio, esse é o coração do DDD. Domínio de negócio refere-se à área de

assunto para qual se está criando um software. Por exemplo, ao escrever um sof-

tware para a indústria de saúde para registrar o tratamento do paciente, não é impor-

tante aprender a se tornar um médico. O que é importante entender é a terminologia

do setor de saúde, como os departamentos diferentes veem os pacientes e os cui-

dados, quais informações os médicos coletam e o que fazem com elas.

A fim de se criar um bom software, é necessário saber para que o softwa-

re servirá. Não se pode criar um sistema de registro de tratamento, a menos que

tenha uma boa compreensão do que é o registro de tratamento para a indústria de

saúde, ou seja, é preciso entender o seu domínio. Quem possui o conhecimento so-

bre o correto registro do tratamento do paciente, não é o desenvolvedor, nem o ar-

quiteto, nem o analista de software, e sim quem vai utilizar o sistema. Ele saberá de

todos os detalhes, regras de negócio e questões possíveis. É aqui que deve come-

çar a modelagem do software, pelo domínio [17].

Há um esforço para produzir um desenvolvimento de qualidade e evitar a

entrega de software com um número fatal de bugs. No entanto, mesmo produzindo

um software completamente livre de bugs, não significa que atenderá ao negócio. O

modelo de software e a forma como o software expressa a solução para a meta de

negócios que está sendo procurada, têm que estar alinhados com a aplicação de-

senvolvida. Sem ter um bom modelo de domínio para servir de guia, a aplicação ge-

rada não atenderá as estratégias de negócio.

Os projetos de software falham quando não tem o entendimento do domí-

nio de negócios em que se está trabalhando. Digitar não é o gargalo para entregar

um produto, a codificação é a parte mais fácil do desenvolvimento. Fora os requisi-

tos não-funcionais, criar e manter um modelo de software para atender aos casos de

uso é a parte difícil.

A abordagem de desenvolvimento de software denominada Domain-

Driven Design - ou DDD - existe para ajudar os desenvolvedores a terem mais su-

cesso na obtenção de modelos de software de alta qualidade. Quando implementa-

Page 25: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

25

do corretamente, gerará modelos simples que refletirão exatamente o que tem que

ser desenvolvido sem tornar a aplicação complexa. Uma das principais razões pelas

quais o software se torna complexo e difícil de gerenciar é devido à mistura de com-

plexidades de domínio com complexidades técnicas [18].

DDD pode ser visto como o fortalecimento dos conceitos sobre a Orienta-

ção a Objetos. São boas práticas que já existem há anos. A Orientação a Objetos

não se trata apenas de classes, heranças, polimorfismo, encapsulamento, mas tam-

bém engloba as seguintes características [19]:

- Alinhamento do código com o negócio: Ao implementar o DDD é essencial o

contato dos desenvolvedores com os especialistas do domínio.

- Favorece a reutilização: Os blocos que pertencem a um mesmo conceito de

domínio são reaproveitados em vários lugares.

- Redução do acoplamento: As partes que compõem o sistema interagem com

pouca dependência entre os módulos ou classes de objetos com diferentes

conceitos.

- Agnóstico a tecnologia. O mais importante é o entendimento das regras de

negócio e o reflexo do domínio no código. A tecnologia é importante, mas não

é uma preocupação.

Domain-Driven Design (DDD) é uma filosofia de desenvolvimento definida

por Eric Evans em seu trabalho “Domain-Driven Design: Tackling Complexity in the

Heart of Software” [20]. É uma abordagem de desenvolvimento de software projeta-

da para gerenciar produtos de software complexos e de grande escala. Em seu cen-

tro, ele se concentra na criação de uma linguagem compartilhada conhecida como

Linguagem Ubíqua para descrever eficiente e efetivamente um domínio de problema.

Essa linguagem ubíqua em constante evolução é a ferramenta que permite às equi-

pes de desenvolvimento e ao negócio colaborarem na construção de modelos úteis

do domínio do problema que são usados para resolver casos de uso de negócios. O

modelo é representado em software usando a mesma Linguagem Ubíqua e está no

centro de qualquer implementação técnica.

O DDD apresenta os seguintes benefícios:

Page 26: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

26

- Isolar e organizar o código: A capacidade de quebrar grandes e complexos

problemas de domínios e concentrar os esforços da equipe sobre as partes

mais valiosas de um sistema é conhecido como o lado estratégico do DDD.

Este projeto estratégico ajuda a impedir que o software evolua incorretamente

como componentes da solução global são capazes de evoluir dentro de con-

textos de negócios bem definidos, sem ter um impacto negativo em outras

partes do sistema. Ele também arma a equipe com o conhecimento sobre o

que investir mais tempo e esforço entendendo o que é importante para o ne-

gócio [21].

- Manutenção do sistema: Qualquer desenvolvedor trabalhando em um sistema

complexo pode escrever um bom código e mantê-lo por um curto tempo. No

entanto, sem uma sinergia entre a base de código e o domínio do problema, o

desenvolvimento contínuo provavelmente acabará em uma base de código

que é difícil de modificar, resultando em uma aplicação monolítica e confusa.

Domain-Driven Design ajuda com este problema, colocando ênfase na verifi-

cação continua do quão útil é o código para o problema atual e desafiando a

evolução e simplificação dos modelos complexos de domínios [21]. - Aprendizagem através da colaboração: O DDD enfatiza a importância da co-

laboração entre as equipes de desenvolvimento e os especialistas em negó-

cios para produzir modelos úteis para resolver problemas. Sem essa colabo-

ração e o comprometimento dos especialistas em negócios, grande parte do

compartilhamento de conhecimento não será possível e as equipes de de-

senvolvimento não obterão uma visão mais profunda do domínio do problema.

Também é verdade que, através da colaboração e divisão de conhecimento, a

empresa tem a oportunidade de aprender muito mais sobre seu domínio [18].

- Ágil, interativo, modelagem contínua: A palavra design pode provocar pensa-

mentos negativos nas mentes da gestão empresarial. No entanto, o DDD não

propõe um design de muita cerimônia e processo de desenvolvimento. DDD

não se trata de desenhar diagramas, trata-se de refinar cuidadosamente o

modelo mental de especialistas de domínio em um modelo útil para o negócio.

Não se trata de criar um modelo do mundo real, como tentar imitar a realidade.

Os esforços da equipe seguem uma abordagem ágil, que é iterativa e incre-

mental. Qualquer processo ágil que a equipe se sinta confortável pode ser

Page 27: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

27

usado com sucesso em um projeto DDD. O modelo que é produzido é o sof-

tware de trabalho que é refinado continuamente até que não seja mais neces-

sário pelo negócio [18].

Utilizando-se um design de sistemas baseado em DDD, haverá uma me-

lhora no entendimento e implementação do domínio de negócio, levando a um me-

lhor design e com isso a diminuição da complexidade do sistema. Com a aplicação

menos complexa, melhor será a manutenção do sistema, fazendo com que o softwa-

re tenha menos defeitos a um longo prazo.

3.2 ARQUITETURA

A arquitetura de software de um programa ou sistema de computação são

as estruturas do sistema que compreendem componentes de software, propriedades

externamente visíveis desses componentes e as relações entre eles. Não é o sof-

tware operacional. Em vez disso, é uma representação que permite analisar a eficá-

cia do projeto no cumprimento de seus requisitos declarados, considerar alternativas

em uma fase em que fazer alterações de projeto ainda é relativamente fácil, e redu-

zir os riscos associados à construção do software [14].

Uma boa escolha de arquitetura poderá salvar uma aplicação da comple-

xidade desnecessária. Assim como na construção de prédios, a criação de softwa-

res também deve ser orquestrada, tendo em vista que a escolha de uma arquitetura

é tida como um dos fatores para o sucesso ou falha do empreendimento.

Para um melhor entendimento da solução serão apresentados 2 tipos de

arquitetura: arquitetura monolítica, utilizada pela grande maioria das aplicações, dei-

xando claro seus problemas; e uma sugestão de arquitetura utilizando micro serviço.

Page 28: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

28

3.2.1 Arquitetura Monolítica

Uma arquitetura monolítica, é toda arquitetura de aplicação que possui as

seguintes características [22]:

- Módulo monolítico: Quando todo código do sistema é um único código base

que é compilado junto e produz um simples artefato. O código pode estar até

bem estruturado, mas não há separação de módulos para a compilação.

- Alocação monolítica: Todo código é entregue ao mesmo tempo, tudo está

compilado e pronto para produção então uma única versão é entregue. Todos

os componentes do software possuem a mesma versão.

- Execução monolítica: Uma simples aplicação ou processo que realiza todo o

trabalho para o sistema.

A maioria das aplicações começam a ser desenvolvidas como uma arqui-

tetura monolítica devido a simplicidade no desenvolvimento e nos testes. Mas, com

o seu crescimento, alguns problemas ficam mais evidentes, como os seguintes [23]:

- A base de código monolítica intimida os desenvolvedores, especialmente

aqueles que são novos na equipe. A aplicação será difícil de entender e modi-

ficar, tornando o desenvolvimento mais lento e arriscado.

- IDE sobrecarregada: Quanto maior a base de código, mais lento é o IDE dei-

xando os desenvolvedores menos produtivos.

- Dificuldade na escalabilidade, não permitindo dimensionar cada componente

independentemente.

- Redução de confiança. Erro em qualquer módulo (por exemplo, vazamento de

memória) pode potencialmente derrubar todo o processo. Além disso, como

todas as instâncias do aplicativo são idênticas, esse bug afetará a disponibili-

dade do aplicativo inteiro.

- Qualquer alteração torna necessário republicar a aplicação inteira e como a

sua arquitetura é monolítica, composta de um único processo, a alteração po-

de impactar toda a aplicação.

Page 29: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

29

- Requer um compromisso de longo prazo com uma tecnologia específica.

Como as mudanças nos frameworks ou nas linguagens afetarão o aplicativo

inteiro, a mudança é extremamente cara em tempo e custo.

- Utilizando-se uma arquitetura monolítica, códigos relacionados a funções se-

melhantes começam a ficar espalhados por todo projeto, tornando a correção

de erros e implementações cada vez mais difíceis [24].

3.2.2 Arquitetura Micro Serviço

Pode-se definir um micro serviço como: An approach to designing software as a suite of small services, each running

in its own process and communicating with lightweight mechanisms. [25]

Microservices are small, autonomous services that work together. [24]

O conceito básico de um micro serviço é simples: é um pequeno aplicati-

vo que realiza uma única tarefa, e realiza essa tarefa bem. Um micro serviço é um

pequeno componente que é facilmente substituível, desenvolvido de forma indepen-

dente, e publicável de maneira independente.

Dentro de um sistema monolítico, há a tentativa de garantir a coesão no

código muitas vezes através da criação de abstrações ou módulos. A coesão, que

determina que classes/serviços devem ter apenas uma única responsabilidade, é um

conceito importante quando se pensa sobre uma arquitetura micro serviço. Sendo

reforçada pela definição do princípio da responsabilidade única, que afirma Robert C.

Martin, “Reunir classes que mudam pela mesma razão, e separar aquelas que mu-

dam por razões diferentes. “ [26]

Micro serviço toma esta mesma abordagem para serviços independentes.

Os limites do serviço são limites de negócios, tornando-se óbvio que o código vive

para uma determinada funcionalidade. E por manter este serviço focado em um limi-

te explícito, evita a tentação que cresça, com todas as dificuldades associadas que o

crescimento possa introduzir.

Page 30: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

30

Os benefícios desta arquitetura são [27]:

- Cada micro serviço é relativamente pequeno, ficando mais fácil para um de-

senvolvedor entender.

- Cada serviço pode ser desenvolvido e implantado de forma independente de

outros serviços.

- Permite escalar melhor o desenvolvimento, dividindo o esforço em torno de

várias equipes. Cada equipe pode desenvolver, implementar e escalar os

seus serviços de forma independente de todas as outras equipes.

- Melhoria no isolamento de falhas. Por exemplo, se houver um vazamento de

memória em um serviço, apenas esse serviço será afetado, os outros serviços

vão continuar trabalhando normalmente. Em comparação, um componente

com mal comportamento em uma arquitetura monolítica, pode derrubar todo o

sistema.

- Elimina qualquer compromisso de longo prazo a tecnologia. Ao desenvolver

um novo serviço poderá escolher uma nova tecnologia, da mesma forma ao

fazer grandes mudanças.

Para deixar mais claro a abordagem, a Figura 1 mostra uma visão de

mais alto nível de como as funcionalidades são implementadas envolvendo uma ar-

quitetura monolítica e uma arquitetura de micro serviços. Na arquitetura monolítica

as funcionalidades pertencem ao mesmo processo e o dimensionamento se dá de

toda a aplicação e não nas partes que requerem maior recurso. Na arquitetura mi-

croserviço a aplicação é construída como serviços, que são independentes e esca-

láveis.

Page 31: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

31

Figura 1: Exemplos de arquiteturas monolítica (à esquerda) e de micro serviços (à direita) [28].

Como um sistema opera e o fluxo de controle passa entre microserviços,

há um incentivo natural para encapsular a comunicação intra-serviços para amortizar

o custo das fronteiras de cada serviço. Enquanto essa dosagem pode aumentar as

latências em alguns casos, também pode simplificar dependências entre componen-

tes e, eventualmente, reduzir a probabilidade de falhas de software e, por conse-

guinte, as vulnerabilidades.

A Figura 2 apresenta exemplos baixo nível das arquiteturas monolítica e

de micro serviços. Na direita, é apresentada uma abordagem utilizada por muitas

aplicações monolíticas, uma aplicação única ou dividida em camadas (módulos) com

um simples e centralizado banco de dados realizando a integração do sistema.

Esta é uma abordagem que aparenta ser mais simples e parece permitir o

reuso de entidade em subsistemas diferentes para tornar tudo consistente.

Mas a realidade é que acaba com uma quantidade enorme de tabelas que

servem para muitos subsistemas diferentes e incluem atributos e colunas

que simplesmente não são necessárias na maioria dos casos. [29]

Page 32: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

32

Além de que toda aplicação este acoplado a um mesmo processo. Para

corrigir uma parte do programa com problemas, toda aplicação terá que ser republi-

cada, e isto não garantirá que a parte substituída não afetará as demais.

A esquerda da Figura 2 apresentada a arquitetura com a separação da

aplicação em diferentes serviços independentes podendo cada uma ter sua própria

tecnologia de persistência de dados. Como os serviços são independentes, cada

um poderá ter seu ciclo de vida independente dos outros serviços. Além disso é

exemplificado o uso de serviços com estado (stateful) e sem estado (stateless). Um

serviço stateful é útil para reduzir a latência entre a lógica e os dados de domínio,

muito utilizado para processamentos de dados pesados. O serviço stateless é mais

simples de implementar, porém apresenta performance inferior ao serviço stateful

devido a não guardar estado para o acesso mais rápido.

Figura 2: Exemplo baixo nível de arquitetura micro serviços (à esquerda) e arquitetura monolítica (à direita) [29]

3.3 LINGUAGEM

As linguagens de programação estão entre o CPU (Central Processing

Unit) e o programador e impõe regras que impedem alguns tipos de erros. Funções

Page 33: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

33

nativas e as características dos seus compiladores são grandes aliados quando se

trata de detecção e prevenção de bugs. Os compiladores muitas vezes adicionam

uma camada extra de segurança, executando análise que pode sinalizar erros no

código muito antes da execução da aplicação.

Compiladores ajudam na prevenção de bugs, mas algumas ambiguidades

podem ser prejudiciais. Roderick Chapman, engenheiro da empresa Praxis, descre-

veu esse tipo de ambiguidade ao escrever uma simples função em C como “i++ *

i++”. Mesmo sabendo que “++” incrementa em uma unidade e “*” sinal de multiplica-

ção, o resultado dependerá do compilador utilizado. Alguns compiladores incremen-

tam antes de multiplicar outros depois, trazendo dificuldade para desenvolvedores

entender o correto funcionamento da linguagem. Such a problem could not happen in Spark, says Praxis’s Chapman, be-

cause all such ambiguous cases were considered—and eliminated—when

the language was created. Coding with Spark thus helps Praxis achieve re-

duced bug rates. In fact, once Spark code has been written, Chapman says,

it has the uncanny tendency to work the first time, just as you wanted. “Our

defect rate with Spark is at least 10 times, sometimes 100 times lower than

those created with other languages." [30]

Nas seções a seguir serão apresentadas características de linguagem

que previnem certos bugs no código, auxiliando na escolha da melhor linguagem

para o projeto.

3.3.1 Tipagem Forte

Uma linguagem é fortemente tipada, quando o compilador não permite

operações como atribuição e comparação entre variáveis de tipos diferentes, sem

usar uma conversão explicita. Por exemplo, não é possível utilizar operações de

ponto flutuante com valores inteiros, ou utilizar valores booleanos como inteiros, sem

utilizar algum tipo de conversão.

A linguagem fortemente tipada impõe restrições sobre operações entre

variáveis de tipos diferentes. Nesses casos, o compilador emite um erro proibindo a

Page 34: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

34

operação. Essas diretrizes rigorosas sobre tipos de dados são projetadas para evitar

possíveis erros [31].

3.3.2 Tipagem Estática

A linguagem é estaticamente tipada se o tipo de uma variável é conhecido

em tempo de compilação em vez de em tempo de execução.

A grande vantagem de verificação de tipo estático é que ele permite que

muitos erros sejam descobertos cedo no ciclo de desenvolvimento. Tipagem estáti-

ca geralmente resulta em código compilado que executa mais rapidamente, porque

quando o compilador sabe os tipos de dados exatos que estão em uso, ele pode

produzir código otimizado da máquina (ou seja, mais rápido e / ou usando menos

memória). Verificadores de tipo estático avaliam apenas o tipo de informação que

pode ser determinado em tempo de compilação, mas são capazes de verificar se as

condições verificadas se mantêm por todas as execuções possíveis do programa, o

que elimina a necessidade de repetir verificações cada vez que o programa é execu-

tado. Um verificador estático irá detectar rapidamente erros de tipo em caminhos de

código raramente usados [32].

3.3.3 Automático Gerenciamento de Memória

Gerenciamento de memória envolve o fornecimento de memória necessá-

ria para objetos de um programa e estruturas de dados a partir dos recursos dispo-

níveis, e reciclando a memória para reutilização quando já não é necessário. Aplica-

ções não podem em geral prever com antecedência quanta memória elas vão exigir,

eles precisam de código adicional para lidar com seus requisitos de mudança de

memória.

O gerenciamento automático de memória é um serviço, seja como parte

da linguagem ou como uma extensão, que recicla automaticamente a memória que

Page 35: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

35

um programa que não vai utilizar novamente. Eles costumam fazer o seu trabalho

através da reciclagem de blocos que são inacessíveis a partir das variáveis do pro-

grama (isto é, blocos que não podem ser alcançados por ponteiros).

As vantagens do gerenciamento automático são [33]:

- O programador é liberado para trabalhar no problema real;

- Interfaces do módulo são mais limpos;

- Há menos erros de gerenciamento de memória;

- Gerenciamento de memória é muitas vezes mais eficiente.

3.3.4 Estrutura Funcional

A programação funcional é assim chamada porque sua operação funda-

mental é a aplicação de funções a argumentos. Um programa principal em si é es-

crito como uma função que recebe a entrada do programa como seu argumento e

entrega a saída do programa como seu resultado. Normalmente, a função principal é

definida em termos de outras funções, que por sua vez são definidas em termos de

ainda mais funções, até que no nível inferior as funções são primitivas de linguagem.

Todas estas funções são muito semelhantes às funções matemáticas comuns.

Os programas funcionais não contêm instruções de atribuição, portanto as

variáveis, uma vez dadas um valor, nunca mudam. De um modo mais geral, os pro-

gramas funcionais não contêm efeitos colaterais. Uma chamada de função não pode

ter outro efeito senão calcular seu resultado. Isso elimina uma grande fonte de bugs

e também torna irrelevante a ordem de execução - uma vez que nenhum efeito late-

ral pode alterar o valor de uma expressão, ele pode ser avaliado a qualquer momen-

to. Isso alivia o programador da carga de prescrever o fluxo de controle. Uma vez

que as expressões podem ser avaliadas a qualquer momento, é possível substituir

livremente as variáveis por seus valores e vice-versa - isto é, os programas são "re-

ferencialmente transparentes". Essa liberdade ajuda a tornar os programas funcio-

nais mais tratáveis matematicamente do que suas contrapartes convencionais [34].

Para as características apresentadas acima, as seguintes linguagens

apresentam todos esses atributos: F# [35], Haskell [36] e Swift [37].

Page 36: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

36

4 REVISÕES DE SOFTWARE

Revisões são atividades de controle de qualidade que verificam a quali-

dade dos entregáveis do projeto. Isso envolve a análise do software, a documenta-

ção e registros do processo para descobrir erros e omissões e ver se os padrões de

qualidade têm sido seguidos.

Revisões de qualidade são baseadas em documentos que foram produzi-

dos durante o processo de desenvolvimento de software. Além de especificações de

software, projetos ou códigos, modelos de processo, planos de teste, procedimentos

de gerenciamento de configuração, padrões de processo e manuais do usuário, to-

dos podem ser revisados. A revisão deve verificar a consistência e integridade dos

documentos ou código sob revisão e certificar-se de que os padrões de qualidade

foram seguidos.

No entanto, as revisões não se limitam a verificar a conformidade com os

padrões. Eles também são usados para ajudar a descobrir problemas e omissões no

software ou na documentação do projeto. As conclusões da revisão devem ser re-

gistradas formalmente como parte do processo de gestão da qualidade. Se os pro-

blemas foram descobertos, os comentários dos revisores devem ser passados para

o autor do software ou quem é responsável pela correção de erros ou omissões [15].

Os benefícios da revisão são:

- Detectar erros na lógica/estrutura do programa ou inconsistências de um arte-

fato para o próximo. Expor programas para outras pessoas ajuda na qualida-

de, tanto pela pressão de pessoas externas para fazer as tarefas bem e tam-

bém detectar problemas que um simples indivíduo não achou.

- Certificar-se de que a intenção do artefato é clara (o mais claro o melhor).

- Verificar se o design e/ou software cumpre seus requisitos.

- Para garantir que o software tenha sido desenvolvido de forma uniforme,

usando padrões acordados.

A revisão de código pode ser especialmente produtiva para identificar vul-

nerabilidades de segurança durante o desenvolvimento de software. Se for devida-

mente conduzida pode fazer mais para a segurança do código do que quase qual-

Page 37: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

37

quer outra atividade. Ela permite localizar e corrigir um grande número de problemas

de segurança antes que o código seja testado ou publicado.

Se planejadas e gerenciadas corretamente, as revisões de código são

muito eficientes em termos de custo, especialmente se forem incorporadas ao pro-

cesso de desenvolvimento, evitando o caro processo de manipulação, localização e

correção de vulnerabilidades de segurança durante fases posteriores de desenvol-

vimento ou após lançamento do software. Outra vantagem desta abordagem é que

facilita a experiência e a educação da equipe de desenvolvimento no uso das melho-

res práticas de segurança, o que ajudará a prevenir futuras questões de segurança.

[38]

Além desses objetivos, quando as revisões envolvem a participação de

grupo, as revisões têm efeitos colaterais benéficos. Primeiramente, as revisões são

um meio excelente de aprender sobre o sistema geral e sobre as técnicas dos com-

panheiros de equipe a fim melhorar a comunicação. Em segundo lugar, trabalhando

juntos, várias pessoas da equipe se familiarizam um pouco com os detalhes do arte-

fato sob revisão. Esse conhecimento adicional é útil quando o criador do artefato não

está disponível e/ou participante da revisão deve interagir com o artefato. Finalmente,

há um benefício psicológico para o criador do artefato, quando outras pessoas estão

revisando os documentos ou códigos tem maior incentivo para tornar as coisas cla-

ras e simples. Como resultado, o trabalho é geralmente de maior qualidade.

Muitos tipos diferentes de revisões podem ser conduzidos como parte da

engenharia de software. Cada um tem seu lugar. Uma apresentação formal da ar-

quitetura de software para uma audiência de clientes, gerenciamento e equipe técni-

ca também é uma forma de revisão. Entretanto uma revisão técnica é o filtro mais

eficaz do ponto de vista do controle de qualidade. Conduzido por engenheiros de

software (e outros) para engenheiros de software, é um meio eficaz para descobrir

erros e melhorar a qualidade do software [39].

As revisões de software variam de acordo com a formalidade, sendo des-

critas nas seções abaixo, do método mais formal ao menos informal.

Page 38: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

38

4.1 INSPEÇÃO

Uma inspeção é o tipo mais sistemático e rigoroso de revisão pelos pares.

Segue-se um processo bem definido, de vários estágios, com funções específicas

atribuídas a cada participante. O processo de inspeção mais comum inclui sete eta-

pas: planejamento, visão geral, preparação, reunião, retrabalho, acompanhamento e

análise causal. Para máxima eficácia, os inspetores devem ser treinados no proces-

so de inspeção e ser capazes de desempenhar todas as diferentes funções. Inspe-

ções dependem de listas de verificação de defeitos comuns encontrados em diferen-

tes tipos de produtos de trabalho de software, regras para construir produtos de tra-

balho e várias técnicas analíticas para procurar bugs.

Um aspecto fundamental da inspeção é que os participantes, além do au-

tor do produto de trabalho, conduzem a reunião (moderador), apresentam o material

à equipe de inspeção (leitor) e gravam as questões à medida que são levantadas.

Os participantes se preparam para a inspeção examinando o material por conta pró-

pria para compreendê-lo e encontrar problemas. Durante a reunião, o leitor apresen-

ta o material, uma pequena parte de cada vez, para os outros inspetores, que levan-

tam questões e apontam possíveis defeitos. O leitor ajuda a equipe a alcançar a

mesma interpretação de cada parte do produto, porque os inspetores podem compa-

rar sua compreensão com a expressa pelo leitor. No final, a equipe concorda com

uma avaliação do produto de trabalho e decide como verificar as mudanças que o

autor fará durante a retrabalho [40].

4.2 REVISÃO DE EQUIPE

São menos formais e abrangentes e seguem várias etapas encontradas

em uma inspeção. Os participantes recebem os materiais de revisão vários dias an-

tes da reunião, e espera-se que eles estudem os materiais por conta própria. A

equipe coleta dados sobre o esforço de revisão e o número de defeitos encontrados.

No entanto, os estágios de visão geral e de acompanhamento são simplificados ou

Page 39: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

39

omitidos, e alguns papéis dos participantes podem ser combinados. O autor pode

liderar a revisão da equipe, e em contraste com a maioria das inspeções, o papel do

leitor é omitido. Em vez de um participante descrever um pequeno pedaço do produ-

to por vez, o líder da revisão pergunta aos participantes se eles têm comentários

sobre uma seção ou página específica.

Revisões de equipe custam mais do que ter uma única pessoa executan-

do uma revisão desk check, mas os diferentes participantes vão encontrar diferentes

conjuntos de erros. A pessoa responsável em gravar ou registrar, captura as ques-

tões à medida que elas são levantadas, usando formulários padrão adotados pela

organização.

Revisões de equipe são adequados para uma equipe ou produto que não

exige o rigor total do processo de inspeção [40].

4.3 WALKTHROUGH

É uma revisão informal em que o autor de um produto de trabalho descre-

ve para um grupo de colegas e solicita seus comentários. Walkthroughs diferem sig-

nificativamente de inspeções porque o autor assume o papel dominante. Não exis-

tem outros papéis específicos do revisor. Considerando-se que uma inspeção é des-

tinada a cumprir os objetivos de qualidade da equipe, um walkthrough serve princi-

palmente as necessidades do autor.

Normalmente não seguem um procedimento definido, não requerem rela-

tórios de gerenciamento e não geram métricas. Eles podem ser uma maneira efici-

ente de rever os produtos modificados durante a manutenção, porque o autor pode

chamar a atenção dos revisores para aquelas partes dos produtos que foram altera-

dos [40].

Page 40: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

40

4.4 PROGRAMAÇÃO EM PAR (PAIR PROGRAMMING)

É uma prática popularizada pelo Extreme Programming e desenvolvimen-

to ágil, mas também é um processo de desenvolvimento que incorpora contínua re-

visão. Programação em par são dois desenvolvedores trabalhando no mesmo pro-

duto simultaneamente em uma única estação de trabalho. Isso facilita a comunica-

ção e oferece uma oportunidade para a revisão contínua, incremental e informal das

ideias de cada pessoa, podendo ser usado para criar qualquer produto de trabalho

de software, não apenas o código.

Culturalmente, a programação em pares promove a colaboração, a pro-

priedade coletiva da base de código da equipe e um compromisso compartilhado

com a qualidade de cada componente. Pelo menos dois membros da equipe tornam-

se intimamente familiarizados com cada pedaço de código, aumentando a dissemi-

nação do conhecimento.

Programação em par não é especificamente uma técnica de revisão, mas

sim uma estratégia de desenvolvimento que se baseia na sinergia de duas mentes

focadas para criar produtos superiores em design, execução e qualidade. No entanto,

é uma grande mudança de cultura na maneira como uma equipe de desenvolvimen-

to opera, portanto, não é uma simples substituição para revisões de pares tradicio-

nais na maioria das situações [40].

4.5 DESK CHECK

Em uma revisão desk check, apenas uma pessoa, além do autor, examina

o produto. O autor pode não saber como o revisor abordou a tarefa ou quão abran-

gente foi a revisão. A revisão depende inteiramente do conhecimento, habilidade e

autodisciplina do revisor, por isso espera ampla variabilidade nos resultados. Após a

conclusão, o revisor pode entregar uma lista de defeitos para o autor ou simples-

mente entregar ao autor o seu trabalho com marcações no produto.

Page 41: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

41

O desk check é a abordagem de revisão mais barata pois envolve apenas

o tempo do revisor. Este método é adequado para produtos de trabalho de baixo

risco ou projetos com graves restrições de tempo e recursos. Esse tipo de revisão

pode ser mais confortável para o autor do que uma revisão em grupo que pode se

tornar intimidante, fornecendo uma boa maneira de começar a desenvolver uma cul-

tura de revisão [40].

4.6 PASS-AROUND

Nesse tipo de revisão é entregue uma cópia do produto para várias pes-

soas e o autor coleta os comentários de cada revisor. Esse tipo de revisão permite

que revisores com diferentes conhecimentos e experiência contribuam com o produ-

to.

O pass-around mitiga dois riscos principais de uma revisão desk check: o

revisor não fornecer feedback oportuno e/ou revisor não realizar um bom trabalho,

pois apresenta facilidade para envolver outras pessoas no processo, funcionando

bem para equipes geograficamente distribuídas.

Todas as técnicas acima são úteis e resultam em código de melhor quali-

dade. Não importando de qual tipo, a revisão de código é uma ótima maneira de

encontrar bugs, compartilhar informações e prover um aprendizado individual [40].

Page 42: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

42

5 TESTES

Os testes destinam-se a mostrar que um programa faz o que se pretende

fazer e para descobrir defeitos do programa antes de ser colocado em uso. Ao testar

software, é executado um programa usando dados artificiais. Verifica-se os resulta-

dos da execução de testes para erros, anomalias ou informações sobre os atributos

não funcionais do programa.

O processo de teste tem dois objetivos distintos:

- Demonstrar ao desenvolvedor e ao cliente que o software atende aos seus

requisitos. Para software, isso significa que deve haver pelo menos um teste

para cada requisito no documento de requisitos. Para produtos genéricos de

software, isso significa que deve haver testes para todos os recursos do sis-

tema, além de combinações desses recursos, que serão incorporados na ver-

são do produto.

- Descobrir situações nas quais o comportamento do software é incorreto, inde-

sejável ou não está de acordo com sua especificação. Estas são uma conse-

quência de defeitos de software. O teste de defeitos está relacionado com a

erradicação do comportamento indesejável do sistema, como falhas do siste-

ma, interações indesejadas com outros sistemas, cálculos incorretos e cor-

rupção de dados.

O objetivo do teste é descobrir o máximo possível de defeitos, no mais

alto nível de seriedade. Não é possível testar um aplicativo com todos os valores de

entrada possíveis devido ao número extraordinariamente grande de combinações de

valores de entrada. Como disse o renomado cientista da computação Edsgar Dijks-

tra, “Testes somente pode mostrar a presença de erros, não a sua ausência”. Em

outras palavras o teste não pode demonstrar que o software está livre de defeitos ou

que se comportará como especificado em todas as circunstâncias, sendo sempre

possível descobrir mais problemas com o sistema.

Page 43: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

43

Dois princípios básicos de teste de software são "testar cedo" e "testar

frequentemente". Estes preceitos têm sido respeitados por muitos anos e são uma

característica principal das metodologias ágeis.

"Testar cedo" significa testar as unidades assim que elas são implementa-

das, em vez de aguardar a conclusão das unidades de que fazem parte.

"Testar frequentemente" significa executar testes em todas as oportunida-

des razoáveis, incluindo após pequenas adições ou alterações. Testando muitas

vezes traduz em uma reexecução dos testes anteriores para então testar a nova

funcionalidade. Uma razão para testar muitas vezes é que as alterações às vezes

invalidam o código já implementado [16].

Será apresentada nas próximas seções uma introdução aos testes ágeis

e os seus benefícios comparado com testes tradicionais, deixando claro a necessi-

dade de serem automatizados, mostrando abordagens e ferramentas para alcançar

essa automação.

5.1 TESTE ÁGIL (AGILE TESTING)

É um conjunto de práticas, seguindo o Manifesto Ágil, que incorpora todas

as técnicas de teste comumente utilizadas por profissionais de teste, tendo um gran-

de foco em automação. A principal função é criticar o produto, ou seja, constante-

mente garantir que o que está sendo especificado e desenvolvido realmente atende

às necessidades do cliente e irá entregar valor ao negócio [41].

Na abordagem Ágil, desenvolvedores e testadores são vistos como dois

lados da mesma moeda de produção, duas linhas paralelas que devem sempre se

encontrar e comparar notas diariamente. De uma perspectiva ágil, a produção efici-

ente é severamente prejudicada se seus desenvolvedores estão se esforçando para

refinar seu código para um estado de perfeição antes de passá-lo para uma equipe

de testes separada, que então se esforçam para quebrá-lo de tantas maneiras quan-

to possível antes de enviar seus relatórios de danos para a equipe de desenvolvi-

mento. Este processo de duas etapas requer tempo, dinheiro e frequentemente

leva à divisão interna entre desenvolvedores de uma empresa e testadores. Em vez

Page 44: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

44

disso, a perspectiva ágil sugere que essas duas funções essenciais sejam mistura-

das, não necessariamente em termos de pessoas, mas em termos de tempo e pro-

cesso, assim superando a divisão ilusória entre criadores e testadores de código,

reduzindo a necessidade de equipes de testes robustas. Ainda respeitando a ne-

cessidade de ambos os papéis, em ágil os desenvolvedores são encorajados a pen-

sar mais como testadores, continuamente verificando seu próprio código para erros

potenciais, e os testadores são incentivados a pensar mais como desenvolvedores,

temperando suas tendências para se engajar mais plenamente no próprio processo

criativo [42].

Várias práticas essenciais utilizadas pelas equipes ágeis estão relaciona-

das com os testes. Os programadores ágeis usam o test-driven developement

(TDD), um desenvolvimento de software orientado a testes, também chamado de-

sign test-driven, para escrever código de produção de qualidade. Os programadores

também escrevem testes de integração de código para certificar-se de que as pe-

quenas unidades de código trabalham juntas como planejado. Esta prática essenci-

al tem sido adotada por muitas equipes, mesmo aqueles que não se chamam "ágil",

porque é apenas uma maneira inteligente de pensar através de seu projeto de sof-

tware e evitar defeitos.

Teste ágil não significa apenas teste em um projeto ágil. Alguns métodos

de teste, como os testes exploratórios, são inerentemente ágeis, quer se trate de um

projeto ágil ou não.

5.2 TESTES TRADICIONAIS E TESTES ÁGEIS

Ágil é iterativo e incremental. Isso significa que os testadores testam ca-

da unidade de codificação assim que ele é finalizado. Uma iteração pode ser tão

curta como uma semana ou até um mês. A equipe constrói e testa um pouco de có-

digo, certificando-se de que ele funciona corretamente e, em seguida, passa para a

próxima unidade que precisa ser construída. Programadores nunca ficam à frente

dos testadores, porque uma história não é fechada até que tenha sido testada.

Page 45: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

45

Ao invés de criar testes a partir de um documento de requisitos criado por

analistas de negócios antes que alguém tenha pensado em escrever uma linha de

código, alguém precisará escrever testes que ilustram os requisitos para cada histó-

ria dias ou horas antes do início da codificação. Isso geralmente é um esforço cola-

borativo entre um especialista em negócios ou domínio e um testador, analista ou

algum outro membro da equipe de desenvolvimento. Os casos de testes funcionais

detalhados, idealmente baseados em exemplos fornecidos por especialistas em ne-

gócios, substituem os requisitos. Os testadores realizarão testes manuais explorató-

rios para encontrar bugs importantes que os casos de teste definidos possam perder.

Os testadores podem se associar a outros desenvolvedores para automatizar e exe-

cutar casos de teste à medida que a codificação de cada história prossegue. Testes

funcionais automatizados são adicionados ao conjunto de testes de regressão.

Quando os testes que demonstram funcionalidade mínima estão completos, a equi-

pe pode considerar a história finalizada.

A diferença mais crítica para os testadores em um projeto ágil é o retorno

rápido do teste. Ele impulsiona o projeto para a frente, e não há nada para bloquear

o progresso do projeto se determinados marcos não forem atendidos.

Uma das maiores diferenças no desenvolvimento ágil para o desenvolvi-

mento tradicional é a abordagem ágil da "equipe inteira". Com ágil, não são só os

testadores ou uma equipe de garantia de qualidade que se sentem responsáveis

pela qualidade. Não há pensamos em "departamentos", apenas pensamentos em

habilidades e recursos necessários para oferecer o melhor produto possível. O foco

do desenvolvimento ágil é a produção de software de alta qualidade em um período

de tempo que maximiza o seu valor para o negócio. Este é o trabalho de toda a

equipe, não apenas testadores ou profissionais de garantia de qualidade. Todos na

equipe ágil ficam orientados a teste.

Uma equipe ágil deve possuir todas as habilidades necessárias para pro-

duzir código de qualidade que ofereça os recursos exigidos pela organização. Em-

bora isso possa significar a inclusão de especialistas na equipe, como testadores

especializados, não há limite de tarefas específicas a membros da equipe em parti-

cular. Qualquer tarefa pode ser concluída por qualquer membro da equipe, ou um

par de membros da equipe. Isso significa que a equipe assume a responsabilidade

por todos os tipos de tarefas de teste, como testes automatizados e testes explorató-

Page 46: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

46

rios manuais. Isso também significa que toda a equipe pensa constantemente em

projetar código de testabilidade [43].

5.3 TESTES AUTOMATIZADOS

Cada grupo de desenvolvimento de software testa seus produtos, mas o

software fornecido sempre tem defeitos. Os engenheiros de teste se esforçam para

capturá-los antes que o produto seja lançado, mas eles sempre se aproximam e eles

muitas vezes reaparecem, mesmo com os melhores processos de teste manual.

Teste automatizado é a melhor maneira de aumentar a eficácia, eficiência e cobertu-

ra dos testes.

O teste manual de software é realizado por um ser humano sentado na

frente de um computador passando cuidadosamente por telas de aplicação, tentan-

do várias combinações de uso e entrada, comparando os resultados com o compor-

tamento esperado e registrando suas observações. Testes manuais são repetidos

frequentemente durante ciclos de desenvolvimento para alterações de código fonte e

outras situações como vários ambientes operacionais e configurações de hardware.

Uma ferramenta de teste automatizada é capaz de reproduzir ações pré-gravadas e

predefinidas, comparar os resultados com o comportamento esperado e relatar o

sucesso ou falha desses testes manuais para um engenheiro de teste. Uma vez

criados os testes automatizados, eles podem ser facilmente repetidos e podem ser

estendidos para executar tarefas impossíveis com testes manuais. Devido a isso,

gestores experientes descobriram que o teste de software automatizado é um com-

ponente essencial de projetos de desenvolvimento bem-sucedidos [43].

Principais benefícios:

- O teste manual demora muito tempo.

A razão mais básica para automatizar é que simplesmente leva muito

tempo para concluir todos os testes necessários manualmente. À medida que a

aplicação se torna cada vez maior, o tempo para testar tudo cresce mais e mais, às

vezes exponencialmente, dependendo da complexidade da aplicação em teste.

Page 47: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

47

Executar um conjunto completo de testes de regressão pelo menos diari-

amente é uma prática indispensável, e não pode ser feito manualmente. Se execu-

tar o teste de regressão manualmente, é preciso mais e mais tempo testando todos

os dias, cada iteração. A fim de testar para manter o ritmo com codificação, ou os

programadores têm de ter tempo para ajudar com os testes de regressão manual-

mente, ou a equipe tem que contratar mais testadores. Inevitavelmente, tanto a dívi-

da técnica quanto a frustração crescerão.

Se o código não passar por um conjunto de testes automatizados, os tes-

tadores provavelmente gastarão muito tempo pesquisando, tentando reproduzir e

relatar bugs simples e menos tempo encontrando bugs de nível de sistema potenci-

almente sérios.

- Processos manuais são propensos a erros.

Testes manuais são repetitivos, especialmente se estiver seguindo testes

com script, e testes manuais ficam cansativos rapidamente. É muito fácil cometer

erros e ignorar erros simples. Passos e mesmo testes inteiros serão ignorados.

As compilações automáticas, implantação, controle de versão e monito-

ramento automatizados também percorrem um longo caminho no sentido de reduzir

riscos e tornar seu processo de desenvolvimento mais consistente. A automatização

destes testes de script elimina a possibilidade de erros, porque cada teste é feito

exatamente da mesma maneira cada vez.

- Automação libera as pessoas a fazer o seu melhor trabalho.

Escrever o teste de código ajuda aos programadores a compreenderem

os requisitos e ter conformidade com o design do código. Tendo compilações contí-

nuas executando todos os testes de unidade e os testes de regressão, significam

mais tempo para fazer testes exploratórios. Esses dois tipos de testes são muito

importantes. O teste de unidade é a forma de se testar unidades individuais de códi-

go fonte. Será visto com mais detalhes adiante. O teste de regressão significa testar

novamente uma parte de um aplicativo que não foi alterado para verificar se conti-

nua a funcionar corretamente.

Automatizar a configuração para testes exploratórios significa ainda mais

tempo para investigar partes potencialmente fracas do sistema. Como não foi gasto

Page 48: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

48

tempo executando scripts manuais tediosos, tem a energia para fazer um bom traba-

lho, pensando em diferentes cenários e aprendendo mais sobre como o aplicativo

funciona.

Se o pensamento está constantemente em como automatizar testes para

uma correção ou nova característica, é mais provável o foco estar na testabilidade e

um design de qualidade, em vez de uma abordagem rápida que possa se mostrar

frágil. Isso significa melhor código e melhores testes.

- Os testes automatizados de regressão fornecem uma rede de segurança.

A maioria dos profissionais conhece a sensação de medo quando se de-

frontam com a correção de um bug ou a implementação de um novo recurso no có-

digo mal projetado que não é coberto por testes automatizados. Qualquer alteração

pode deixar uma parte do sistema instável e não terá o resultado do mal funciona-

mento, na maioria das vezes deixando para o usuário final descobrir o problema.

Conhecer o código com cobertura suficiente por testes de regressão au-

tomáticos dá uma grande sensação de confiança. Uma mudança pode produzir um

efeito inesperado, mas o resultado será dado em questão de minutos ou horas, se

em um nível funcional mais elevado. Fazer o teste de mudança primeiro significa

pensar através do comportamento alterado antes de escrever o código e escrever

um teste para o verificar, o que aumenta essa confiança.

- Os testes automatizados dão feedback de forma precoce e frequente.

Depois de um teste automatizado para uma unidade da funcionalidade

passa, ele deve continuar a passar até que a funcionalidade é alterada. Quando

planejamos mudanças no aplicativo, alteramos os testes para acomodá-los. Quando

um teste automatizado falha inesperadamente, um defeito de regressão pode ter

sido introduzido por uma alteração de código. Rodando um conjunto automatizado

de testes sempre que o novo código é verificado ajuda a garantir que os erros de

regressão serão detectados rapidamente. O feedback rápido ajuda na solução dos

problemas tendo a solução mais rápida do que o bug fosse encontrado semanas de

testes mais tarde.

Page 49: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

49

- Os testes fornecem documentação.

É difícil manter a documentação estática atualizada, mas se os testes au-

tomatizados não forem alterados quando o sistema for alterado, os testes falharão.

É necessário corrigi-los para manter o processo de compilação funcionando. Isso

significa que os testes automatizados são sempre uma imagem precisa de como o

código funciona.

- Automação pode ser um bom retorno sobre o investimento.

A automação fornece consistência a um projeto e dá à equipe a oportuni-

dade de testar de forma diferente e empurrar os limites da aplicação. Automação

significa tempo extra para testadores e membros da equipe para se concentrar em

obter o produto certo para o mercado em tempo hábil.

Um componente importante do retorno da automação do teste é a manei-

ra como os defeitos são corrigidos. Equipes que dependem de testes manuais ten-

dem a encontrar bugs muito depois que o código que contém o bug é escrito. Eles

entram no modo de corrigir o "bug do dia", em vez de olhar para a causa raiz do pro-

blema e redesenhar o código de acordo. Quando os programadores executam o

conjunto de testes automatizados, encontram os bugs antes que o código seja verifi-

cado, dando tempo para corrigir o design. Isso é um reembolso muito maior e reduz

a dívida técnica desenvolvendo um código sólido e robusto.

5.4 TEST DRIVEN DEVELOPMENT (TDD)

É a prática de conduzir o design de código com testes. Em contraste com

o fluxo de trabalho tradicional de "escrever código - verificar código", o TDD exige

que a primeira tarefa em qualquer empreendimento de desenvolvimento seja escre-

ver um teste. Somente então o código que fará passar esse teste será escrito. Se

for fielmente aplicado, nenhum código de produção virá a existir, a menos que seja

precedido e acompanhado de pelo menos um teste [44].

O desenvolvimento orientado por teste é realizado em ciclos curtos, cada

uma consistindo no seguinte fluxo: [15]

Page 50: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

50

1. Iniciar identificando o incremento da funcionalidade que é necessário. Isso

normalmente deve ser pequeno e implementável em algumas linhas de códi-

go.

2. Um teste para essa funcionalidade é escrita e é implementada como um teste

automatizado. Isso significa que o teste pode ser executado e relatará se ele

foi aprovado ou executado com falha.

3. Em seguida, o teste é executado juntamente com todos os outros testes que

foram implementados. Inicialmente, a funcionalidade não foi implementada

de modo que o novo teste falhará. Isso é deliberado, pois mostra que o teste

adiciona algo ao conjunto de testes.

4. Em seguida, implementar a funcionalidade e voltar a executar o teste. Isso

pode envolver a refatoração do código existente para aprimorá-lo e adicionar

novo código ao que já existe.

5. Uma vez que todos os testes sejam executados com êxito, o próximo pedaço

da funcionalidade poderá ser implementada.

Um ambiente de teste automatizado é essencial para TDD. Como o códi-

go é desenvolvido em passos muito pequenos, tem que ser capaz de executar cada

teste cada vez que adicionar uma funcionalidade ou refatorar o programa. Portanto,

os testes são incorporados em um programa separado que executa os testes e invo-

ca o sistema que está sendo testado. Usando esta abordagem, é possível executar

centenas de testes separados em poucos segundos.

Além da melhor compreensão dos problemas, outros benefícios do de-

senvolvimento orientado a teste são:

- Cobertura de código. Em princípio, cada segmento de código escrito deve ter

pelo menos um teste associado. Portanto, a confiança aumenta de que todo

o código no sistema foi realmente executado. O código é testado conforme

está escrito para que os defeitos sejam descobertos no início do processo de

desenvolvimento.

- Teste de regressão. Um conjunto de testes é desenvolvido gradualmente à

medida que um programa é desenvolvido. Os testes de regressão sempre

podem ser executados para verificar se as alterações no programa não intro-

duziram novos bugs.

Page 51: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

51

- Depuração simplificada. Quando um teste falha, deve ser óbvio onde o pro-

blema está. O código recém-escrito precisa ser verificado e modificado. Não

é necessário usar ferramentas de depuração para localizar o problema.

- Documentação do sistema. Os próprios testes funcionam como uma forma

de documentação que descreve o que o código deve fazer. A leitura dos tes-

tes pode facilitar a compreensão do código.

5.5 PIRÂMIDE DE AUTOMAÇÃO

Figura 3: Exemplo de pirâmides de automação. [45]

É um conceito popularizado por Mike Cohn (ver Figura 3), que mostra o

que deve ser automatizado e dará maior retorno de investimento, garantindo os mai-

ores benefícios da automação [46].

A pirâmide de automação de teste ágil (a pirâmide da direita) mostra três

camadas diferentes de testes automatizados. A camada mais baixa é a fundação

que suporta as demais camadas. É composta principalmente de testes de unidade.

Page 52: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

52

Esta camada representa a maior parte dos testes automatizados. Eles geralmente

são escritos na mesma linguagem do sistema em teste. Depois de uma equipe ter

dominado a arte de TDD, estes testes são, de longe, os mais rápidos e menos caros

para escrever. Eles fornecem o feedback mais rápido, também os tornando altamen-

te valiosos. Eles têm o maior ROI (retorno do investimento) do que qualquer tipo de

teste.

Em desenvolvimento ágil, é indicada a realização de tantos testes quanto

possível para esta camada. Se existem testes nos quais os clientes não são capa-

zes de ler, eles podem ser codificados muito mais rapidamente como testes de uni-

dade. Outros tipos de testes voltados para a tecnologia, como testes de desempe-

nho, também podem ser possíveis no nível da unidade.

A camada intermediária na pirâmide é a camada que inclui a maioria dos

testes automatizados de negócios voltados para apoiar a equipe. Estes são os tes-

tes funcionais que verificam se a construção está correta. Os testes nesta camada

podem incluir testes de "história", testes de "aceitação" e testes que cobrem conjun-

tos de funcionalidade maiores do que a camada de teste de unidade. Esses testes

operam no nível API ou "atrás da GUI", testando a funcionalidade diretamente sem

passar pela GUI. Como esses testes ignoram a camada de apresentação, eles são

menos caros de escrever e manter do que os testes que usam a interface gráfica.

O nível superior representa o que deve ser o menor esforço de automa-

ção, porque os testes geralmente oferecem o ROI mais baixo. Esses testes são os

feitos através da GUI, os que realmente operam e manipulam a camada de apresen-

tação. Eles são escritos depois que o código é concluído, e por isso são geralmente

escritos para criticar o produto e ir diretamente para o conjunto de regressão.

Estes testes são tradicionalmente mais caros para escrever, embora haja

novas ferramentas que ajudam a reduzir o investimento necessário. Como os com-

ponentes da interface do usuário tendem a ser alterados frequentemente, esses tes-

tes são muito mais frágeis do que os testes que funcionam em nível funcional ou de

unidade.

Não importa quantos testes automatizados se tenha, a maioria dos siste-

mas também precisa de atividades de testes manuais, como testes exploratórios e

testes de aceitação do usuário. Esses testes não podem ser esquecidos e estão

ilustrados na Figura 3 como um círculo na ponta da pirâmide. A maior parte dos tes-

Page 53: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

53

tes de regressão deve ser automatizada ou os testes manuais não darão um bom

retorno sobre o investimento.

A abordagem de pirâmide é uma maneira mais forte, mais benéfica e

econômica de implementar a automação de teste do que colocar o foco em testes

GUI automatizados e inadvertidamente seguindo o anti-padrão “Ice Cream Cone5”

(cone de sorvete), sendo representado pela pirâmide da esquerda na Figura 3. A

pirâmide fornece um forte teste de unidade na base de teste para a partir dela cons-

truir testes adicionais nas fases de integração e UI (Interface do Usuário) enquanto a

abordagem é mais pesada e menos estável. É imperativo seguir a pirâmide de tes-

tes de automação para produzir o melhor software de qualidade possível [43].

Sabendo-se o que deve ser automatizado, mostrado pelas camadas da

pirâmide de automação, será detalhado cada camada nos próximos itens.

5.5.1 Camada base: Testes de Unidade

Um teste de unidade é um pedaço de código que testa uma unidade de

trabalho, um método, uma classe ou um conjunto de classes que implementam uma

única operação lógica, que é acessível por meio de uma interface pública [44].

Quando testar classes de objeto, os testes devem ser projetados para

fornecer cobertura de todos os recursos do objeto. Isso significa que deve [15]:

- Testar todas as operações associadas ao objeto.

- Definir e verificar o valor de todos os atributos associados ao objeto.

- Colocar o objeto em todos os estados possíveis. Isso significa que todos os

eventos que causam uma alteração de estado devem ser simulados.

Os testes unitários possuem as seguintes propriedades:

5 Anti-padrão causado com a inversão da pirâmide, se parecendo com um cone de sorvete, onde o foco principal são os testes de UI. Nesse modo são quase inexistentes os testes de unidade. Testes através da interface do usuário são lentos, aumentando os tempos de compilação e o mais importan-te, esses testes são muito frágeis. Um aprimoramento para o sistema pode facilmente acabar que-brando muitos desses testes, que, em seguida, tem que ser reescritos. Resumindo, esse tipo de teste é muito caro e pode minar a confiança do time e dos usuários.

Page 54: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

54

- Eles são totalmente automatizados. Os testes de unidade podem ser execu-

tados com o mínimo esforço seja através de um IDE, um script de compilação

ou usando uma ferramenta especializada. Programas de driver que são exe-

cutados manualmente não são testes de unidade.

- Eles são auto verificados. A unidade de teste não executa apenas código.

Ele verifica que o código se comporta como esperado (pelo teste) e comunica

esse resultado.

- Eles são repetitivos e consistentes. Eles fornecem as mesmas entradas e

esperam os mesmos resultados para cada execução e podem ser executados

quantas vezes forem necessárias.

- Eles testam um único conceito lógico. Um teste de unidade deve verificar

apenas uma coisa sobre o código testado.

- Eles devem ser isolados. Um teste não é um teste unitário se fala com o ban-

co de dados, se comunica através da rede, acessa o sistema de arquivos,

não pode ser executado ao mesmo tempo que qualquer um dos seus outros

testes unitários, ou realizar configurações especiais de ambiente (como a edi-

ção de arquivos de configuração) para executá-lo.

- Eles são rápidos. Um teste de unidade leva alguns milissegundos para ser

executado. Um conjunto completo de milhares desses testes leva no máximo

alguns minutos. Juntamente com a exigência de isolamento, isso desqualifica

os testes que exigem o acesso a recursos lentos, como redes e bancos de

dados, e testes algoritmicamente complexos.

5.5.2 Ferramentas para Teste de Unidade

Para a realização dos testes de unidade, existem inúmeras ferramentas

no mercado e a escolha de qual será utilizada, dependerá principalmente da lingua-

gem de programação utilizada para implementar os testes. Seguem algumas opções:

- xUnit.net. É uma ferramenta de teste de unidade de código aberto, centrada

na comunidade para o .NET Framework. Escrito pelo inventor original do

NUnit v2, xUnit.net é a mais recente tecnologia para testar unidades C#, F#,

Page 55: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

55

VB.NET e outros idiomas .NET. XUnit.net funciona com ReSharper, Code-

Rush, TestDriven.NET e Xamarin. É parte da Fundação .NET, e opera sob seu

código de conduta e licenciado sob o Apache 2 [47].

- JUnit. É uma ferramenta de código aberto, criado por Erich Gamma e Kent

Beck, com suporte à criação de testes automatizados na linguagem de pro-

gramação Java [48].

5.5.3 Cobertura de Código no teste de unidade

Ferramentas de cobertura de código fornecem uma boa assistência na

escrita, elaboração e manutenção dos testes. Eles mostram graficamente qual códi-

go foi executado nos testes, permitindo saber se o código pretendido foi atingido e

qual código ainda não foi coberto.

Cobertura de código de nenhuma maneira lhe dá uma compreensão exa-

ustiva de como você exercitou seu código. Ela é um guia, não um objetivo. Cober-

tura ajuda a escrever os testes certos para exercer os caminhos de execução sintá-

tica do código. Da mesma forma, a qualidade dos testes escrita depende da habili-

dade e atenção aplicada à tarefa de escrevê-los. A cobertura tem pouco poder para

detectar testes acidentalmente ou deliberadamente de má qualidade.

Use a métrica da cobertura de código como um indicador para identificar

as classes que estão com baixa cobertura. Essas classes podem indicar futuros

problemas, pois não foi alcançado um bom nível de teste.

Não há um número mágico para identificar o quanto de cobertura de teste

é necessário. Conforme dito pelo autor Stephen Vance a partir de 50% de cobertura

já possui um retorno de qualidade, tornado mais significativo quando chega as 80%

[49].

Page 56: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

56

5.6 CAMADA INTERMEDIÁRIA: ACEITAÇÃO, INTEGRAÇÃO, TESTE DE COM-

PONENTE E API

A abordagem do BDD (Behavior-Driven Development) é muito comum

para testes de aceitação e integração, fornecendo uma linguagem não técnica para

escrever testes. Será abordada com detalhes a seguir.

5.6.1 Behavior-Driven Development (BDD)

São um conjunto de práticas de engenharia de software projetado para

ajudar as equipes a construir e entregar software valiosos e de maior qualidade mais

rápido. Baseia-se em práticas ágeis e enxutas, incluindo, em particular, Test-Driven

Development (TDD) e Domain-Driven (DDD). Mas o mais importante é que o BDD

fornece uma linguagem comum baseada em frases simples e estruturadas expres-

sas em inglês (ou na língua nativa das partes interessadas) que facilitam a comuni-

cação entre os membros da equipe do projeto e as partes interessadas do negócio.

O BDD ajuda as equipes a concentrar seus esforços na identificação,

compreensão e construção de recursos valiosos que importam para as empresas, e

garante que esses recursos sejam bem projetados e bem implementados.

Os praticantes do BDD usam conversas em torno de exemplos concretos

de comportamento do sistema para ajudar a entender como os recursos fornecerão

valor ao negócio. O BDD encoraja os analistas de negócios, desenvolvedores de

software e testadores a colaborar mais estreitamente, permitindo que eles expres-

sem os requisitos de uma forma mais testável, de uma forma que tanto a equipe de

desenvolvimento quanto os responsáveis pelo negócio possam entender facilmente.

As ferramentas do BDD podem ajudar a transformar esses requisitos em testes au-

tomatizados que ajudam a orientar o desenvolvedor, verificar o recurso e documen-

tar o que o aplicativo faz.

Page 57: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

57

O BDD não é uma metodologia de desenvolvimento de software por si só.

Não é uma substituição para Scrum [50], XP [51] e RUP [52], ou qualquer metodolo-

gia usada atualmente, incorporando, desenvolvendo e aprimorando ideias de muitas

dessas metodologias.

Apresenta os seguintes benefícios [53]:

- Reduzir Desperdício: BDD é sobre como concentrar o esforço de desenvol-

vimento na descoberta e entrega dos recursos que fornecerão valor de negó-

cios e evitar aqueles que não. Quando uma equipe cria um recurso que não

está alinhado com os objetivos de negócios subjacentes ao projeto, o esforço

é desperdiçado para o negócio. Da mesma forma, quando uma equipe es-

creve um recurso que o negócio precisa, mas de uma forma que não é útil pa-

ra o negócio, a equipe terá que retrabalhar o recurso para caber na conta, re-

sultando em mais desperdícios. O BDD ajuda a evitar esse tipo de esforço

desperdiçado, ajudando as equipes a se concentrar em recursos que estão

alinhados com os objetivos de negócios.

- Reduzir custos: A consequência direta desse desperdício reduzido é a redu-

ção de custos. Ao concentrar-se na construção de recursos com valor de ne-

gócio demonstrável (construção do software certo) e não desperdiçar esforços

em recursos de pouco valor, reduzirá o custo de fornecer um produto viável

para os usuários. E, melhorando a qualidade do código do aplicativo, reduzi-

rá o número de bugs e, portanto, o custo de corrigir esses bugs, bem como o

custo associado aos atrasos que esses bugs causariam.

- O BDD torna consideravelmente mais fácil alterar e estender os aplicativos. A

documentação viva é gerada a partir das especificações executáveis usando

termos com os quais as partes interessadas estão familiarizadas. Isso torna

muito mais fácil para as partes interessadas entender o que a aplicação real-

mente faz. As especificações executáveis de baixo nível também atuam co-

mo documentação técnica para os desenvolvedores, facilitando a compreen-

são da base de código existente e a realização de suas próprias alterações.

- Liberação rápida: As práticas do BDD produzem um conjunto abrangente de

testes de unidade e aceitação automatizados, o que reduz o risco de regres-

sões causadas por quaisquer novas alterações ao aplicativo. Estes abran-

Page 58: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

58

gentes testes automatizados também aceleram o ciclo de lançamento consi-

deravelmente. Testadores não são mais necessários para realizar longas

sessões de testes manuais antes de cada nova versão. Em vez disso, eles

podem usar os testes de aceitação automatizados como ponto de partida e

gastar seu tempo de forma mais produtivo e eficiente em testes exploratórios

e outros testes manuais não triviais.

Exemplo:

Conceitualmente falando, Critérios de Aceite são requisitos necessários

para que uma funcionalidade possa ser considerada completa. Não existem limites

de critérios de aceite nem regras de como eles devem ser descritos, o fundamental é

que todos eles representem um comportamento testável que agregue valor para o

cliente.

Para o bom entendimento do BDD, é fundamental entender como são es-

truturados os critérios de aceite. Para ilustrar esta estrutura, um exemplo de User

Story (História de Usuário) será apresentado conforme a Figura 4. Nesse exemplo,

o papel, o objetivo e a razão de uma funcionalidade serão descritos.

Feature: <description of the feature>

As a <user/actor>

I want <goal to be achieved>

so that <the reason you want to achieve the goal>

Figura 4: Exemplo de formato de user story no BDD

Cada story (funcionalidade) recebe um ou mais Acceptance Criterias (Cri-

térios de Aceite), o que são um substituto dos casos de teste tradicionais que muitos

testadores estão acostumados. São descritos na Figura 5: Exemplo de formato de

critério de aceitação no BDD:

Scenario: <description of the test>

Given <a known state>

When <an event occurs>

Page 59: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

59

Then <then this should happen>

Figura 5: Exemplo de formato de critério de aceitação no BDD

O modelo acima traduzido para o português seria algo como:

Funcionalidade: <descrição da funcionalidade>

Como um <usuário/ator>

Eu quero <meta a ser alcançada>

De modo que <a razão para alcançar a meta>

Cenário: <descrição do teste>

Dado <um estado conhecido>

Quando <um determinado evento ocorre>

Então <isso deve ocorrer> [54]

Um exemplo bem simples de história de uma aplicação de vendas utilizando os for-

matos da Figura 4 e Figura 5 poderia ser: “Venda de balas na doceria”. Demonstrado

pelo exemplo (1).

#language: pt-br

Funcionalidade: Vender doces

Para quando um doce for vendido

Eu, como vendedor

Desejo decrementar um item no estoque

Cenário: Baixa 1 bala do estoque

Dado que cliente pede 1 bala

E tenho 10 balas em estoque

Quando ele realiza a compra

Então eu fico com 9 balas em estoque [55]

(1)

Page 60: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

60

5.6.2 Ferramentas para escrever BDD

- SpecFlow. Ferramenta de código aberto e fornecido sob uma licença BSD,

usando o parser oficial Gherkin e suporta a estrutura .NET, Xamarin e Mono.

O SpecFlow se integra com o Visual Studio, mas também pode ser usado a

partir da linha de comando (por exemplo, em um servidor de compilação). O

SpecFlow suporta outros populares frameworks de teste: MSTest, NUnit (2 e

3), xUnit 2 e MbUnit. Use SpecFlow para definir, gerenciar e executar auto-

maticamente testes de aceitação legível em projetos .NET [56].

- RSpec. É uma ferramenta de teste para Ruby, criada para desenvolvimento

orientado por comportamento (BDD). É a biblioteca de testes mais utilizada

para Ruby em aplicações de produção. Mesmo que tenha um rico e poderoso

DSL (Domínio de Linguagem Específica), o seu núcleo é uma ferramenta

simples com uma pequena curva de aprendizado [57].

5.6.3 Teste de API e componentes

Uma API (Interface de Programação de Aplicativo) é uma coleção de fun-

ções que podem ser executadas por outros aplicativos de software ou componentes.

O usuário final geralmente nunca sabe que existe uma API, interagindo apenas com

a interface final.

Cada chamada de API tem uma função específica com um número de

parâmetros que aceitam entradas diferentes. Cada variação retornará um resultado

diferente. Cada chamada pode ser desenvolvida cedo no ciclo de vida de uma apli-

cação, o que significa que o teste também pode ocorrer cedo junto com o desenvol-

vimento. Testar através de uma API pode trazer confiança ao sistema antes de tes-

tes complicados da camada de UI.

Page 61: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

61

5.6.4 Ferramentas de Teste para API e componentes

- Fit (Framework for Integrated Tests): É um framework de teste de código

aberto que promove a colaboração, o que o torna uma boa ferramenta para

ajudar a refinar os requisitos. O Fit permite que os clientes, testadores e pro-

gramadores usem exemplos para especificar o que esperam que o sistema

faça. Quando os testes são executados, o Fit compara automaticamente as

expectativas dos clientes com os resultados reais. Com o Fit, os clientes po-

dem fornecer orientação usando os seus conhecimentos especializados para

definir os exemplos que os programadores podem codificar contra. Os pro-

gramadores participam escrevendo os textos que fazem os cheques reais

contra os exemplos. Esses arquivos usam os dados especificados nos exem-

plos para serem executados com o programa real [58].

- FitNesse: É um servidor web, uma wiki e uma ferramenta de teste de software

baseada no Fit. Originalmente desenvolvido por Robert C. "Tio Bob" Martin e

Micah Martin, é uma ferramenta de código aberto com uma comunidade de

desenvolvedores ativos. A principal diferença entre FitNesse e Fit é que os

testes FitNesse são escritos em marcação wiki em vez de tabelas HTML, o

que alguns usuários acham mais fácil. Ele também suporta a criação de tes-

tes em planilhas e importá-las para os testes [59].

Outro benefício de um tipo de ferramenta Fit ou FitNesse é que ele pro-

move a colaboração entre diferentes membros da equipe, a fim de chegar aos testes

certos para orientar o desenvolvimento. Clientes, programadores, testadores e ou-

tros trabalham juntos para especificar e automatizar os testes.

Page 62: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

62

5.6.5 Web Services (Serviços Web)

Os serviços da Web são uma arquitetura baseada em serviços que forne-

cem uma interface externa para que outros possam acessar o sistema. São seme-

lhantes à API, mas são acessíveis através de protocolos HTTP.

5.6.6 Ferramentas de Teste WebService

As mesmas ferramentas de teste de API poderiam ser utilizadas. Porém,

existem outras ferramentas especializadas em serviços Web que poupam bastante

trabalho no momento de escrever o teste.

- SOAPSonar: É um exemplo de uma ferramenta para testar serviços da web.

Basta fornecer o WSDL (Web Services Description Language); SOAPSonar

compila a página e, em seguida, apresenta-lhe um menu com guias que con-

tém caixas de texto para preencher. Possui um modo de execução que per-

mite adicionar os testes a um conjunto e, em seguida, executa-los [60].

- SoapUI: Tem uma boa curva de aprendizado, mas pode ser usado para testes

de desempenho, carga e segurança. Como ele pode executar um loop de li-

nhas em uma planilha do Excel ou em um arquivo de texto, ele pode ser usa-

do para testes de dados [61].

5.7 CAMADA SUPERIOR: TESTE DE UI

Nos últimos anos, a comunidade ágil veio com padrões e práticas mais

eficazes para projetar testes automatizados que entregam um grande ROI. Isso é

Page 63: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

63

verdadeiro para todos os níveis de automação, incluindo os testes de regressão que

são executados através da interface do usuário.

Automatizar os testes que exercem a interface do usuário da aplicação

continua a apresentar os desafios mais difíceis. Muitas equipes têm investido tempo

e dinheiro para automatizar testes de interface do usuário, apenas para encontrar o

um bom custo de manutenção a longo prazo [62].

5.7.1 Ferramentas para Teste de UI

Estas ferramentas fornecem uma variedade de maneiras de verificar a

navegação correta e o conteúdo das páginas, como etapas específicas de verifica-

ção de ferramenta ou XPath. Algumas dessas ferramentas têm uma curva de

aprendizado mais alta do que as ferramentas simples de gravação/reprodução, mas

o investimento extra de tempo geralmente compensa em scripts com um baixo custo

total de propriedade.

Implementar uma nova ferramenta de automação de teste geralmente

requer alguma experimentação para obter um bom equilíbrio de código testável e

scripts de teste bem projetados. Envolver toda a equipe torna isso muito mais fácil.

- Watir: É uma biblioteca de Ruby de código aberto simples para automatizar

navegadores da Web que funciona com o Internet Explorer no Windows. Exis-

tem diferentes plug-ins para outros navegadores, incluindo FireWatir para

Firefox e SafariWatir para Safari [63].

- Selenium. É um conjunto de ferramentas de código aberto para testes de

aplicações Web. Os testes podem ser escritos como tabelas HTML ou codifi-

cados em várias linguagens de programação e scripts populares, incluindo

Java, C # e Ruby, e podem ser executados diretamente na maioria dos nave-

gadores modernos. Um plug-in do Firefox chamado "Selenium IDE" fornece

uma maneira de aprender a ferramenta rapidamente. Um gravador é forneci-

do para ajudar a criar os testes, incluindo asserções de escrita [64].

Page 64: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

64

6 MÉTODOS FORMAIS

Métodos formais incluem todas as abordagens de análise de software ba-

seadas em matemática e lógica, incluindo análise, verificação de tipo, desenvolvi-

mento baseado em modelo e correção por construção. Métodos formais podem aju-

dar desenvolvedores de software a obterem maior garantia de que classes inteiras

não possuem vulnerabilidades, e também podem ajudar a reduzir ciclos imprevisí-

veis de testes caros e correção de erros [65].

Existem vários tipos de métodos formais. Aqueles que serão apresenta-

dos a seguir possuem o maior impacto na detecção e correção de defeitos e vulne-

rabilidades.

6.1 ANÁLISE ESTÁTICA

O termo análise estática refere-se a qualquer processo para avaliar o có-

digo sem executá-lo. A análise estática é poderosa porque permite a rápida conside-

ração de muitas possibilidades. Uma ferramenta de análise estática pode explorar

um grande número de cenários sem ter que passar por todos os cálculos necessá-

rios para executar o código para todos os cenários. A análise estática é particular-

mente adequada à segurança porque muitos problemas de segurança ocorrem em

casos e estados diferenciados, que podem ser difíceis de serem alcançados pela

execução do código. Boas ferramentas de análise estática fornecem uma maneira

rápida de obter uma avaliação consistente e detalhada do código [66].

As métricas estáticas de análise de código são métricas técnicas. É pos-

sível detectar problemas ou potenciais problemas no software analisando o código

fonte, sem compilar ou executar. As informações disponibilizadas por esses tipos de

ferramenta podem fornecer uma riqueza de informações sobre a qualidade do códi-

go automaticamente. Com base nesse feedback, a equipe pode tomar medidas pa-

ra melhorar a qualidade.

Page 65: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

65

A razão para se preocupar com a qualidade do código é que o código

complicado e confuso é difícil de modificar com segurança. Isso faz com que cada

aprimoramento de recursos ou manutenção demore mais tempo e custe mais dinhei-

ro do que o necessário, além dos defeitos que a alteração possa causar. O acúmulo

de problemas técnicos ao longo do tempo é chamado de dívida técnica ou dívida de

design, e é uma das principais causas de desaceleração no desenvolvimento e de

morte prematura dos sistemas de produção.

As ferramentas estáticas de análise de código geralmente se concentram

em sete áreas-chave, conhecidas como os sete eixos de qualidade do código ou os

sete pecados mortais dos programadores [67]:

- Complexidade. As ferramentas de análise de código estáticas procuram um

par de tipos de complexidade. A primeira é a complexidade ciclomática, que

verifica a profundidade das instruções condicionais aninhadas no código. Um

valor alto para a complexidade ciclomática pode significar que o código é difí-

cil de entender e, portanto, difícil de modificar com segurança. Em alguns ca-

sos, isso só pode significar que a seção de código em questão é complicada.

O segundo tipo de complexidade é conhecido como “Resposta para a Classe”

(RFC), e se aplica principalmente a linguagens de programação orientada a

objetos. O algoritmo é baseado na contagem do número total de chamadas

de método e o número de chamadas de método exclusivo em uma classe. A

complexidade excessiva de qualquer tipo pode tornar o código difícil de en-

tender, bem como demorado e arriscado para mudar.

- Duplicação. Fragmentos de código idêntico em vários locais na base de có-

digo. Também pode haver formas menos óbvias de duplicação, como fun-

ções ou métodos que executam quase o mesmo processamento e que dife-

rem apenas de maneira superficial, ou utilitários em diferentes pacotes de ter-

ceiros que executam as mesmas funções ou classes em pacotes diferentes

que tem responsabilidades semelhantes ou sobrepostas.

- Cobertura de teste. Os testes unitários são o conjunto de testes automatiza-

dos mais finos aplicados a uma base de código. As ferramentas de análise

de código estático podem facilmente verificar a cobertura de código no nível

da unidade. A cobertura adequada depende do nível de validação incorpora-

do na própria linguagem de programação e da quantidade de código que po-

Page 66: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

66

de ser gerada automaticamente por ferramentas de desenvolvimento. Cem

por cento de cobertura de teste não é geralmente necessário ou desejável,

mas em geral uma cobertura mais elevada é melhor do que uma cobertura

mais baixa.

- Padrões de codificação. Uma base de código que geralmente segue as

mesmas convenções para nomes e estrutura tenderá a ser menos propensa a

erros e mais fácil de manter do que uma base de código que exibe um misto

de diferentes convenções e estilos.

- Comentários. Código que inclui comentários de fonte excessiva pode ser

confuso, tanto por causa da desorganização geral criada pelos comentários,

quanto porque os comentários tendem a ficar rapidamente fora de sincronia

com o código que descrevem. Por outro lado, há ocasiões em que comentá-

rios explicativos ajudam as pessoas a entender a intenção do código ou aler-

tam sobre possíveis efeitos colaterais quando o código é modificado. Ferra-

mentas de análise de código estático podem aplicar heurísticas para avisá-lo

quando parece que há muitos ou muito poucos comentários no código-fonte.

As linhas de origem que são comentadas e deixadas no local também são

questionáveis.

- Bugs potenciais. Algumas ferramentas estáticas de análise de código procu-

ram padrões estruturais no código que podem levar a problemas previsíveis

em termos de manutenção, segurança, testabilidade eficiência, confiabilidade,

portabilidade e fatores semelhantes. Estes podem fornecer alertas úteis de

problemas potenciais.

- Problemas de arquitetura. Padrões estruturais no código podem apontar para

problemas de arquitetura. A análise estática de código pode identificar os ar-

quivos de código-fonte que têm os problemas estruturais mais graves. Isso

ajuda a equipe a entender quais arquivos são dignos de atenção para refato-

ração para reduzir a dívida técnica. Em aplicações grandes e complicadas

que compreendem múltiplos componentes implementáveis separadamente,

as dependências circulares ou cíclicas entre componentes podem levar a sé-

rios problemas na construção e implantação da aplicação. Isso significa que

um módulo no componente A tem uma dependência de um módulo no com-

ponente B e um módulo diferente no componente B tem uma dependência em

Page 67: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

67

algum outro módulo no componente A. Um programador trabalhando em um

pequeno subconjunto da base de código pode ignorar esse tipo de problema,

mas as ferramentas de análise estáticas de código podem indicar o problema.

Algumas ferramentas podem validar a estrutura da base de código contra um

conjunto de restrições de arquitetura definidas pela equipe. Isso pode prote-

ger contra o acesso inadequado em diferentes camadas ou níveis da arquite-

tura no aplicativo. As dependências entre os componentes do aplicativo e bi-

bliotecas de terceiros podem ser detectadas e relatadas por ferramentas está-

ticas de análise de código. Essas informações podem ajudar as equipes a

identificar possíveis oportunidades de melhoria da qualidade do código, bem

como a exposição a bugs relatados em bibliotecas.

Uma diretriz geral para o bom design de software é lutar pela alta coesão

e baixo acoplamento. Os dois variam geralmente inversamente um em relação

aos outros. Acoplamento refere-se ao grau em que diferentes módulos depen-

dem uns dos outros, ou devem saber uns sobre os outros. A regra de ouro sobre

alta coesão e baixo acoplamento se aplica a qualquer código-fonte e não é espe-

cífico para qualquer paradigma de programação. Ferramentas estáticas de análi-

se de código podem procurar padrões estruturais que sugerem alto acoplamento

[67].

6.1.1 Ferramentas para análise estática

Existem bastantes ferramentas no mercado para realizar análise estática,

mas o mais popular é o SonarQube [68].

Sonar é uma plataforma de qualidade de código livre e aberto. Ele coleta

e analisa o código fonte, medindo a qualidade e fornecendo relatórios para os proje-

tos. Ele combina ferramentas de análise estática e dinâmica e permite que a quali-

dade seja medida continuamente ao longo do tempo. Mais de 600 regras de código

são incorporadas na plataforma, verificando o código de diferentes perspectivas.

Page 68: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

68

As regras são separadas em grupos lógicos diferentes e cada uma contri-

bui em um nível diferente para a qualidade geral do projeto no caso. Os resultados

da análise, as violações de código e os dados históricos estão disponíveis e acessí-

veis através de uma interface de usuário, composta por diferentes componentes,

cada um servindo e atendendo a diferentes necessidades e escopos.

A plataforma analisa o código fonte de diferentes aspectos. Para conse-

guir isso, o Sonar detalha o código, camada por camada, passando do nível do mó-

dulo para o nível da classe. Em cada nível, a Sonar realiza análise estática e dinâ-

mica produzindo valores métricos e estatísticas, revelando áreas problemáticas na

fonte que requerem inspeção ou melhoria. A análise não é um procedimento monolí-

tico, mas examina o código de diferentes perspectivas, introduzindo o conceito de

eixos de qualidade. Os resultados são então interpretados e consolidados em um

painel informativo, exemplificado pela Figura 6, permitindo formar uma opinião sobre

o código defeituoso e testes de qualidade sobre os projetos [69].

Page 69: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

69

Figura 6: Exemplo do painel do SonarQube [70]

O Sonar trabalha visando os “Sete Eixos de Qualidade” exibindo em cada

widget. Os mais importantes para este trabalho serão mostrados nas seções a se-

guir.

6.1.2 Bugs potenciais e regras de código

Como parte da análise, o SonarQube compara seu código a um conjunto

de regras. Quando uma regra é quebrada, um problema é marcado com a linha on-

de ocorreu. Os problemas são relatados em uma das cinco severidades: Blocker,

Critical, Major, Minor e Info, exemplificados pela Figura 7. O nível de seriedade está

indicado em ordem decrescente.

Page 70: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

70

Figura 7: Exemplo do widget de bugs potencias e regras de código

Basicamente o SonarQube quebra os problemas em seis categorias ge-

rais que são categorizados nas severidades. Segue a lista pela ordem de importân-

cia:

- Bugs: Problemas na categoria de bugs são garantidos por serem um proble-

ma.

- Bugs potenciais: como acontece com bugs, representam problemas reais no

código. Muitas vezes, porém, eles são problemas condicionais, aqueles que

só acontecerão em algum estado ou condição específica. Problemas de se-

gurança também estão nesta categoria.

- Indicações de erro (potencial) do programador: ao contrário das duas primei-

ras categorias, não é garantido que irão causar problemas.

- Ineficiências: Os problemas nesta categoria não farão com que o programa

deixe de executar corretamente e nem levará a problemas futuros. Porém, fa-

rão com que o programa rode com pior desempenho.

- Incoerências no estilo: O programa listará os problemas de estilo de codifica-

ção, baseando-se nas regras configuradas. Por serem deixados para o final,

não quer dizer que não sejam importantes. Estes problemas podem tornar o

código difícil de manter e favorecer a introdução de bugs (devido à baixa legi-

bilidade).

Page 71: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

71

6.1.3 Cobertura e testes

Neste widget, exemplificado pela Figura 8, são exibidos a cobertura dos

testes unitários e métricas dos testes, mostrando a quantidade de testes na aplica-

ção, quantos estão com erro, quantos não foram executados e o tempo total de exe-

cução dos testes.

Figura 8: Exemplo do widget de cobertura e testes

Conforme mencionado anteriormente, a cobertura de código serve como

um guia para a qualidade do software. Baixa cobertura poderá indicar instabilidade

com o programa, devido a cenários que não foram testados.

6.1.4 Comentário

Existem dois tipos principais de comentários de código: na linha em qual-

quer método (público ou privado) que se destinam dar alguns detalhes da lógica do

código, e os fora de um método público que se destinam a comunicar como e por

que usá-los (os comentários da API). O primeiro tipo é muitas vezes referido como

um “code smell6”. Esse tipo de comentário tende a ficar obsoleto, a lógica muda,

mas os comentários não ou os comentários ficam separados do que eles se referem.

6 É um termo usado para evidenciar que algo no código não faz sentido (falta de coesão).

Page 72: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

72

O segundo tipo de comentário (a documentação da API) é o que é medido pelo So-

nar.

Esta é uma métrica de manutenção. Ela olha para quantas vezes o cha-

mador do método lerá o código para entender o que está implementado, em compa-

ração com a documentação intencional que (idealmente) explica o que deve ser

passado, o que será devolvido e talvez até mesmo o que acontecer entre isso.

Comentários são medidos porque eles são parte do que torna um sistema

fácil (ou não) para trabalhar. A sua falta pode ocasionar um mal-uso da API, deixan-

do a aplicação em um estado inesperado. Eles são medidos com a ideia de que os

programadores devem gastar seu tempo escrevendo os sistemas que os seus usuá-

rios precisam, não tentando descobrir o que a última pessoa pensou que estava fa-

zendo quando codificou o método.

Figura 9: Exemplo do widget de comentário

O Sonar, apresentado na Figura 9, mostra a quantidade absoluta de li-

nhas comentadas, percentual da API que foi documentada, quantidade de linhas da

API pública que não foram comentadas e o percentual de linhas comentadas basea-

do na quantidade de comentários e linhas de código.

6.1.5 Duplicação

Do not Repeat Yourself (DRY) é um princípio de engenharia de software

que deve ser aplicado a todos os aspectos de um projeto de software. Concentra-se

em minimizar ou eliminar duplicações entre os recursos de um sistema, especial-

mente no código.

Page 73: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

73

Um dos conceitos básicos do DRY é que é mais eficiente e produtivo

manter uma única cópia de cada recurso do que manter várias cópias. Isso é por-

que ter várias cópias de qualquer coisa, quer dados ou algoritmos, não só significa

mais trabalho quando há mudanças, mas também pode significar que pode acabar

com algumas cópias desatualizadas, que é o efeito colateral mais perigoso da dupli-

cação.

Código duplicado é responsável por muitos bugs, e pode ter grandes im-

pactos especialmente em sistemas que estão em constante evolução para refletir as

necessidades do mercado.

Figura 10: Exemplo do widget de duplicação de código

O Sonar, conforme mostra a Figura 10, mostra a quantidade absoluta de

linhas envolvida em duplicação, quantidade absoluta de blocos de código duplicados,

o número absoluto de arquivos fontes que contém linhas duplicadas e o percentual

de linhas duplicadas de acordo com o número total de linhas do projeto.

6.1.6 Arquitetura e design

O widget de design do pacote, exemplificado pela Figura 11, mostra o

quão limpa está implementação de design, dando-lhe números de alto nível que in-

dicam quanto trabalho precisa ser feito para tornar a implementação mais limpa com

um bom design.

Page 74: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

74

Figura 11: Exemplo do widget de arquitetura e design

Para entender melhor, imagine uma pequena aplicação dividida em três

bibliotecas. Ao longo do tempo, cada biblioteca evoluiu para depender das demais,

criando, assim, ciclos. Em certo ponto não se pode atualizar uma biblioteca sem

alterar também as outras. Devido aos ciclos de dependência, mudanças simples

que devem ser fáceis levam três vezes mais tempo para serem concluídas.

Detectar esse tipo de dependência circular no nível da biblioteca é o foco

desse widget, mostrado na Figura 11,. Ele é dividido em duas partes. No lado es-

querdo, apresenta uma métrica denominada Package Tangle Index e o número de

ciclos de pacotes detectados durante a análise. À direita, o widget relata dependên-

cias indesejadas entre pacotes e arquivos. Estas são as dependências que devem

ser cortadas para remover os ciclos de bibliotecas. Para a imagem exibida, seria

necessário corrigir 35 dependências de bibliotecas envolvendo 51 arquivos para lim-

par seus ciclos de dependência.

Essa métrica indica o quanto será difícil entender e manter o código no

futuro. Os ciclos de dependência podem diminuir a produtividade, a manutenção e a

compatibilidade do projeto.

6.1.7 Complexibilidade

O Sonar reporta a complexidade ciclomática que essencialmente trata de

quantos pares de chaves (reais ou implícitas) o método tem. A premissa deste indi-

cador principal é que quanto mais pares de chaves existirem, mais complexa será a

lógica. E quanto mais complexa é a lógica, mais difícil é entender e manter.

Page 75: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

75

Figura 12: Exemplo do widget de complexibilidade

Os números no widget, exemplificado pela Figura 12, são médias: com-

plexidade média por método, classe e arquivo. O número na parte inferior é a com-

plexidade geral do aplicativo, que é a soma das partes. O gráfico no lado direito do

widget mostra a distribuição de complexidade entre métodos ou arquivos, com base

na opção selecionada.

Um alto nível de complexidade diminui a capacidade de manutenção de

um arquivo e aumenta o tempo necessário para entender o código. Além disso, a

alta complexidade torna difícil testar um método de forma adequada [71].

6.2 SEGURANÇA

A análise estática é bem adequada para identificar problemas de segu-

rança por uma série de razões:

- As ferramentas de análise estática aplicam as verificações cuidadosamente e

consistentemente, sem qualquer preconceito que um programador possa ter

sobre quais pedaços de código são "interessantes" sob a perspectiva de se-

gurança ou quais pedaços de código são fáceis de exercer através de testes

dinâmicos.

- Ao examinar o código em si, as ferramentas de análise estática muitas vezes

podem apontar para a causa raiz de um problema, e não apenas um de seus

sintomas. Isto é particularmente importante para garantir que as vulnerabili-

dades sejam corrigidas corretamente.

Page 76: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

76

- A análise estática pode encontrar erros no início do desenvolvimento, mesmo

antes de o programa ser executado pela primeira vez. Encontrar um erro ce-

do não só reduz o custo de corrigir o erro, mas o ciclo de feedback rápido po-

de ajudar a orientar o trabalho de um programador. Um programador tem a

oportunidade de corrigir erros que não estava ciente anteriormente que pode-

rá acontecer. Os cenários de ataque e as informações sobre as construções

de código usadas por uma ferramenta de análise estática agem como um

meio de transferência de conhecimento.

- Quando um pesquisador de segurança descobre uma nova variedade de ata-

ques, as ferramentas de análise estática facilitam a verificação de um grande

corpo de código para ver onde o novo ataque pode ser bem-sucedido. Alguns

defeitos de segurança existem no software por anos antes de serem desco-

bertos, o que torna a capacidade de rever o código herdado para os tipos de

defeitos recentemente descobertos de valor inestimável.

A reclamação mais comum contra as ferramentas de análise estática que

visam a segurança é que produzem muitos falsos positivos, também conhecidos

como falsos alarmes. Neste contexto, um falso positivo é um problema relatado em

um programa quando nenhum problema realmente existe. Um grande número de

falsos positivos pode causar uma grande dificuldade. Não só caminhar através de

uma longa lista de falsos positivos é cansativo, faz com que um programador possa

ignorar resultados importantes que estão nela.

Falso positivos são certamente indesejáveis, mas a partir de uma pers-

pectiva de segurança, falsos negativos são muito piores. Com um falso negativo,

existe um problema no programa, mas a ferramenta não o denúncia. A penalidade

para um falso positivo é a quantidade de tempo desperdiçado ao rever o resultado.

A penalidade para um falso negativo é muito maior. Não só porque pagará o preço

associado por ter uma vulnerabilidade no código, mas viverá com uma falsa sensa-

ção de segurança decorrente do fato de que a ferramenta fez parecer que tudo esta-

va bem.

Todas as ferramentas de análise estática são garantidas para produzir

alguns falsos positivos ou alguns falsos negativos. O equilíbrio que uma ferramenta

atinge entre falsos positivos e falsos negativos é muitas vezes indicativo do propósi-

Page 77: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

77

to da ferramenta. O equilíbrio certo é bastante diferente para as ferramentas de

análise estática que se destinam a detectar bugs diversos e ferramentas de análise

estática que visam especificamente defeitos relevantes para a segurança. O custo

de não detectar um defeito é pequeno, porque várias técnicas e processos podem

ser aplicados para se certificar de que os erros mais importantes são capturados.

Por esta razão, as ferramentas de qualidade de código geralmente tentam produzir

um baixo número de falsos positivos e estão mais dispostas a aceitar falsos negati-

vos. Segurança é uma história diferente. A penalidade para bugs de segurança ig-

norados é alta, então as ferramentas de segurança geralmente produzem mais fal-

sos positivos para minimizar os falsos negativos.

Na prática, o importante é que as ferramentas de análise estática forne-

cem resultados úteis. O fato de serem imperfeitos não os impede de ter um valor

significativo. Na verdade, a natureza da análise estática não é realmente o principal

fator limitante para as ferramentas de análise estática. Os principais fatores práticos

que determinam a utilidade de uma ferramenta de análise estática são:

- Fazer sentido ao programa, construindo um modelo preciso

- Fazer bons compromissos entre precisão, profundidade e escalabilidade

- Procurar o conjunto certo de defeitos.

- Apresentar resultados e erros fáceis de entender.

- Integração fácil com o sistema de compilação e ambientes de desenvolvimen-

to integrados [66].

6.2.1 Ferramenta

O SonarQube possui alguns plug-ins com algumas métricas de segurança

como o FindBugs [72], mas somente está disponível para a linguagem Java.

Existem outras ferramentas de análise estática focadas em segurança.

As mais populares são o Checkmarx [73], Coverity [74] e Fortify [75].

Page 78: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

78

6.3 ANÁLISE DINÂMICA

A análise dinâmica é a análise de software de computador que é executa-

da enquanto programas são executados em um processador real ou virtual em tem-

po real. O objetivo é encontrar erros de segurança em um programa enquanto ele

está em execução, em vez de examinar repetidamente o código off-line. Ao depurar

um programa em todos os cenários para os quais foi concebido, a análise dinâmica

elimina a necessidade de criar artificialmente situações susceptíveis de produzir er-

ros. Ele tem as vantagens distintas de ter a capacidade de identificar vulnerabilida-

des que poderiam ter sido falsos negativos e validar resultados da análise de código

estático.

A análise dinâmica também é conhecida como Teste Dinâmico de Segu-

rança de Aplicativos (DAST), identificando vulnerabilidades dentro de um aplicativo

de produção. As ferramentas DAST são usadas para avaliar rapidamente a segu-

rança geral de um sistema.

A análise dinâmica possui os seguintes benefícios:

- Não há acesso a instruções reais sendo executadas.

- Requer apenas um sistema em execução para executar um teste.

- Nenhuma exigência para ter acesso ao código fonte ou código binário.

- Não há necessidade de entender como escrever software ou executar compi-

lações.

- Testa uma implantação operacional específica.

- Identifica vulnerabilidades em um ambiente de tempo de execução.

- As ferramentas automatizadas fornecem flexibilidade sobre o que procurar.

- Permite a análise de aplicações sem acesso ao código real, podendo ser rea-

lizado em qualquer aplicação.

- Identifica vulnerabilidades que podem ter sido falsas negativas na análise de

código estático e permite a validação dos resultados obtidos pela análise es-

tática [38].

Page 79: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

79

6.3.1 Ferramenta para análise dinâmica

A Open Web Application Security Project (OWASP) é uma entidade sem

fins lucrativos e de reconhecimento internacional, que contribui para a melhoria da

segurança de softwares aplicativos reunindo informações importantes que permitem

avaliar riscos de segurança e combater formas de ataques através da internet.

Os estudos e documentos da OWASP são disponibilizadas para toda a

comunidade internacional, e adotados como referência por entidades como U.S. De-

fense Information Systems Agency (DISA), U.S. Federal Trade Commission, várias

empresas e organizações mundiais das áreas de Tecnologia, Auditoria e Segurança,

e também pelo PCI Council [76].

A OWASP possui uma grande lista de recomendações de ferramentas e

uma delas é o ZAP [77]. O WASP Zed Attack Proxy (ZAP) é uma das ferramentas

de segurança gratuitas e de código fonte aberto mais populares do mundo e é man-

tido ativamente por centenas de voluntários internacionais. Ele ajuda a encontrar

automaticamente vulnerabilidades de segurança em aplicativos da Web enquanto

estiver desenvolvendo e testando as aplicações. É também uma ótima ferramenta

para profissionais experientes utilizarem para testes manuais de segurança.

As principais funcionalidades do Zap são:

- Proxy de interceptação. Ele permite ver todos os pedidos realizados para um

aplicativo da Web e todas as respostas que recebe dele.

- Tradicional and AJAX spiders. O Spider é uma ferramenta que é usada para

descobrir automaticamente novos recursos (URLs) em um determinado site.

Ele começa com uma lista de URLs para visitar, chamado de sementes. O

Spider então visita esses URLs, identificando todos os hiperlinks na página e

os adiciona à lista de URLs a visitar e o processo continua recursivamente

enquanto novos recursos forem encontrados.

- Scanner automático. A verificação ativa tenta encontrar possíveis vulnerabili-

dades usando ataques conhecidos contra os destinos selecionados. Vulnera-

bilidades lógicas, como controle de acesso interrompido, não serão encontra-

das por qualquer verificação de vulnerabilidade ativa ou automatizada. Testes

Page 80: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

80

de penetrações manuais devem sempre ser realizados além de verificação

ativa para encontrar todos os tipos de vulnerabilidades.

- Scanner Passivo. Por padrão, o ZAP verifica passivamente todas as mensa-

gens HTTP (solicitações e respostas) enviadas para o aplicativo da Web que

está sendo testado. A varredura passiva não altera os pedidos nem as res-

postas de forma alguma e, portanto, é seguro de usar. A varredura é realiza-

da em um segmento de plano de fundo para garantir que não atrasará a ex-

ploração de um aplicativo [78].

Page 81: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

81

7 ABORDAGENS NÃO TÉCNICAS

A Engenharia de Software está principalmente voltada para o desenvolvi-

mento de software que satisfaça requisitos funcionais e não funcionais. No en-

tanto, desenvolvedores não são influenciados apenas por determinados requisi-

tos e restrições. A qualidade, estrutura e outras características dos sistemas de

softwares desenvolvidos também dependem da formação dos programadores,

sua experiência de trabalho, estratégias de resolução de problemas, estrutura

organizacional e relações sociais.

A importância dos fatores não técnicos no desenvolvimento dos sistemas

de informação é reforçada por uma pesquisa, que afirma que 90% das falhas do

projeto podem ser atribuídas a falhas não técnicas (sociais, organizacionais, etc.).

Portanto, um processo de design de software não é meramente uma tarefa técni-

ca, mas também há um processo social incorporado nas estruturas organizacio-

nais e culturais. Estas estruturas influenciam e governam o comportamento de

trabalho dos programadores e seus produtos finais, como o código e documenta-

ção [79].

O cultivo de pessoas motivadas e altamente qualificadas de software tem

sido discutido desde a década de 1960. De fato, o "fator pessoas" é tão importan-

te que o Instituto de Engenharia de Software desenvolveu um Modelo de Maturi-

dade de Capacidade de Pessoas (CMM), em reconhecimento ao fato de que "to-

da organização precisa melhorar continuamente sua capacidade de atrair, de-

senvolver, motivar, organizar e reter a força de trabalho necessária para atingir

seus objetivos estratégicos de negócios.

O modelo de maturidade de capacidade de pessoas define as seguintes

áreas de prática chave para pessoas envolvidas com software: pessoal, comuni-

cação e coordenação, ambiente de trabalho, gerenciamento de desempenho,

treinamento, compensação, análise e desenvolvimento de competências, desen-

volvimento de carreira, desenvolvimento de grupo de trabalho, desenvolvimento

de equipe/cultura e outras. As organizações que alcançam altos níveis de matu-

ridade de Pessoas-CMM têm maior probabilidade de implementar práticas efica-

zes de gerenciamento de projetos de software [14].

Page 82: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

82

Diversos fatores influenciam a qualidade de um produto, veremos alguns

nas seções seguintes.

7.1 EDUCAÇÃO E TREINAMENTO

O treinamento visa possibilitar mecanismos de capacitação e aperfeiçoa-

mento profissional, como também oferecer instrumentos de desenvolvimento pesso-

al. Treinar significa o preparo da pessoa para uma tarefa ou cargo, enquanto o pro-

pósito da educação é o de preparar a pessoa para o ambiente dentro ou fora do seu

trabalho.

O treinamento é uma atividade que visa fornecer novos conhecimentos,

desenvolver comportamentos necessários para o bom andamento do trabalho e re-

duzir a dívida técnica e na época de hoje. Sua maior missão é de conscientizar os

funcionários da importância de autodesenvolver-se e de buscar o aperfeiçoamento

contínuo. Tem como principais benefícios, o aumento da produtividade, redução de

custos, qualificação da mão de obra e menor rotatividade dos funcionários [80].

Educação não trata apenas do ensino a desenvolvedores sobre como es-

crever melhor software. Ela também inclui educar os usuários sobre como se especi-

ficar melhor o software, e gerentes sobre como configurar ambientes que resultam

em software de qualidade superior. Além disso, a educação e a formação são o

principal mecanismo para a transição das abordagens técnicas discutidas neste tra-

balho.

O treinamento é um elemento crítico no desenvolvimento seguro de sof-

tware que requer o elemento humano. O treinamento ajuda a reduzir o custo da se-

gurança e um programa de treinamento eficaz motivará a equipe de desenvolvimen-

to a produzir softwares mais seguros com menos problemas, mais eficiência e eco-

nomia. Deve-se enfatizar que nenhuma solução pontual fornecerá uma solução úni-

ca para a segurança do software. Em vez disso, é necessária uma abordagem pro-

funda incluindo uma mistura de pessoas, processos e tecnologia. Embora as ferra-

mentas possam analisar através de grandes quantidades de código rapidamente,

elas não são substitutas para os seres humanos. No futuro previsível, a segurança

Page 83: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

83

do software ainda será considerada uma arte, mas a arte pode ser aumentada atra-

vés do processo e da tecnologia e, contrariamente aos mitos, a arte pode ser ensi-

nada através de mentores adequados.

Ao longo dos últimos anos, tem havido uma mudança de foco no ensino

superior para incluir uma maior ênfase na concepção de software com segurança. A

educação também tem visto crescimento nos esforços de segurança tanto do usuá-

rio quanto do produtor de software. Entender os princípios de segurança é essencial

para garantir que o software seja seguro e utilizável. Os gerentes e executivos tam-

bém devem ser educados nas implicações de gerenciamento de risco de vulnerabili-

dades de softwares, para entender a importância de investir em softwares de segu-

rança e de baixa vulnerabilidade [38].

7.2 MOTIVACIONAL

Motivação significa organizar o trabalho e o ambiente de trabalho para

incentivar as pessoas a trabalhar o mais eficazmente possível. Se as pessoas não

estão motivadas, não estarão interessadas no trabalho que estão fazendo. Eles tra-

balharão lentamente, terão maior probabilidade de cometer erros e não contribuirão

para os objetivos mais amplos da equipe ou da organização.

Para dar esse incentivo, será necessário entender um pouco sobre o que

motiva as pessoas. O psicólogo americano Abraham H. Maslow sugere que as pes-

soas são motivadas por satisfazer suas necessidades. Essas necessidades são or-

ganizadas em uma série de níveis, como mostrado na Figura 13. Os níveis mais

baixos dessa hierarquia, que são as necessidades fisiológicas, representam neces-

sidades fundamentais de alimentação e sono. Seguindo em diante, encontra-se a

necessidade de segurança que é a necessidade de se sentir seguro em um ambien-

te. As necessidades sociais dizem respeito à necessidade de se sentirem parte de

um agrupamento social. As necessidades de autoestima representam a necessida-

de de se sentirem respeitadas pelos outros, e as necessidades de auto realização

preocupam-se com o desenvolvimento pessoal. As pessoas precisam satisfazer ne-

Page 84: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

84

cessidades de nível inferior antes das necessidades mais abstratas e de nível mais

alto.

Figura 13: Exemplo da pirâmide de Maslow. [81]

Pessoas que trabalham em organizações de desenvolvimento de software

não estão geralmente com fome ou sede ou fisicamente ameaçadas por seu ambi-

ente. Portanto, o ponto mais importante é que as necessidades sociais das pessoas,

estima e auto realização sejam satisfeitas.

Para satisfazer necessidades sociais, é necessário dar tempo às pessoas

para conhecer seus colegas de trabalho e fornecer lugares para eles se encontrarem.

Isso é relativamente fácil quando todos os membros de uma equipe de desenvolvi-

mento trabalham no mesmo lugar, mas, cada vez mais, os membros da equipe não

estão localizados no mesmo prédio ou mesmo na mesma cidade ou estado. Eles

podem trabalhar para diferentes organizações ou de casa a maior parte do tempo.

Sistemas de redes sociais e teleconferência podem ser utilizados para facilitar as

comunicações, mas sistemas eletrônicos são mais eficazes uma vez que as pessoas

Page 85: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

85

se conhecem. Portanto, é interessante que sejam organizadas algumas reuniões

cara a cara no início do projeto para que as pessoas possam interagir diretamente

com outros membros da equipe. Através dessa interação direta, as pessoas se tor-

nam parte de um grupo social e aceitam as metas e prioridades desse grupo.

Para satisfazer as necessidades de estima, é necessário mostrar às pes-

soas que elas são valorizadas pela organização. O reconhecimento público das

conquistas é uma maneira simples, mas eficaz, de se fazer isso. Obviamente, as

pessoas também devem sentir que são pagas ao nível que reflete suas habilidades

e experiência.

Finalmente, para satisfazer as necessidades de auto realização, será pre-

ciso dar às pessoas a responsabilidade pelo seu trabalho, atribuir tarefas exigentes,

mas não impossíveis e fornecer um programa de treinamento onde as pessoas pos-

sam desenvolver suas habilidades. O treinamento é uma importante influência moti-

vadora, pois as pessoas gostam de adquirir novos conhecimentos e aprender novas

habilidades [15].

7.3 EXCESSO DE HORAS TRABALHADAS

Conforme relatou o economista Sidney J. Chapman que publicou o traba-

lho “Hours of Labour” [82], após a realização de um estudo com trabalhadores indus-

triais que mantinham uma produtividade em mais ou menos 40 horas por semana de

trabalho em cinco dias, concluiu-se que, quando os trabalhadores foram expostos a

longas horas de trabalho, a produtividade começou a diminuir. O estudo realizado

constatou que, no período entre quatro dias e dois meses, os ganhos de horas adi-

cionais de trabalho são anulados pelo declínio da produtividade. Em casos extre-

mos, com a privação do sono o resultado foi pior.

A habilidade de fazer tarefas mentais complexas se degrada mais rapi-

damente do que o desempenho físico. Entre os trabalhadores do conhecimento,

uma perda de produtividade devida a horas excessivas pode começar mais cedo e

ser maior do que os trabalhadores industriais, porque o trabalho é afetado pela fadi-

ga mental [83].

Page 86: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

86

Embora não exista uma pesquisa aprofundada específica para descobrir a

relação entre produtividade e horas trabalhadas no desenvolvimento de software, há

diversos fatores a favor da extinção do trabalho excessivo [84]:

- A programação requer concentração intensa. Em primeiro lugar, a principal

atividade de desenvolvimento de software requer concentração intensa e es-

forço mental. Assim, a programação é muito vulnerável aos custos da priva-

ção de sono e o estresse que assumem os trabalhadores.

- Os erros são caros. Erros na programação podem levar muito tempo para se-

rem corrigidos, muito mais tempo do que costumam tomar para fazer. Código

que é escrito durante a fadiga e estresse extremo é quase sempre de quali-

dade muito inferior ao código escrito em condições mais relaxadas. Tal códi-

go muitas vezes falta de documentação e cheio de defeitos. Erros muitas ve-

zes não são descobertos até muito mais tarde em um projeto quando este

código passa a ser testado de novas maneiras. Tais erros envolvem frequen-

temente complexas interações de um grande número de componentes indivi-

duais e podem levar dias, se não semanas, para encontrar e corrigir. De fato,

o código escrito durante a fadiga é geralmente muito mais suscetível a pro-

blemas.

- O desenvolvimento de software é altamente colaborativo. A programação é

um esforço colaborativo, e os erros cometidos por um indivíduo muitas vezes

trarão um efeito cascata no trabalho de todos os envolvidos em um projeto.

Assim, é comum que um desenvolvedor de software gaste uma grande parte

de seu tempo lidando com bugs produzidos por outros desenvolvedores. O

excesso de trabalho de um único funcionário pode, portanto, afetar negativa-

mente a produtividade de toda a equipe. Quando cada programador está tra-

balhando longas e cansativas horas, esse problema é aumentado exponenci-

almente. Todos começam a gastar mais e mais do seu tempo corrigindo erros

ao invés de realizar novas tarefas.

- A reutilização é muito importante. Finalmente, é muito comum que o software

seja reutilizado por anos, se não décadas, e tal software invariavelmente re-

quer atualizações e outras modificações. Embora o código escrito em situa-

ções extremas possa ser concluído no tempo, para atender a um prazo mui-

tas vezes mal concebido, geralmente apresenta qualidade muito inferior ao

Page 87: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

87

código escrito em condições mais relaxadas. Quando é necessária a realiza-

ção de atualizações e modificações, esse código é muitas vezes muito mais

frágil e difícil de entender, o que significa que essas mudanças geralmente le-

vam muito mais tempo para serem implementadas. É muito mais produtivo

fazer o trabalho certo na primeira vez, em vez de fazer um trabalho com me-

nos qualidade e depois pagar por ele mais tarde.

Page 88: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

88

CONCLUSÕES E TRABALHOS FUTUROS

Este trabalho reuniu conhecimentos, sob diferentes aspectos, para melho-

ria da qualidade do software, apresentando conteúdo técnico e não técnico, buscan-

do centralizar abordagens para redução de falhas de software e vulnerabilidades.

Como o assunto abordado é muito complexo e amplo, este estudo serviu também

como um guia para esclarecer como o bug foi introduzido e as abordagens para que

a correção de falhas seja realmente efetiva e outros defeitos não venham ocorrer.

Para reduzir os bugs e vulnerabilidades de uma aplicação este estudo se

baseou em estratégias técnicas que envolvem a diminuição e controle da complexi-

dade, aumento do índice de manutenção do código fonte, revisão dos artefatos pro-

duzidos e aumento da qualidade dos testes. O estudo abordou estratégias, além das

técnicas, mostrando fatores como educação, motivação e o excesso de horas traba-

lhadas.

As estratégias apresentadas nos capítulos propostos permitem que o obje-

tivo seja alcançado através da diminuição da quantidade de bugs e vulnerabilidades

inseridos na aplicação final, e o aumento da quantidade de bugs e vulnerabilidades

encontrados na fase de desenvolvimento. Além disso, a qualidade do software e di-

minuição do impacto das falhas é possibilitada através de uma arquitetura mais ro-

busta.

O trabalho mostrou que propostas de design e arquitetura de software po-

dem ser aplicadas para diminuir e controlar a complexidade do software. Além disso,

linguagens de programação com uso de seus compiladores fornecem uma camada

extra de proteção para possíveis problemas.

Revisões de software também podem ser utilizadas com o objetivo de au-

mentar a descoberta de bugs, além de melhorar a qualidade do software escrito e o

favorecimento da formação dos profissionais. Também são práticas muito efetivas

para descobertas de vulnerabilidades, permitindo uma análise prévia, antes que o

software entre em produção.

O trabalho também introduziu técnicas para melhorar a qualidade dos tes-

tes em todas as camadas da aplicação com foco na automação, melhorando a qua-

lidade do software. Os métodos formais englobam técnicas baseadas em matemáti-

Page 89: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

89

ca e lógica para descobrir possíveis problemas, desde a construção do software até

a manutenção, oferecendo uma boa opção para a construção de um software com

qualidade e efetivo suporte aos testes.

As abordagens não técnicas representam o outro lado da engenharia de

software que é o elemento pessoal. O objetivo dessas abordagens é reduzir a quan-

tidade de falhas no código usando elementos como motivação, treinamento e uma

melhor qualidade de vida, através do controle das horas trabalhadas.

Dada a importância e abrangência do tema será necessário o aprofunda-

mento dos estudos, principalmente com foco em segurança da aplicação, que é um

dos problemas em ascensão, aperfeiçoando o conhecimento e a educação nessa

área.

Cada vez mais as aplicações crescem em complexidade, sendo necessá-

rio construir um software seguro e com menos bugs. Com as abordagens descritas

nesse trabalho, desenvolvedores serão capazes de projetar e construir uma aplica-

ção com essas características. Mas como a criação e manutenção do software é

uma tarefa realizada por humanos, erros e problemas, por mínimos que sejam, sem-

pre existirão.

Page 90: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

90

REFERÊNCIAS BIBLIOGRÁFICAS

1. COMPUTERWORLD. Moth in the machine: Debugging the origins of 'bug'. ComputerWorld, 3 set. 2011. Disponivel em: <http://www.computerworld.com/article/2515435/app-development/moth-in-the-machine--debugging-the-origins-of--bug-.html>.

2. THE NATIONAL MUSEUM OF AMERICAN HISTORY. Log Book with Computer Bug. The National Museum of American History. Disponivel em: <http://americanhistory.si.edu/collections/search/object/nmah_334663>.

3. MAGOUN, A. B.; ISRAEL, P. Did You Know? Edison Coined the Term “Bug”. the institute, 23 ago. 2013. Disponivel em: <http://theinstitute.ieee.org/tech-history/technology-history/did-you-know-edison-coined-the-term-bug>.

4. BEYER, K. W. Grace Hopper and the Invention of the Information Age. [S.l.]: The MIT Press, 2012. 64 p.

5. GARFINKEL, S. History's Worst Software Bugs. Wired, 11 ago. 2015. Disponivel em: <http://archive.wired.com/software/coolapps/news/2005/11/69355?currentPage=all>.

6. HARLEY, N. 10 of the most costly software errors in history. Raygun, 29 maio 2014. Disponivel em: <https://raygun.com/blog/2014/05/10-costly-software-errors-history/>.

7. JONES, A. 10 Seriously Epic Computer Software Bugs. ListVerse, 24 dez. 2012. Disponivel em: <http://listverse.com/2012/12/24/10-seriously-epic-computer-software-bugs/>.

8. SELTZER, L. The Morris Worm: Internet malware turns 25. Zdnet, 2 nov. 2013. Disponivel em: <http://www.zdnet.com/article/the-morris-worm-internet-malware-turns-25/>.

9. SEELEY, D. A Tour of the Worm. University of Utah. [S.l.], p. 8-9. 1989. 10. BISHOP, M.; BAILEY, D. A Critical Analysis of Vulnerability Taxonomies. University

of California. [S.l.]. 1996. (CSE-96-11). 11. LONGLEY, D.; SHAIN, M. The Data and Computer Security Dictionary of

Standards,concepts and terms. [S.l.]: [s.n.], 1990. 12. VIJAYAN, J. The 10 Worst Vulnerabilities of The Last 10 Years. DarkReading, 06 maio

2016. Disponivel em: <http://www.darkreading.com/vulnerabilities---threats/the-10-worst-vulnerabilities-of-the-last-10-years/d/d-id/1325425>.

13. HALVORSEN, H.-P. Software Development A Practical Approach! University College of Southeast Norway. [S.l.], p. 50-53. 2017.

14. S.PRESSMAN, R. SOFTWARE ENGINEERING: A PRACTITIONER’S APPROACH. Seventh Edition. ed. [S.l.]: [s.n.]. ISBN 978–0–07–337597–7.

15. SOMMERVILLE, I. SOFTWARE ENGINEERING. Ninth Edition. ed. [S.l.]: Addison-Wesley. ISBN 978-0-13-703515-1.

Page 91: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

91

16. BRAUDE, E. J.; BERNSTEIN, M. E. Software Engineering Modern Approaches. Second Edition. ed. [S.l.]: [s.n.].

17. MILLETT, S.; TUNE, N. Patterns, Principles, and Practices of Domain-Driven Design. [S.l.]: Wrox.

18. VERNON, V. Implemeting Domain-Driven Design. [S.l.]: Addison-Wesley. 19. CUKIER, D. DDD - Introdução a Domain Driven Design. Agile And Art, 16 jul. 2010.

Disponivel em: <http://www.agileandart.com/2010/07/16/ddd-introducao-a-domain-driven-design/>.

20. EVANS, E. Domain-Driven Design: Tackling Complexity in the Heart of Software. [S.l.]: Addison-Wesley Professional, v. 1, 2003.

21. MILLETT, S. Practicing Domain-Driven Design Practical advice for teams implementing the development philosophy of Domain-Driven Design. [S.l.]: [s.n.].

22. ANNETT, R. What is a Monolith? coding the architecture, 10 dez. 2014. Disponivel em: <http://www.codingthearchitecture.com/2014/11/19/what_is_a_monolith.html>.

23. RICHARDSON, C. Microservice Patterns. Version 1. ed. [S.l.]: Manning. 24. NEWMAN, S. Building Microservices. [S.l.]: Mike Loukides, 2015. 25. LEWIS, J.; FOWLER, M. Microservices Resource Guide. MartinFowler. Disponivel em:

<https://martinfowler.com/microservices/>. 26. MARTIN, R. C. Clean Code A Handbook of Agile Software Craftsmanship. [S.l.]:

Prentice Hall. 27. RICHARDSON, C. Pattern: Microservice Architecture. Microservice Architecture.

Disponivel em: <http://microservices.io/patterns/microservices.html>. 28. FOWLER, M.; LEWIS, J. Microservices. MartinFowler, 10 mar. 2014. Disponivel em:

<https://martinfowler.com/articles/microservices.html>. 29. TORRE, C. D. L.; SINGH, K. D.; TURECEK, V. Microsoft Azure - Azure Service Fabric

and the Microservices Architecture. MSDN, dez. 2015. Disponivel em: <https://msdn.microsoft.com/en-us/magazine/mt595752.aspx>.

30. ROSS, P. E. The Exterminators. IEEE Spectrum, 1 set. 2005. Disponivel em: <http://spectrum.ieee.org/computing/software/the-exterminators>.

31. MICROSOFT. Strong Typing. MSDN. Disponivel em: <https://msdn.microsoft.com/en-us/library/windows/desktop/aa378693(v=vs.85).aspx>.

32. KRAUSS, A. Programming Concepts: Static vs. Dynamic Type Checking. thesocietea.org, 20 nov. 2015. Disponivel em: <https://thesocietea.org/2015/11/programming-concepts-static-vs-dynamic-type-checking/>.

33. RAVENBROOK. Memory Management Reference. Memory Management Reference. Disponivel em: <http://www.memorymanagement.org/mmref/begin.html>.

34. HUGHES, J. Why Functional Programming Matters. The University, Glasgow. [S.l.], p. 1.

35. F# SOFTWARE FOUNDATION. FSharp. FSharp. Disponivel em: <http://fsharp.org/>. 36. OPEN SOURCE FOUNDATION. Haskell. Haskell. Disponivel em:

<https://www.haskell.org/>. 37. OPEN SOURCE FOUNDATION. Swift. Swift. Disponivel em: <https://swift.org/>. 38. RANSOME, J.; MISRA, A. Core Software Security Security at the Source. [S.l.]: CRC

Page 92: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

92

Press. 39. WILLIAMS, D. L. A (Partial) Introduction to Software Engineering Practices and

Methods. North Carolina State University. [S.l.]. 2010. 40. WIEGERS, K. When Two Eyes Aren't Enough. Dr.Dobb's The World of Software

Development, 01 out. 2001. Disponivel em: <http://www.drdobbs.com/when-two-eyes-arent-enough/184414780>.

41. NOGUEIRA, E. O que é Agile Testing? iMasters, 04 jul. 2016. Disponivel em: <https://imasters.com.br/desenvolvimento/o-que-e-agile-testing/?trace=1519021197&source=single>.

42. SMARTBEAR. What is Agile Testing. SmartBear. Disponivel em: <https://smartbear.com/learn/software-testing/what-is-agile-testing/>.

43. CRISPIN, L.; GREGORY, J. Agile Testing A Practical Guide for Testers and Agile Teams. [S.l.]: [s.n.].

44. TARLINDER, A. Developer Testing Building Quality into Software. [S.l.]: [s.n.]. 45. AMARAL, L. Estratégias para implantar o processo de automação de testes. Base2, 20

dez. 2016. Disponivel em: <http://www.base2.com.br/2016/12/20/estrategias-para-implantar-o-processo-de-automacao-de-testes/>.

46. COHN, M. Succeeding with Agile Software Development using Scrum. [S.l.]: [s.n.]. 47. NET FOUNDATION. xUnit.net. xUnit.net. Disponivel em: <https://xunit.github.io/>. 48. OPEN SOURCE FOUNDATION. JUnit. JUnit. Disponivel em: <http://junit.org/junit4/>. 49. VANCE, S. Quality Code Software Testing Principles, Practices, and Patterns. [S.l.]:

Addison-Wesley. 50. RUBIN, K. S. Essential Scrum A Practical Guide to the Most Popular Agile Process.

[S.l.]: Addison-Wesley. 51. BECK, K.; ANDRES, C. Extreme Programming Explained: Embrace Change. 2nd

Edition. ed. [S.l.]: Addison-Wesley. 52. KROLL, P.; KRUCHTEN, P. The Rational Unified Process Made Easy: A Practitioner's

Guide to the RUP. [S.l.]: Addison-Wesley. 53. SMART, J. F. BDD in Action Behavior-Driven Development for the whole software

lifecycle. [S.l.]: Manning. 54. RIBEIRO, C. Entendendo BDD com Cucumber. The Bug Bang Theory Teste de

Software e Continuos Delivery, 19 fev. 2012. Disponivel em: <http://www.bugbang.com.br/entendendo-bdd-com-cucumber-parte-i/>.

55. PIRES, E. Eduardo Pires Treinamentos e Consultoria. DDD, TDD, BDD, Afinal o que são essas siglas?, 06 jun. 2012. Disponivel em: <http://www.eduardopires.net.br/2012/06/ddd-tdd-bdd/>.

56. OPEN SOURCE FOUNDATION. specflow. specflow. Disponivel em: <http://specflow.org/>.

57. RSPEC TEAM. RSpec. RSpec. Disponivel em: <http://rspec.info/>. 58. OPEN SOURCE FOUNDATION. Fit: Framework for Integrated Test. Fit. Disponivel em:

<http://fit.c2.com/>. 59. OPEN SOURCE FOUNDATION. FitNesse. FitNesse. Disponivel em:

<http://www.fitnesse.org/>. 60. CROSSXCHECK. SOAPSonar. SOAPSonar. Disponivel em:

Page 93: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

93

<http://www.crosschecknet.com/products/soapsonar.php>. 61. SMARTBEAR. SoapUI. SoapUI. Disponivel em: <https://www.soapui.org/>. 62. GREGORY, J.; CRISPIN, L. More Agile Testing Learning Journeys for the Whole

Team. [S.l.]: [s.n.]. 63. OPEN SOURCE FOUNDATION. watir. watir. Disponivel em: <http://watir.github.io/>. 64. OPEN SOURCE FOUNDATION. SeleniumHQ. SeleniumHQ. Disponivel em:

<http://www.seleniumhq.org/>. 65. AL., P. E. B. E. Dramatically Reducing Software Vulnerabilities. Report to the White

House Office of Science and Technology Policy, November 2016. 66. CHESS, B.; WEST, J. Secure Programming with Static Analysis. [S.l.]: [s.n.]. 67. NICOLETTE, D. Software Development Metrics. [S.l.]: Manning. 68. SONARSOURCE. SonarQube. SonarQube. Disponivel em:

<https://sonarqube.com/about>. 69. ARAPIDIS, C. S. Sonar Code Quality Testing Essentials. [S.l.]: Packt. 70. UAIJUG. Automação e Devops. uaijug. Disponivel em: <http://uaijug.github.io/hermes-

workshop/sessao4.html#/>. 71. CAMPBELL, G. A.; PAPAPETROU, P. P. SonarQube in Action. [S.l.]: Manning. 72. OPEN SOURCE FOUNDATION. FindBugs. FindBugs. Disponivel em:

<http://findbugs.sourceforge.net/>. 73. CHECKMARX. Static Code Analysis (SAST). CheckMarx. Disponivel em:

<https://www.checkmarx.com/>. 74. SYNOPSYS. Static Application Security Testing (SAST). Synopsys. Disponivel em:

<https://www.synopsys.com/software-integrity/security-testing/static-analysis-sast.html>. 75. HEWLETT PACKARD ENTERPRISE. Fortify Static Code Analyzer. Hewlett Packard

Enterprise. Disponivel em: <https://saas.hpe.com/en-us/software/sca>. 76. OWASP. About The Open Web Application Security Project. OWASP. Disponivel em:

<https://www.owasp.org/index.php/Main_Page>. 77. OPEN SOURCE FOUNDATION. OWASP Zed Attack Proxy Project. Owasp. Disponivel

em: <https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project>. 78. OWASP ZED. OWASP Zed Attack Proxy Project. OWASP Zed Attack Proxy Project.

Disponivel em: <https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project>.

79. DAMASEVICIUS, R. Information Systems Development. [S.l.]: Springer, 2010. 80. CALIL, S. O treinamento visa possibilitar mecanismos de capacitação e

aperfeiçoamento profissional. UFSM. [S.l.]. 81. ABRANTES, L. Pirâmide de Maslow: Entenda os níveis de necessidade dos seus clientes.

saia do lugar. Disponivel em: <http://saiadolugar.com.br/piramide-de-maslow/>. 82. CHAPMAN, S. J. Hours of Labour. Economic Journal, set. 1909. 83. ROBINSON, E. Why Crunch Modes Doesn't Work: Six Lessons. igda. Disponivel em:

<http://www.igda.org/?page=crunchsixlessons>. 84. ROBERTS, E. How is Software Development Different? Crunch mode: programming to

the extreme. Disponivel em: <https://cs.stanford.edu/people/eroberts/courses/cs181/projects/crunchmode/econ-

Page 94: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

94

software-differences.html>. 85. TIMBERG, C. A FLAW IN THE DESIGN. The Washington Post, 30 May 2015.

Disponivel em: <http://www.washingtonpost.com/sf/business/2015/05/30/net-of-insecurity-part-1/?utm_term=.11c1f1ebb71e>.

86. ALEXANDER B. MAGOUN; ISRAEL, P. Did You Know? Edison Coined the Term “Bug”. the institute The IEEE news source, 23 August 2013. Disponivel em: <http://theinstitute.ieee.org/tech-history/technology-history/did-you-know-edison-coined-the-term-bug>.

1. COMPUTERWORLD. Moth in the machine: Debugging the origins of 'bug'.

ComputerWorld, 3 set. 2011. Disponivel em: <http://www.computerworld.com/article/2515435/app-development/moth-in-the-machine--debugging-the-origins-of--bug-.html>.

2. THE NATIONAL MUSEUM OF AMERICAN HISTORY. Log Book with Computer Bug. The National Museum of American History. Disponivel em: <http://americanhistory.si.edu/collections/search/object/nmah_334663>.

3. MAGOUN, A. B.; ISRAEL, P. Did You Know? Edison Coined the Term “Bug”. the institute, 23 ago. 2013. Disponivel em: <http://theinstitute.ieee.org/tech-history/technology-history/did-you-know-edison-coined-the-term-bug>.

4. BEYER, K. W. Grace Hopper and the Invention of the Information Age. [S.l.]: The MIT Press, 2012. 64 p.

5. GARFINKEL, S. History's Worst Software Bugs. Wired, 11 ago. 2015. Disponivel em: <http://archive.wired.com/software/coolapps/news/2005/11/69355?currentPage=all>.

6. HARLEY, N. 10 of the most costly software errors in history. Raygun, 29 maio 2014. Disponivel em: <https://raygun.com/blog/2014/05/10-costly-software-errors-history/>.

7. JONES, A. 10 Seriously Epic Computer Software Bugs. ListVerse, 24 dez. 2012. Disponivel em: <http://listverse.com/2012/12/24/10-seriously-epic-computer-software-bugs/>.

8. SELTZER, L. The Morris Worm: Internet malware turns 25. Zdnet, 2 nov. 2013. Disponivel em: <http://www.zdnet.com/article/the-morris-worm-internet-malware-turns-25/>.

9. SEELEY, D. A Tour of the Worm. University of Utah. [S.l.], p. 8-9. 1989. 10. BISHOP, M.; BAILEY, D. A Critical Analysis of Vulnerability Taxonomies. University

of California. [S.l.]. 1996. (CSE-96-11). 11. LONGLEY, D.; SHAIN, M. The Data and Computer Security Dictionary of

Standards,concepts and terms. [S.l.]: [s.n.], 1990. 12. VIJAYAN, J. The 10 Worst Vulnerabilities of The Last 10 Years. DarkReading, 06 maio

2016. Disponivel em: <http://www.darkreading.com/vulnerabilities---threats/the-10-worst-vulnerabilities-of-the-last-10-years/d/d-id/1325425>.

13. HALVORSEN, H.-P. Software Development A Practical Approach! University College of Southeast Norway. [S.l.], p. 50-53. 2017.

14. S.PRESSMAN, R. SOFTWARE ENGINEERING: A PRACTITIONER’S APPROACH. Seventh Edition. ed. [S.l.]: [s.n.]. ISBN 978–0–07–337597–7.

Page 95: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

95

15. SOMMERVILLE, I. SOFTWARE ENGINEERING. Ninth Edition. ed. [S.l.]: Addison-Wesley. ISBN 978-0-13-703515-1.

16. BRAUDE, E. J.; BERNSTEIN, M. E. Software Engineering Modern Approaches. Second Edition. ed. [S.l.]: [s.n.].

17. MILLETT, S.; TUNE, N. Patterns, Principles, and Practices of Domain-Driven Design. [S.l.]: Wrox.

18. VERNON, V. Implemeting Domain-Driven Design. [S.l.]: Addison-Wesley. 19. CUKIER, D. DDD - Introdução a Domain Driven Design. Agile And Art, 16 jul. 2010.

Disponivel em: <http://www.agileandart.com/2010/07/16/ddd-introducao-a-domain-driven-design/>.

20. EVANS, E. Domain-Driven Design: Tackling Complexity in the Heart of Software. [S.l.]: Addison-Wesley Professional, v. 1, 2003.

21. MILLETT, S. Practicing Domain-Driven Design Practical advice for teams implementing the development philosophy of Domain-Driven Design. [S.l.]: [s.n.].

22. ANNETT, R. What is a Monolith? coding the architecture, 10 dez. 2014. Disponivel em: <http://www.codingthearchitecture.com/2014/11/19/what_is_a_monolith.html>.

23. RICHARDSON, C. Microservice Patterns. Version 1. ed. [S.l.]: Manning. 24. NEWMAN, S. Building Microservices. [S.l.]: Mike Loukides, 2015. 25. LEWIS, J.; FOWLER, M. Microservices Resource Guide. MartinFowler. Disponivel em:

<https://martinfowler.com/microservices/>. 26. MARTIN, R. C. Clean Code A Handbook of Agile Software Craftsmanship. [S.l.]:

Prentice Hall. 27. RICHARDSON, C. Pattern: Microservice Architecture. Microservice Architecture.

Disponivel em: <http://microservices.io/patterns/microservices.html>. 28. FOWLER, M.; LEWIS, J. Microservices. MartinFowler, 10 mar. 2014. Disponivel em:

<https://martinfowler.com/articles/microservices.html>. 29. TORRE, C. D. L.; SINGH, K. D.; TURECEK, V. Microsoft Azure - Azure Service Fabric

and the Microservices Architecture. MSDN, dez. 2015. Disponivel em: <https://msdn.microsoft.com/en-us/magazine/mt595752.aspx>.

30. ROSS, P. E. The Exterminators. IEEE Spectrum, 1 set. 2005. Disponivel em: <http://spectrum.ieee.org/computing/software/the-exterminators>.

31. MICROSOFT. Strong Typing. MSDN. Disponivel em: <https://msdn.microsoft.com/en-us/library/windows/desktop/aa378693(v=vs.85).aspx>.

32. KRAUSS, A. Programming Concepts: Static vs. Dynamic Type Checking. thesocietea.org, 20 nov. 2015. Disponivel em: <https://thesocietea.org/2015/11/programming-concepts-static-vs-dynamic-type-checking/>.

33. RAVENBROOK. Memory Management Reference. Memory Management Reference. Disponivel em: <http://www.memorymanagement.org/mmref/begin.html>.

34. HUGHES, J. Why Functional Programming Matters. The University, Glasgow. [S.l.], p. 1.

35. F# SOFTWARE FOUNDATION. FSharp. FSharp. Disponivel em: <http://fsharp.org/>. 36. OPEN SOURCE FOUNDATION. Haskell. Haskell. Disponivel em:

<https://www.haskell.org/>.

Page 96: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

96

37. OPEN SOURCE FOUNDATION. Swift. Swift. Disponivel em: <https://swift.org/>. 38. RANSOME, J.; MISRA, A. Core Software Security Security at the Source. [S.l.]: CRC

Press. 39. WILLIAMS, D. L. A (Partial) Introduction to Software Engineering Practices and

Methods. North Carolina State University. [S.l.]. 2010. 40. WIEGERS, K. When Two Eyes Aren't Enough. Dr.Dobb's The World of Software

Development, 01 out. 2001. Disponivel em: <http://www.drdobbs.com/when-two-eyes-arent-enough/184414780>.

41. NOGUEIRA, E. O que é Agile Testing? iMasters, 04 jul. 2016. Disponivel em: <https://imasters.com.br/desenvolvimento/o-que-e-agile-testing/?trace=1519021197&source=single>.

42. SMARTBEAR. What is Agile Testing. SmartBear. Disponivel em: <https://smartbear.com/learn/software-testing/what-is-agile-testing/>.

43. CRISPIN, L.; GREGORY, J. Agile Testing A Practical Guide for Testers and Agile Teams. [S.l.]: [s.n.].

44. TARLINDER, A. Developer Testing Building Quality into Software. [S.l.]: [s.n.]. 45. AMARAL, L. Estratégias para implantar o processo de automação de testes. Base2, 20

dez. 2016. Disponivel em: <http://www.base2.com.br/2016/12/20/estrategias-para-implantar-o-processo-de-automacao-de-testes/>.

46. COHN, M. Succeeding with Agile Software Development using Scrum. [S.l.]: [s.n.]. 47. NET FOUNDATION. xUnit.net. xUnit.net. Disponivel em: <https://xunit.github.io/>. 48. OPEN SOURCE FOUNDATION. JUnit. JUnit. Disponivel em: <http://junit.org/junit4/>. 49. VANCE, S. Quality Code Software Testing Principles, Practices, and Patterns. [S.l.]:

Addison-Wesley. 50. RUBIN, K. S. Essential Scrum A Practical Guide to the Most Popular Agile Process.

[S.l.]: Addison-Wesley. 51. BECK, K.; ANDRES, C. Extreme Programming Explained: Embrace Change. 2nd

Edition. ed. [S.l.]: Addison-Wesley. 52. KROLL, P.; KRUCHTEN, P. The Rational Unified Process Made Easy: A Practitioner's

Guide to the RUP. [S.l.]: Addison-Wesley. 53. SMART, J. F. BDD in Action Behavior-Driven Development for the whole software

lifecycle. [S.l.]: Manning. 54. RIBEIRO, C. Entendendo BDD com Cucumber. The Bug Bang Theory Teste de

Software e Continuos Delivery, 19 fev. 2012. Disponivel em: <http://www.bugbang.com.br/entendendo-bdd-com-cucumber-parte-i/>.

55. PIRES, E. Eduardo Pires Treinamentos e Consultoria. DDD, TDD, BDD, Afinal o que são essas siglas?, 06 jun. 2012. Disponivel em: <http://www.eduardopires.net.br/2012/06/ddd-tdd-bdd/>.

56. OPEN SOURCE FOUNDATION. specflow. specflow. Disponivel em: <http://specflow.org/>.

57. RSPEC TEAM. RSpec. RSpec. Disponivel em: <http://rspec.info/>. 58. OPEN SOURCE FOUNDATION. Fit: Framework for Integrated Test. Fit. Disponivel em:

<http://fit.c2.com/>. 59. OPEN SOURCE FOUNDATION. FitNesse. FitNesse. Disponivel em:

Page 97: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

97

<http://www.fitnesse.org/>. 60. CROSSXCHECK. SOAPSonar. SOAPSonar. Disponivel em:

<http://www.crosschecknet.com/products/soapsonar.php>. 61. SMARTBEAR. SoapUI. SoapUI. Disponivel em: <https://www.soapui.org/>. 62. GREGORY, J.; CRISPIN, L. More Agile Testing Learning Journeys for the Whole

Team. [S.l.]: [s.n.]. 63. OPEN SOURCE FOUNDATION. watir. watir. Disponivel em: <http://watir.github.io/>. 64. OPEN SOURCE FOUNDATION. SeleniumHQ. SeleniumHQ. Disponivel em:

<http://www.seleniumhq.org/>. 65. AL., P. E. B. E. Dramatically Reducing Software Vulnerabilities. Report to the White

House Office of Science and Technology Policy, November 2016. 66. CHESS, B.; WEST, J. Secure Programming with Static Analysis. [S.l.]: [s.n.]. 67. NICOLETTE, D. Software Development Metrics. [S.l.]: Manning. 68. SONARSOURCE. SonarQube. SonarQube. Disponivel em:

<https://sonarqube.com/about>. 69. ARAPIDIS, C. S. Sonar Code Quality Testing Essentials. [S.l.]: Packt. 70. UAIJUG. Automação e Devops. uaijug. Disponivel em: <http://uaijug.github.io/hermes-

workshop/sessao4.html#/>. 71. CAMPBELL, G. A.; PAPAPETROU, P. P. SonarQube in Action. [S.l.]: Manning. 72. OPEN SOURCE FOUNDATION. FindBugs. FindBugs. Disponivel em:

<http://findbugs.sourceforge.net/>. 73. CHECKMARX. Static Code Analysis (SAST). CheckMarx. Disponivel em:

<https://www.checkmarx.com/>. 74. SYNOPSYS. Static Application Security Testing (SAST). Synopsys. Disponivel em:

<https://www.synopsys.com/software-integrity/security-testing/static-analysis-sast.html>. 75. HEWLETT PACKARD ENTERPRISE. Fortify Static Code Analyzer. Hewlett Packard

Enterprise. Disponivel em: <https://saas.hpe.com/en-us/software/sca>. 76. OWASP. About The Open Web Application Security Project. OWASP. Disponivel em:

<https://www.owasp.org/index.php/Main_Page>. 77. OPEN SOURCE FOUNDATION. OWASP Zed Attack Proxy Project. Owasp. Disponivel

em: <https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project>. 78. OWASP ZED. OWASP Zed Attack Proxy Project. OWASP Zed Attack Proxy Project.

Disponivel em: <https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project>.

79. DAMASEVICIUS, R. Information Systems Development. [S.l.]: Springer, 2010. 80. CALIL, S. O treinamento visa possibilitar mecanismos de capacitação e

aperfeiçoamento profissional. UFSM. [S.l.]. 81. ABRANTES, L. Pirâmide de Maslow: Entenda os níveis de necessidade dos seus clientes.

saia do lugar. Disponivel em: <http://saiadolugar.com.br/piramide-de-maslow/>. 82. CHAPMAN, S. J. Hours of Labour. Economic Journal, set. 1909. 83. ROBINSON, E. Why Crunch Modes Doesn't Work: Six Lessons. igda. Disponivel em:

<http://www.igda.org/?page=crunchsixlessons>. 84. ROBERTS, E. How is Software Development Different? Crunch mode: programming to

Page 98: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

98

the extreme. Disponivel em: <https://cs.stanford.edu/people/eroberts/courses/cs181/projects/crunchmode/econ-software-differences.html>.

85. TIMBERG, C. A FLAW IN THE DESIGN. The Washington Post, 30 May 2015. Disponivel em: <http://www.washingtonpost.com/sf/business/2015/05/30/net-of-insecurity-part-1/?utm_term=.11c1f1ebb71e>.

86. ALEXANDER B. MAGOUN; ISRAEL, P. Did You Know? Edison Coined the Term “Bug”. the institute The IEEE news source, 23 August 2013. Disponivel em: <http://theinstitute.ieee.org/tech-history/technology-history/did-you-know-edison-coined-the-term-bug>.

Page 99: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

99

ANEXOS

A função das duas definições, Anexo e Apêndice, é semelhante, mas com uma

grande diferença entre elas: a autoria. O ANEXO de um trabalho acadêmico deve

ser aquele texto ou documento que não foi elaborado por você, tendo como objeti-

vo servir de legitimação. Já o APÊNDICE se configura como texto ou documento

elaborado por você, tendo como objetivo complementar a sua argumentação.

Page 100: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

100

ANEXO A – TÍTULO DO ANEXO A

Page 101: COMO REDUZIR O NÚMERO DE BUGS E VULNERABILIDADES DE … · 1 INTRODUÇÃO A demanda por qualidade é um fator que está sendo perseguido por todas as áreas, não apenas pela engenharia

101

ANEXO B – TÍTULO DO ANEXO B