Você está na página 1de 11

Apostila – Unidade 3

Técnicas Ágeis

Disciplina: Metodologias Ágeis de Desenvolvimento

Prof. Vinícius Alves Silva


1 Modelagem e técnicas ágeis

Nesta aula veremos conceitos relacionados com técnicas e modelagem ágil.

1.1 Modelagem Ágil


Como discutido nas aulas anteriores, a Engenharia de Software Tradicional, de um
modo geral, utiliza-se da documentação e da modelagem para “formalizar” o
entendimento sobre o software e também como forma de comunicação entre os
envolvidos no processo de desenvolvimento.
Vimos também que o Manifesto Ágil, por outro lado, valoriza bastante “Indivíduos e
interações” e “software funcionando mais que documentação abrangente”.
Quando as empresas decidem utilizar métodos ágeis, esses valores acabam sendo
entraves, pois necessita uma mudança de postura, principalmente da direção da
empresa.
Comumente, os gestores responsabilizam a falta de mecanismos de controle pela
falha dos processos. Esses mesmos gestores focam as melhorias numa melhor divisão
de papéis e responsabilidades e revisões periódicas dos artefatos gerados, ou seja, há a
necessidade de evidências, documentos.
Indo para outro extremo, um mito recorrente no mercado é que Métodos Ágeis não
documentam nada. Uma leitura equivocada pode levar a esse exagero, porém, note que o
segundo valor somente diz que o software funcionando (resolver o problema) é mais
importante que ter apenas a documentação. Isso não significa que a documentação não
deva existir.
Em projetos ágeis, os documentos são guardados somente para manter
informações importantes. Documentos não são escritos para passar informações entre
analistas de negócio, desenvolvedores e testadores, nem são elaborados para proteção
contra mudanças provenientes de clientes ou usuários. Mudanças são sempre bem-
vindas.
Assinar escopos, congelar requisitos ou entrar em discussões inúteis dizendo para
o cliente “Foi isso que você pediu” não fazem parte do dia a dia ágil.

1.1.1 Modelos múltiplos


Ao passar por diferentes projetos de software, é possível perceber que cada um
pode ter necessidades diferentes com relação à documentação. Além disso, as técnicas
de análise ou levantamento de requisitos também podem variar de projeto para projeto.
Usar modelos múltiplos significa que seu processo precisa variar de projeto para projeto
para acomodar essa variedade de técnicas e estilos de documentação. Muitas empresas
utilizam Casos de Uso para elicitação de requisitos, para demonstrar os objetivos dos
principais usuários e como documentação de negócios. Porém, isso não significa que
todos os sistemas precisam de casos de uso. Nenhum processo apregoa que
documentos são obrigatórios e nenhum processo deveria predeterminar a ordem da
criação de artefatos.
A Modelagem Ágil também possui uma prática chamada de “Use o artefato
correto”. Use a ferramenta certa para o problema em mãos. Se nenhum tipo de
documento ou técnica atende ao que você precisa para o projeto, crie a sua própria
ferramenta! Também é importante ressaltar que nem todo modelo ou documento precisa
se tornar artefato definitivo no projeto. Determinados modelos simplesmente podem
ajudar no planejamento de uma versão de entrega ou iteração e ser descartados logo em
seguida.
A UML também tem seu espaço dentro do mundo ágil, porém não é utilizada para
especificações formais. A UML pode ser usada simplesmente como uma notação para
representar classes, objetos, associações, atividades, estados, etc., seja em rascunhos
no papel ou esboços em um quadro branco ou flipchart para toda a equipe. Se todos na
equipe “falam” UML, ela passa a ser o idioma do projeto.
1.1.2 Prática: ferramentas simples
A maioria dos modelos ágeis são feitos em quadros brancos, flipcharts, papéis de rascu -
nho, cartolinas ou outros instrumentos simples de abstração. A atividade de modelar deve
aproximar ao máximo as pessoas interessadas, e não afastá-las. O ideal é utilizar de re -
cursos para explorar requisitos e organizar Backlogs com cooperação. Em algumas situa -
ções, o próprio usuário pode modelar diagramas para comunicar a ideia para a equipe.
Isso é possível usando ferramentas simples, que não intimidem quem quiser se arriscar a
prototipar algo, mesmo que a ideia seja descartada logo em seguida, mas que tenha po -
tencial para evoluir a discussão.

1.2 TDD – Test-Driven Development


O TDD (Desenvolvimento Orientado a Testes) foi inicialmente proposto por Kent
Beck como parte integrante da metodologia Extreme Programming (XP). Inicialmente a
técnica tinha o nome de Test-first, em alusão à proposta estranha de se testar o código
antes mesmo de escrevê-lo. Com alguns anos de amadurecimento da técnica Kent
decidiu publicar um livro sobre a prática, passando a chamá-la de Test-Driven
Development. Em 2007, o IEEE dedicou uma edição inteira da revista Software ao tema,
despertando ainda mais o interesse acadêmico e do mercado pelo assunto.
Martin Fowler destaca o TDD como uma prática central na metodologia XP, sendo
um dos fatores que a torna viável. Isso porque, dentre outros fatores, ele ajuda a manter
controlado o crescimento do custo das mudanças ao longo do projeto. Em outras
palavras, a prática do TDD mantém a solução mais facilmente modificável durante o
desenvolvimento, permitindo revisões constantes e viabilizando a estratégia adaptativa
como um todo.

Martin Fowler

Conhecido autor britânico, tendo publicado vários livros nas áreas de Arquitetura de
computadores, UML, NoSql, Refatoração e Desenvolvimento Ágil.
1.2.1 Automação
Juntamente com a técnica TDD na área de testes de software, a automação mudou
radicalmente o papel da área no contexto do processo de desenvolvimento como um
todo. Assim como assistimos os ambientes de desenvolvimento (IDE’s) incorporarem o
processo de compilação automática do código ao se salvar um arquivo, estamos
assistindo o mesmo em relação aos testes. Já são populares ferramentas e frameworks
que executam novamente os testes a cada vez que se salva o código, dando feedback
quase instantâneo sobre o resultado das últimas alterações. É quase como se os editores
pudessem sublinhar o trecho de código defeituoso, como já fazem com erros de
compilação, só que dessa vez detectando defeitos de lógica.

1.2.2 Definição
A técnica consiste em criar o código seguindo as seguintes etapas:
● Escreva um teste automatizado, antes de escrever qualquer código de produção;
● Remova duplicações.

Pela técnica, a sequência de atividades envolve a escrita e execução dos testes


antes do código que será testado.
O segundo passo, “remova duplicações”, é também conhecido como Refatoração
(Refactoring) e consiste no processo pelo qual se melhora o código já funcional sem
alterar seu comportamento externo.
Alguns autores comentam que ao utilizar TDD “... Você não tem nada a perder, a
não ser seus bugs”.
Ainda segundo a Wikipédia, “Desenvolvimento dirigido por testes é uma técnica de
desenvolvimento de software que baseia em um ciclo curto de repetições: primeiramente
o desenvolvedor escreve um caso de teste automatizado que define uma melhoria
desejada ou uma nova funcionalidade. Então, é produzido código que possa ser validado
pelo teste para posteriormente o código ser refatorado para um código sob padrões
aceitáveis”.

1.1.1 Sendo guiado por testes


O ciclo do TDD é composto pelas seguintes etapas:
1. Escreva um teste falhando;
2. Escreva apenas o código suficiente para satisfazer o teste;
3. Refatore.
Essas etapas são também conhecidas pela sequência vermelho-verde-refatore
(red-green-refactor), fazendo alusão ao estado da suíte de testes em cada um dos
momentos (utilizada pelos frameworks de testes de diversas linguagens de programação).
Ao escrever um teste falhando, os testes estão “quebrados”, o que é representado pela
cor vermelha; ao satisfazer o teste, ou fazê-lo “passar”, a suíte passa a indicar a cor
“verde”. Nesse ponto, analisa-se e modifica-se o código para torná-lo mais simples, porém
sem alterar seu comportamento (sem quebrar nenhum teste).

Figura 1. Ciclos do TDD


Nas próximas seções serão exibidos exemplos de código da linguagem Ruby
representando os 3 ciclos.

1.1.1.1 Começando no vermelho


A escrita do teste a priori representa o ato de tornar explícita a próxima pequena
meta de programação a ser cumprida. O teste deve expressar bem a intenção do
programador a cada investida no código.
Testes automáticos são pequenos exemplos de como se espera que o código
funcione. No geral, começa-se com os casos mais simples, testando as situações mais
conhecidas, para posteriormente fazer testes com situações mais complexas. Isso
significa que se deve começar a explorar o problema a partir dos pontos que nos são mais
claros, tentando não antecipar as complexidades que surgirão logo adiante.
Vejamos um exemplo do que poderia ser um caso bem óbvio e simples para
começarmos a desenvolver uma solução de uma funcionalidade de ordenação de uma
lista:
Obs: Em Ruby o comentário simples é declarado utilizando o caractere ‘#’

Escrita do Teste
def test_unitary_list
original = [1] # declara uma lista com valor 1
ordered = Sorting.sort(original) # invoca o método sort da classe Sorting
assert_equal(original, ordered) # Compara os parâmetros
end

Métodos Assert
Os métodos Assert (afirmações) estão presentes em frameworks de testes de várias
linguagens. O método, que possui várias variações, permite comparar os resultados
esperados de um teste.

É importante ressaltar a regra de que o teste recém-escrito deve falhar. A princípio,


no ponto em que estamos em nosso exemplo, ele nem ao menos compila, visto que a
classe Sorting e o método sort() ainda nem foram criados. Isso faz parte do processo. O
teste que não compila é considerado como se estivesse executando e falhando
(vermelho).

TDD não é Teste Unitário


Embora esses temas estejam ligados por um cordão umbilical, Teste Unitário é
ferramenta, e TDD é técnica. TDD também pode e deve envolver outros tipos de testes,
como Integração e Funcional.

1.1.1.2 Rumo ao verde


A partir desse ponto, e até que o teste seja satisfeito, os erros apresentados pelo
compilador e pelos resultados dos testes funcionam como um sistema de lembretes que
sempre indica precisamente qual é o próximo passo. Em nosso exemplo, o próximo passo
na direção do verde é criar a classe Sorting e fazer o teste compilar,

1) Error: test_unitary_list(SortingTest): NameError: uninitialized constant


SortingTest::Sorting

Ao criarmos a classe Sorting, o teste passa a reclamar da inexistência do método sort().

1) Error: test_unitary_list(SortingTest): NoMethodError: undefined method `sort’ for


Sorting:Class
Depois de criar o método, o teste já pode ser executado, mas ainda não é satisfeito, visto
que o código ainda está “vazio”.
Teste:
class SortingTest < Test::Unit::TestCase
def test_single_list
original = [1]
ordered = Sorting.sort(original)
assert_equal(original, ordered)
end
end

Código do programa:
class Sorting
def self.sort(list)
return nil
end
end
Desta vez, o erro passa a nos ser reportado pelo framework de testes, e não mais pelo
compilador:

1) Failure: test_unitary_list:6 <[1]> expected but was <nil>.

Nossa tarefa ainda é bem clara: precisamos fazer o teste passar. Nesse ponto, o
conselho da prática é para que se escreva o código mais simples possível que faça o
teste passar. E apenas ele!
Nenhuma complexidade desnecessária deve ser incluída no código, a menos que
esteja sendo explicitamente requisitada pelo teste. Nesse caso, sendo esse nosso
primeiro teste, o código mais simples é retornar apenas a lista que o teste espera.
Teste:
class SortingTest < Test::Unit::TestCase
def test_single_list
original = [1]
ordered = Sorting.sort(original)
assert_equal(original, ordered)
end
end
Código do programa:
class Sorting
def self.sort(list)
return [1]
end
end

Tal solução pode ser um tanto simplista para quem não está acostumado, afinal
isso não parece um algoritmo de ordenação ainda. Contudo, é uma solução interessante
aqui, por ser bastante emblemática. Sendo levemente exagerada, ela ilustra muito bem o
princípio de design que a justifica: simplicidade e pragmatismo.
Seria possível, nesse ponto, em vez de escrever um programa simplista, escrever
logo todo o algoritmo de ordenação que se tem em mente. Isso satisfaria o teste da
mesma forma. No entanto, nesse caso, chegaríamos a um código desproporcionalmente
mais complexo do que a suite correspondente – uma anomalia, do ponto de vista do TDD.
Nosso código vai chegar lá, mas aos poucos e em sincronia com a suite que o
sustenta.
O princípio conhecido como YAGNI (“You Ain’t Gonna Need It”) defende que não se
deve adicionar hoje código de uma funcionalidade que só será útil amanhã.
2 Referências
AGILE MANIFESTO. Disponível em http://agilemanifesto.org/. Acessado em 21 de julho
de 2018.

DESENVOLVIMENTO ÁGIL. Disponível em http://www.desenvolvimentoagil.com.br.


Acessado em 25 de julho de 2018.

DUARTE, Luiz. Scrum e Métodos Ágeis: Um Guia Prático. Editora LuizTools. Edição do
Kindle. 2016.

MÉTODO ÁGIL. Disponível em http://www.metodoagil.com/. Acessado em 20 de julho de


2018.

PRIKLADNICKI, Rafael; WILL, Renato; MILANI, Fabiano. Métodos Ágeis para


Desenvolvimento de Software. Editora Bookman, 2014.

Você também pode gostar