Use o código e tenha 10% de desconto!

Test Driven Development Teste e design no mundo real com Ruby

Hugo Corbucci, Mauricio Aniche
Capa

Test-Driven Development com Ruby

Agradecimentos

Aos que não leram outras versões desse livro, Mauricio escreveu o livro originalmente em Java e C# e Hugo ajudou na "tradução" para Ruby. Os agradecimentos estão divididos pois foram escritos em momentos diferentes.

 

Agradecimentos do Mauricio

 

Essa talvez seja a seção mais difícil de se escrever, pois a quantidade de pessoas que participaram direta ou indiretamente do livro é muito grande.

Vou começar agradecimento a meu pai, mãe e irmão, que a todo momento me apoiaram na decisão de fazer um mestrado, entender como ciência deve ser feita, e que sofreram junto comigo nos momentos de grande estresse (que todo mestrado proporciona!).

Agradeço também ao meu orientador de mestrado e doutorado, prof. Dr. Marco Aurelio Gerosa, que me ensinou como as coisas funcionam "do lado de lá". Sem ele, acho que esse livro seria muito diferente; seria mais apaixonado, porém menos verdadeiro. Se meu texto olha TDD de maneira fria e imparcial, a culpa é dele.

Os Srs. Paulo Silveira e Adriano Almeida também merecem uma lembrança. Mesmo na época em que a Casa do Código não existia de fato, eles já haviam aceitado a ideia do livro de TDD. Obrigado pela confiança.

Todas as pessoas das últimas empresas em que atuei também me ajudaram muito com as incontáveis conversas de corredor sobre o assunto. Isso com certeza enriqueceu muito o texto.

Agradeço também aos amigos José Donizetti, Guilherme Moreira e Rafael Ferreira, que gastaram tempo lendo o livro e me dando sugestões de como melhorar.

Por fim, obrigado a você que está lendo esse livro. Espero que ele ajude.

 

Agradecimentos do Hugo

 

Seções de agradecimentos são sempre injustas já que é impossível listar todos que contribuíram de alguma forma para um trabalho ou o tamanho de suas contribuições. No entanto, vou tentar fazer a minha parte e já peço desculpas pelos que não pude mencionar.

Agradeço aos profs. Drs. Fabio Kon e Alfredo Goldman que, durante o curso de Bacharelado em Ciências da Computação (BCC) da USP, me apresentaram a técnica de TDD entre muitas outras no curso de Programação Extrema (XP). Ao Danilo Sato que foi nosso coach na disciplina e nos anos seguintes e todos os outros membros da AgilCoop que muito contribuíram no meu aprendizado de métodos ágeis.

Obrigado ao Paulo Silveira e Adriano Almeida pelas oportunidades com a Casa do Código e pela paciência com minha demora para escrever. Junto com eles, todos os amigos da Caelum que, apesar de não terem sido colegas de trabalho diretamente, sempre foram uma parte importante das conversas e aprendizados.

Muitos agradecimentos aos irmãos Alexandre Freire e Fernando Freire pelo nosso longo trabalho junto durante o qual comecei a trabalhar em Ruby. Nesse tempo juntos evoluímos nosso conhecimento e prática de TDD. Em especial, as diferenças entre TDD em linguagens mais dinâmicas como Ruby e linguagens mais estáticas como Java. À Mariana Bravo não poderei fazer justiça mas, além de tudo que os irmãos Freire fizeram, pelas revisões, discussões, ajudas, paciência, amor e carinho.

Agradeço também ao Mauricio obviamente pela oportunidade de "traduzir" o livro mas também pelas incontáveis e intermináveis discussões. Discussões sobre TDD, mocks, modelagem, linguagens, padrões e basicamente qualquer coisa que podemos encontrar para discordar nos ajudaram a enriquecer nossos argumentos e entendimentos sobre desenvolvimento.

Finalmente, a todos que têm paixão pelo seu trabalho e procuram melhorar o mundo com artigos, posts, livros, código aberto, palestras e voluntariado, continuem fazendo o que gostam e não deixem as pessoas ao seu redor se acomodarem.

Quem somos nós?

Como todo indivíduo, cada um de nós é único. No entanto, Mauricio e Hugo compartilham algumas coisas. Entre elas, ambos trabalham com desenvolvimento de software há perto de uma década, estão ligados com o Instituto de Matemática e Estatística (IME) da Universidade de São Paulo (USP) e têm opiniões fortes (e frequentemente divergentes) sobre desenvolvimento de software.

O grande Hugo Corbucci

Java e .NET são linguagens/plataformas com que eu tive um grande contato. Com Ruby, ao contrário, tive muito pouca experiência. E dado o sucesso que o livro fez em ambas as linguagens, muitos desenvolvedores da comunidade Ruby me pediram uma versão do livro.

Não tive dúvidas em convidar o Hugo para enfrentar esse desafio. Deixando a nossa amizade de lado, o Hugo é um desenvolvedor de quem eu sou fã. É um desenvolvedor com muita experiência e opiniões fortes. Perdi a conta de quantas vezes tivemos infinitas discussões sobre TDD, design etc. E, com certeza, aprendi muito com todas elas.

Por isso, a minha total confiança nele.

 

Mauricio Aniche

 

Em boa parte dos 10 anos de experiência que acumulei até a escrita desse livro, atuei como consultor para diferentes empresas do mercado brasileiro e internacional. Com certeza, as linguagens mais utilizadas por mim ao longo da minha carreira foram Java, C# e C.

Como sempre pulei de projeto em projeto (e, por consequência, de tecnologia em tecnologia), nunca fui a fundo em nenhuma delas. Pelo contrário, sempre foquei em entender princípios que pudessem ser levados de uma para outra, para que no fim, o código saísse com qualidade, independente da tecnologia.

Em meu último ano da graduação, 2007, comecei a ler mais sobre testes automatizados e TDD. Achei muito interessante e útil a ideia de se escrever um programa para testar seu programa, e decidi praticar TDD, por conta própria, para entender melhor como ela funcionava.

Gostei muito do que vi. De 2007 em diante, resolvi praticar, pesquisar e divulgar melhor minhas ideias sobre o assunto. Comecei devagar, apenas blogando o que estava na minha cabeça e sobre o que gostaria de feedback de outros desenvolvedores. Mas para fazer isso de maneira mais decente, resolvi ingressar no programa de Mestrado da Universidade de São Paulo. Lá, pesquisei sobre os efeitos da prática de TDD no design de classes.

Ao longo desse tempo participei da grande maioria dos eventos relacionados ao assunto. Palestrei nos principais eventos de métodos ágeis do país (como Agile Brazil, Encontro Ágil), de desenvolvimento de software (QCON SP e DNAD), entre outros menores. Cheguei a participar de eventos internacionais também; fui o único palestrante brasileiro no Primeiro Workshop Internacional sobre TDD, em 2010, na cidade de Paris. Isso mostra também que tenho participado dos eventos acadêmicos. Em 2011, apresentei um estudo sobre TDD no WBMA (Workshop Brasileiro de Métodos Ágeis), e em 2012, no maior simpósio brasileiro sobre engenharia de software, o SBES.

Atualmente trabalho pela Caelum, como consultor e instrutor. Também sou aluno de doutorado pela Universidade de São Paulo, onde continuo a pesquisar sobre a relação dos testes de unidade e qualidade do código.

Portanto, esse é meu relacionamento com TDD. Nos últimos anos tenho olhado ele de todos os pontos de vista possíveis: de praticante, de acadêmico, de pesquisador, de apaixonado, de frio. Esse livro é o relato de tudo que aprendi nesses últimos anos.

 

Hugo Corbucci

 

Lá na década de 1990, eu escrevi meus primeiros trechos de código. Começando com Visual Basic, PHP, Asp (não .Net, o anterior), shell (do DOS e bash) e Javascript, eu não aprendi muito sobre qualidade de código. O que importava era que funcionasse exatamente naquela hora. Era super divertido mas eu sempre me senti limitado.

Em 2005, ao participar do 7º Fórum Internacional de Software Livre (FISL), resolvi responder, com vários amigos, ao chamado de John "Maddog" Hall para desenvolver um sistema livre de Desenho Auxiliado por Computador (Computer Aided Design ou CAD). O trabalho teve início na matéria de Laboratório de Programação Extrema do curso de computação do IME-USP.

Foi meu primeiro projeto com mais de 5 desenvolvedores envolvidos, com mais de 10000 linhas de código Java e a necessidade de funcionar em computadores de pessoas completamente desconhecidas. Esse projeto (Archimedes-CAD) não teria conseguido sobreviver seus 6 anos de desenvolvimento ativo com mais de 50 pessoas diferentes envolvidas sem ter sido iniciado com TDD.

Pouco depois, Danilo Sato trouxe da conferência XP 2005 uma ideia de Coding Dojo *. A ideia de praticar programação com TDD trouxe muitas pessoas juntas e resultou no Coding Dojo São Paulo no qual participei de em torno de 100 sessões de dojo, sempre com TDD.

Junto com o dojo, comecei a participar de conferências nacionais e internacionais e passei a organizar algumas como Encontro Ágil e Agile Brazil. Graças a elas, conheci muitos praticantes de TDDs e variei minhas técnicas e decisões de design.

Atualmente, trabalho como consultor na ThoughtWorks em Chicago. Desde de 2011, participo de projetos Ruby e Rails nos quais pratico TDD diariamente.

Minha experiência com TDD se resume então em práticas pontuais (dojos), projetos novos e curtos em Java e Ruby (3 meses), projetos novos e longos em Java (mais de 4 anos) e projetos velhos e longos em Ruby (mais de 7 anos). Ainda não achei um projeto no qual TDD não me ajude a desenvolver código mais sustentável de forma eficiente.

Prefácio

TDD é uma das práticas de desenvolvimento de software sugeridas por diversas metodologias ágeis, como XP. A ideia é fazer com que o desenvolvedor escreva testes automatizados de maneira constante ao longo do desenvolvimento. Mas, diferentemente do que estamos acostumados, TDD sugere que o desenvolvedor escreva o teste antes mesmo da implementação.

Essa simples inversão no ciclo traz diversos benefícios para o projeto. Baterias de testes tendem a ser maiores, cobrindo mais casos, e garantindo uma maior qualidade externa. Além disso, escrever testes de unidade forçará o desenvolvedor a escrever um código de maior qualidade pois, como veremos ao longo do livro, para escrever bons testes de unidade, o desenvolvedor é obrigado a encapsular bem o código escrito e definir bem as interações possíveis com aquele código. Em linguagens orientadas a objeto, como Ruby, esses benefícios se apresentam como melhorias no design dos objetos.

A prática nos ajuda a escrever um software melhor, com mais qualidade, e um código melhor, mais fácil de ser mantido e evoluído. Esses dois pontos são importantíssimos em qualquer software, e TDD nos ajuda a alcançá-los. Toda prática que ajuda a aumentar a qualidade do software produzido deve ser estudada.

Neste livro, tentei colocar toda a experiência e tudo que aprendi ao longo desses últimos anos praticando e pesquisando sobre o assunto. Mostrei também o outro lado da prática, seus efeitos no design de classes, que é muito falada mas pouco discutida e explicada. A prática de TDD, quando bem usada, pode ser bastante produtiva. Mas, como se verá ao longo do livro, os praticantes devem estar sempre alertas às dicas que o teste dará sobre nosso código. Aqui, passaremos por eles e o leitor ao final do livro terá em mãos uma nova e excelente ferramenta de desenvolvimento.

 

A quem se destina esse livro?

 

Esse livro é destinado a desenvolvedores que querem aprender a escrever testes de maneira eficiente, e que desejam aprender a como melhorar ainda mais o código que produzem. Neste livro, utilizamos Ruby para demonstrar os conceitos discutidos, mas você pode facilmente levar as discussões feitas aqui para a sua linguagem de programação favorita. Mesmo que você já pratique TDD, tenho certeza que aqui encontrará discussões interessantes sobre como a prática dá feedback sobre problemas de acoplamento e coesão, bem como técnicas para escrever testes melhores e mais fáceis de serem mantidos.

Testadores também podem se beneficiar deste livro, entendendo como escrever códigos de teste de qualidade, quando ou não usar TDD, e como reportar problemas de código para os desenvolvedores.

 

Como devo estudar?

 

Ao longo do livro, trabalhamos em diversos exemplos, muito similares ao mundo real. Todo capítulo possui sua parte prática e parte teórica. Na parte prática, muito código de teste é escrito. Na parte teórica, refletimos sobre o código que produzimos até aquele momento, o que foi feito de bom, o que foi feito de ruim, e melhoramos de acordo.

O leitor pode refazer todos os códigos produzidos nos capítulos. Praticar TDD é essencial para que as ideias fiquem naturais. Além disso, a Caelum também disponibiliza um curso online sobre testes automatizados *, que pode ser usado como complemento desse livro.

Boa leitura!

Por que uma versão em Ruby?

Essa é a terceira versão deste livro (Java e .NET já foram lançadas). Por que então decidimos escrever uma versão para Ruby?

Ruby tem algumas diferenças importantes com relação a Java e C#. O traço comum é a orientação a objetos que todas essas linguagens seguem. Isso significa que, nas três linguagens, podemos criar objetos, isto é, elementos que acoplam dados (atributos) e comportamentos (métodos). Além disso, Ruby, Java e C# são linguagens fortemente tipadas, isto é, todo objeto tem um tipo e esse tipo não pode mudar.

No entanto, Ruby é uma linguagem dinamicamente tipada ao contrário de Java e C#, que são estaticamente tipadas. A diferença é que, em Java e C#, uma variável é declarada de um determinado tipo e esse tipo não pode mudar. Em Ruby, variáveis não tem um tipo determinado e podem ser reatribuídas para o tipo que for dinamicamente. A vantagem é que fica mais fácil alterar dinamicamente comportamentos de certos objetos. A desvantagem é que não há mais nenhuma validação por parte do compilador para apontar potenciais problemas de tipos incompatíveis. Veremos ao longo do livro que isso faz com que, em Ruby, precisemos escrever mais testes automatizados do que em Java ou C#.

Outra característica importante de Ruby é a facilidade com a qual a linguagem permite o programador utilizar o que é chamado de meta-programação. Ruby permite ao programador escrever código que gera código de forma muito fácil. Por exemplo:

class Exemplo
  def um_getter
    @um_getter
  end
  def um_setter=(valor)
    @um_setter = valor
  end
  def ambos
    @ambos
  end
  def ambos=(valor)
    @ambos = valor
  end
end

Esse código que tem um getter para o atributo @um_getter, um setter para o atributo @um_setter e um getter e um setter para o atributo @ambos, pode ser escrito em Ruby da seguinte forma:

class Exemplo
  attr_reader :um_getter
  attr_writer :um_setter
  attr_accessor :ambos
end

attr_reader, attr_writer e attr_accessor são métodos que geram getters, setters e ambos respectivamente. Ou seja, com essas 3 linhas, geramos o código que tinha sido escrito antes com 12 linhas. Existem muitas outras formas de tirar proveito dessa metaprogramação simples em Ruby conforme veremos ao longo do livro.

Essas várias diferenças fazem com que o desenvolvimento em Ruby costume ser mais denso e fácil de se cometer erros bobos que só são descobertos ao executar aquele trecho exato de código. De uma certa forma, isso faz com que seja ainda mais importante fazer bom uso de testes automatizados e, provavelmente, de TDD para garantir o sucesso do seu código Ruby.

Por esses vários motivos e para ajudar todos aqueles que têm curiosidade com relação a Ruby, o Hugo e eu decidimos reformular os exemplos do livro para uma versão Ruby. Você verá que os códigos são um pouco diferentes dos encontrados nas outras versões deste livro e assim como alguns conselhos e preocupações.

Esperamos que esse material seja bastante útil para toda a comunidade Ruby.

Sumário

  • 1 - Introdução
    • 1.1 - Era uma vez um projeto sem testes...
    • 1.2 - Por que devemos testar?
    • 1.3 - Por que não testamos?
    • 1.4 - Testes automatizados e TDD
    • 1.5 - Conclusão
    • 1.6 - Como tirar dúvidas?
  • 2 - Testes de Unidade
    • 2.1 - O que é um teste de unidade?
    • 2.2 - Preciso mesmo escrevê-los?
    • 2.3 - O primeiro teste de unidade
    • 2.4 - Continuando a testar
    • 2.5 - Conclusão
  • 3 - Introdução ao Test-Driven Development
    • 3.1 - O problema dos números romanos
    • 3.2 - O primeiro teste
    • 3.3 - Refletindo sobre o assunto
    • 3.4 - Quais as vantagens?
    • 3.5 - Um pouco da história de TDD
    • 3.6 - Conclusão
  • 4 - Simplicidade e Baby Steps
    • 4.1 - O problema do cálculo de salário
    • 4.2 - Implementando da maneira mais simples possível
    • 4.3 - Passos de Bebê (ou Baby Steps)
    • 4.4 - Usando baby steps de maneira consciente
    • 4.5 - Conclusão
  • 5 - TDD e design de classes
    • 5.1 - O problema do carrinho de compras
    • 5.2 - Testes que influenciam no design de classes
    • 5.3 - Diferenças entre TDD e testes da maneira tradicional
    • 5.4 - Testes como rascunho
    • 5.5 - Conclusão
  • 6 - Qualidade no código do teste
    • 6.1 - Repetição de código entre testes
    • 6.2 - Nomenclatura dos testes
    • 6.3 - Test Data Builders
    • 6.4 - Testes repetidos
    • 6.5 - Escrevendo boas asserções
    • 6.6 - Testando listas
    • 6.7 - Separando as classes de teste
    • 6.8 - Conclusão
  • 7 - TDD e a coesão
    • 7.1 - Novamente o problema do cálculo de salário
    • 7.2 - Ouvindo o feedback dos testes
    • 7.3 - Testes em métodos privados?
    • 7.4 - Resolvendo o problema da calculadora de salário
    • 7.5 - O que olhar no teste em relação a coesão?
    • 7.6 - Conclusão
  • 8 - TDD e o acoplamento
    • 8.1 - O problema da nota fiscal
    • 8.2 - Mock Objects
    • 8.3 - Dependências explícitas
    • 8.4 - Ouvindo o feedback dos testes
    • 8.5 - Classes estáveis
    • 8.6 - Resolvendo o problema da nota fiscal
    • 8.7 - Testando métodos estáticos
    • 8.8 - TDD e a constante criação de interfaces
    • 8.9 - O que olhar no teste em relação ao acoplamento?
    • 8.10 - Conclusão
  • 9 - TDD e o encapsulamento
    • 9.1 - O problema do processador de boleto
    • 9.2 - Ouvindo o feedback dos testes
    • 9.3 - Tell, Don't Ask e Lei de Demeter
    • 9.4 - Resolvendo o problema do processador de boletos
    • 9.5 - O que olhar no teste em relação ao encapsulamento?
    • 9.6 - Conclusão
  • 10 - Testes de integração e TDD
    • 10.1 - Testes de unidade, integração e sistema
    • 10.2 - Quando não usar mocks?
    • 10.3 - Testes em subclasses de ActiveRecord::Base
    • 10.4 - Devo usar TDD em testes de integração?
    • 10.5 - Testes em aplicações Web
    • 10.6 - Conclusão
  • 11 - Testando código dinâmico
    • 11.1 - É possível utilizar TDD com Duck Typing?
    • 11.2 - A mágica do send e seus testes
    • 11.3 - O uso e teste de method_missing
  • 12 - Quando não usar TDD?
    • 12.1 - Quando não praticar TDD?
    • 12.2 - 100% de cobertura de código?
    • 12.3 - Devo testar códigos simples?
    • 12.4 - Erros comuns durante a prática de TDD
    • 12.5 - Como convencer seu chefe sobre TDD?
    • 12.6 - TDD em sistemas legados
    • 12.7 - Conclusão
  • 13 - E agora?
    • 13.1 - Como aprender mais agora?
    • 13.2 - Dificuldade no aprendizado
    • 13.3 - Como interagir com outros praticantes?
    • 13.4 - Conclusão final
  • 14 - Apêndice: princípios SOLID
    • 14.1 - Sintomas de projetos de classes em degradação
    • 14.2 - Princípios de projeto de classes
    • 14.3 - Conclusão
  • 15 - Apêndice: RSpec como biblioteca de testes de unidade
    • 15.1 - Asserções na primeira versão do RSpec
    • 15.2 - Biblioteca de mocks embutida no RSpec
    • 15.3 - Comparando a saída das duas bibliotecas
    • 15.4 - Novas asserções do RSpec
    • 15.5 - Conclusão
Capítulo1

Introdução

Será que testar software é realmente importante? Neste capítulo, discutimos um pouco sobre as consequências de software não testado e uma possível solução para isso, que hoje é um problema para a sociedade como um todo, já que softwares estão em todos os lugares.

1.1 - Era uma vez um projeto sem testes...

Durante os anos de 2005 e 2006, trabalhei em um projeto cujo objetivo era automatizar todo o processo de postos de gasolina. O sistema deveria tomar conta de todo o fluxo: desde a comunicação com as bombas de gasolina, liberando ou não o abastecimento, até relatórios de fluxo de caixa e quantidade de combustível vendido por dia ou por bomba.

A aplicação era desenvolvida inteira em C e deveria rodar em um microdispositivo de 200MHz de processamento e 2MB de RAM. Nós éramos em 4 desenvolvedores. Todos programavam e todos testavam ao mesmo tempo. Os testes não eram tão simples de serem feitos, afinal precisávamos simular bombas de gasolinas, abastecimentos simultâneos etc. Mas, mesmo assim, nós nos revezávamos e testávamos da forma que conseguíamos.

Após alguns meses de desenvolvimento, encontramos o primeiro posto disposto a participar do piloto da aplicação. Esse posto ficava em Santo Domingo, capital da República Dominicana.

Eu, na época líder técnico dessa equipe, viajei para o lugar com o objetivo de acompanhar nosso produto rodando pela primeira vez. Fizemos a instalação do produto pela manhã e acompanhamos nosso "bebê" rodando por todo o dia. Funcionou perfeitamente. Saímos de lá e fomos jantar em um dos melhores lugares da cidade para comemorar.

Missão cumprida.

1.2 - Por que devemos testar?

Voltando do jantar, fui direto pra cama, afinal no dia seguinte entenderíamos quais seriam as próximas etapas do produto. Mas, às 7h da manhã, o telefone tocou. Era o responsável pelo posto de gasolina piloto. Ele me ligou justamente para contar que o posto de gasolina estava completamente parado desde as 0h: o software parou de funcionar e bloqueou completamente o posto de gasolina.

Nosso software nunca havia sido testado com uma quantidade grande de abastecimentos. Os postos em Santo Domingo fazem muitos pequenos abastecimentos ao longo do dia (diferente daqui, onde enchemos o tanque de uma vez). O sistema não entendeu isso muito bem, e optou por bloquear as bombas de gasolina, para evitar fraude, já que não conseguia registrar as futuras compras.

O software fez com que o estabelecimento ficasse 12h parado, sem vender nada. Quanto será que isso custou ao dono do estabelecimento? Como será que foi a reação dele ao descobrir que o novo produto, no primeiro dia, causou tamanho estrago?

Os Estados Unidos estimam que erros de software lhes custam aproximadamente 60 bilhões de dólares por ano *. O dinheiro que poderia estar sendo usado para erradicar a fome do planeta está sendo gasto em correções de software que não funcionam.

É incrível a quantidade de software que não funciona. Pergunte ao seu amigo não-técnico se ele já ficou irritado porque algum programa do seu dia a dia simplesmente parou de funcionar. Alguns erros de software são inclusive famosos por todos: o foguete Ariane 5 explodiu por um erro de software; um hospital panamenho matou pacientes pois seu software para dosagem de remédios errou.

1.3 - Por que não testamos?

Não há um desenvolvedor que não saiba que a solução para o problema é testar seus códigos. A pergunta é: por que não testamos?

Não testamos porque testar sai caro. Imagine o sistema em que você trabalha hoje. Se uma pessoa precisasse testá-lo do começo ao fim, quanto tempo ela levaria? Semanas? Meses? Pagar um mês de uma pessoa a cada mudança feita no código (sim, os desenvolvedores também sabem que uma mudança em um trecho pode gerar problemas em outro) é simplesmente impossível.

Testar sai caro, no fim, porque estamos pagando "a pessoa" errada para fazer o trabalho. Acho muito interessante a quantidade de tempo que gastamos criando soluções tecnológicas para resolver problemas "dos outros". Por que não escrevemos programas que resolvam também os nossos problemas?

1.4 - Testes automatizados e TDD

Uma maneira de conseguir testar o sistema todo de maneira constante e contínua a um preço justo é automatizando os testes. Ou seja, escrevendo um programa que testa o seu programa. Esse programa invocaria os comportamentos do seu sistema e garantiria que a saída é sempre a esperada.

Se isso fosse realmente viável, teríamos diversas vantagens. O teste executaria muito rápido (afinal, é uma máquina!). Se ele executa rápido, logo o rodaríamos constantemente. Se os rodarmos o tempo todo, descobriríamos os problemas mais cedo, diminuindo o custo que o erro geraria.

Um ponto que é sempre levantado em qualquer discussão sobre testes manuais versus testes automatizados é produtividade. O argumento mais comum é o de que agora a equipe de desenvolvimento gastará tempo escrevendo código de teste; antes ela só gastava tempo escrevendo código de produção. Portanto, essa equipe será menos produtiva.

O contra-argumento nesse caso é: o que é produtividade? Se produtividade for medida através do número de linhas de código de produção escritos por dia, talvez o desenvolvedor seja sim menos produtivo. Agora, se produtividade for a quantidade de linhas de código de produção sem defeitos escritos por dia, provavelmente o desenvolvedor será mais produtivo ao usar testes automatizados.

Além disso, se analisarmos o dia a dia de um desenvolvedor que faz testes manuais, podemos perceber a quantidade de tempo que ele gasta com teste. Geralmente o desenvolvedor executa testes enquanto desenvolve o algoritmo completo. Ele escreve um pouco, roda o programa, e o programa falha. Nesse momento, o desenvolvedor entende o problema, corrige-o, e em seguida executa novamente o mesmo teste. Quantas vezes por dia o desenvolvedor executa o mesmo teste manual? O desenvolvedor que automatiza seus testes perde tempo apenas 1 vez com ele; nas próximas, ele simplesmente aperta um botão e vê a máquina executando o teste pra ele, de forma correta e rápida.

1.5 - Conclusão

Minha família inteira é da área médica. Um jantar de fim de semana em casa parece mais um daqueles episódios de seriados médicos da televisão: pessoas discutindo casos e como resolvê-los. Apesar de entender praticamente nada sobre medicina, uma coisa me chama muito a atenção: o fanatismo deles por qualidade.

Um médico, ao longo de uma cirurgia, nunca abre mão de qualidade. Se o paciente falar para ele: "Doutor, o senhor poderia não lavar a mão e terminar a cirurgia 15 minutos mais cedo?", tenho certeza que o médico negaria na hora. Ele saberia que chegaria ao resultado final mais rápido, mas a chance de um problema é tão grande, que simplesmente não valeria a pena.

Em nossa área, vejo justamente o contrário. Qual desenvolvedor nunca escreveu um código de má qualidade de maneira consciente? Quem nunca escreveu uma "gambiarra"? Quem nunca colocou software em produção sem executar o mínimo suficiente de testes para tal?

Não há desculpas para não testar software. E a solução para que seus testes sejam sustentáveis é automatizando. Testar é divertido, aumenta a qualidade do seu produto, e pode ainda ajudá-lo a identificar trechos de código que foram mal escritos ou projetados (aqui entra a prática de TDD). É muita vantagem.

Ao longo do livro, espero convencê-lo de que escrever testes automatizados é importante, e que, na verdade, é mais fácil do que parece.

1.6 - Como tirar dúvidas?

Para facilitar a comunicação entre os leitores deste livro e interessados no assunto, criei um grupo de discussão no Google Groups. Você pode se cadastrar em https://groups.google.com/forum/#!forum/tdd-no-mundo-real.

Toda e qualquer discussão, dúvida ou sugestão será bem-vinda.

Não se esqueça também de participar do GUJ, o maior portal de desenvolvedores do Brasil: http://www.guj.com.br/

Lá você pode perguntar, responder, editar e dar pontos às dúvidas e respostas de outros desenvolvedores.

Dados do produto

Número de páginas:
224
ISBN:
978-85-66250-43-5
Data publicação:
04/2014

Compartilhe!

Compartilhe no Facebook Compartilhe no Twitter