Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. PHP

O Guia do Novato em Desenvolvimento Guiado por Testes

by
Difficulty:BeginnerLength:LongLanguages:
This post is part of a series called Test-Driven PHP.
It's Time To Dig In
Test-Driven Development in PHP: First Steps

Portuguese (Português) translation by Tony Morais (you can also view the original English article)

Testar seu código é chato, mas o impacto de não fazê-lo pode ser ordens de magnitude mais chato. Neste artigo, nós vamos usar o desenvolvimento guiado por testes para escrever e testar nosso código mais efetivamente.


O que é desenvolvimento guiado por testes?

Desde os primórdios da era dos computadores, programadores e bugs tem lutado pela supremacia. É uma ocorrencia inevitável. Mesmo o maior dos programadores cai, vitima dessas anomalias. Nenhum código está seguro. Isto é porque testamos. Programadores, pelo menos os sãos, testam seus códigos rodando-os em máquinas de desenvolvimento para terem certeza que eles fazem o que deveriam fazer.


Programadores sãos que testam seus programas.
cortesia de imagem de http://www.youthedesigner.com

Programador insano que não testa seus programas.
Cortesia de imagem de http://www.internetannoyanceday.com

desenvolvimento guiado por testes é uma técnica de programação que requer que você escreva código real e código automatizado de teste simultaneamente. Isto assegura que você testa seu código - e permite que você reteste seu código rápido e facilmente, uma vez que está automatizado.

Homo isso funciona?

Desenvolvimento guiado por testes, ou TDD, como chamaremos daqui em diante, nos remete ao pequeno ciclo iterativo de desenvolvimento parecido com o descrito abaixo:

  1. Antes de escrever qualquer código, você deve primeiro escrever um teste automatizado para este código. Enquanto escreve os testes automatizados, você deve levar em conta todos as possíveis entradas, erros e saidas. Desta forma, sua mente não estára anuveada por qualquer código que já esteja escrito.
  2. A primeira vez que você rodar seu teste automatizado, o teste deve falhar - indicando que o código não esta pronto.
  3. Em seguida, você pode começar a programar. Uma vez que exista um teste automatizado, enquanto o código falhar, significa que ele ainda não está pronto. O código pode ser corrigido até que passe nas asserções.
  4. Uma vez que o código passe o teste, você pode começar limpando ele, por meio de refatoração. Enquanto o código continuar passando nos testes, isso significa que o seu código ainda funciona. Você não precisa mais se preocupar com as mudanças que podem introduzir novos bugs.
  5. Comece tudo novamente com algum outro método ou programa.

O ciclo de desenvolvimento guiado por testes
cortesia de http://en.wikipedia.org/wiki/Test-driven_development

timo, mas como isso é melhor do que um teste regular?

Você já pulou a fase de testes de um programa de proposito porque:

  • você sentiu que era um gasto de tempo, uma vez que a mudança realizada no código  era muito pequena?
  • Você se sentiu lerdo testando tudo novamente?
  • Você não tem tempo suficiente para testar porque o gerente de projeto quer que seu código suba tão rápido quando possivel para produção?
  • Você diz a si mesmo que vai fazer isso amanhã?
  • Você tem que escolher entre teste manual, ou assistir o ultimo episodio de seu programa de tv favorito (Big Bang Theory)?

Na maior parte do tempo, nada acontece, e você sobe seu código para produção com sucesso sem problemas. Mas algumas vezes, depois que você sobe seu código para produção, tudo dá errado. Você esta estagnado corrigindo uma centena de buracos em um barco furado, com mais buracos aparecendo a cada minuto. Você não vai querer se encontrar nesta situação.


Dane-se, só sobe isso para produção!
cortesia de http://phenomenaonbreak.wordpress.com

TDD pretende eliminar nossas desculpas. Quando um programa é desenvolvido usando TDD, ele nos permite realizar modificações e testá-los rápido e eficientemente. Tudo o que precisamos é rodar os testes automatizados, e voila! se passar em todos os testes automatizados, então estamos bem para prosseguir - Se não, então isso só significa que quebrou alguma coisa com a modificação. Sabendo exatamente que parte do teste falhou, isso nos permite facilmente verificar o ponto da mudança que quebrou, logo isso faz a correção de bugs mais fácil.


Estou vendido. Como Vamos Fazer Isso?

Existe uma multidão de frameworks para teste automatizados ai fora que podemos usar. Um dos frameworks de teste automatizado mais usados mundialmente é o PHPUnit.

PHPUnit é um ótimo framework de teste, que pode ser facilmente integrado em seus projetos, ou outros projetos construidos sobre frameworks de PHP populares.

Para nossos propositos, nós não vamos precisar dessa multidão de funções que o PHPUnit oferece. Ao invés disso, nós vamos optar por criar nossos testes usando um framework de teste muito mais facil, chamado SimpleTest.

Nos próximos passos, vamos assumir que nós estamos desenvolvendo uma aplicação para livro de visitantes onde qualquer usuario pode adicionar e ver quem está listado. Vamos assumir que o resto já esta feito, e nós vamos simplesmente fazer uma classe que contem a lógica da aplicação do livro de visitas, que é onde a aplicação insere e lê do banco de dados. A porção de leitura desta classe é o que nós vamos desenvolver e testar.


Passo 1. Configurar SimpleTest

Este é sem argumentos o passo mais fácil de todos. Mesmo este cara poderia fazer isso:


Eu posso fazer isso... Eu posso usar, meu, um... cérebro!
cortesia de http://longstreet.typepad.com/

Download aqui o SimplesTest, e faça extract para uma pasta de sua escolha -- preferenciamente uma pasta onde você vá desenvolver seu código, ou o seu PHP include_path para fácil acesso.

Para este tutorial, eu configurei a pasta desta forma:

Index.php irá rodar guestbook.php, e chamar os métodos de view e mostrar as entradas. Dentro da pasta de classes é onde nós vamos colocar a classe guestbook.php, e a pasta de teste é onde nós vamos colocar o biblioteca simpletest.


Passo 2. Planeje seu ataque.

O segundo passo, que é o mais importante deles, é começar criando seus testes. Para isto, você vai realmente precisar planejar e pensar sobre o que sua função vai fazer, qual as possíveis entradas, e quais suas respectivas saídas serão enviadas. Este passo remonta um jogo de xadrez -- você precisa saber tudo sobre o oponente (o programa), incluindo todas as suas fraquezas (possiveis erros) e forçar (o que acontece se rodar com sucesso).

Então, para nossa aplicação livro de visitas, vamos seguir o seguinte esquema:

View

  • Esta função não vai ter entradas, uma vez que irá apenas retornar todas as entradas do banco de dados e enviá-las de volta para serem impressas.
  • Ela vai retornar um array de registro do livro de visitas contendo o nome do registrado e sua mensagem. Se não existir registros, então isso poderia retornar um array vazio.
  • Se existir registros, o array vai ter um ou mais valores dentro dele.
  • Ao mesmo tempo, o array vai ter uma estrutura específica como:

Passo 3. Escreve um Teste!

Agora, nós vamos escrever nosso primeiro teste. Vamos começar criando um arquivo chamado guestbook_test.php dentro da pasta test.

Então, vamos converter o que nós determinamos no passo dois.

Asserções garantem que uma certa coisa é o que se espera que seja -- basicamente, isso assegura que o que é retornado é o que esperamos que seja retornado. Por exemplo, se uma função deve retornar true se ela for bem sucedida, então em nosso teste, nós vamos fazer uma asserção cujo valor de retorno seja igual a true.

Como você pode ver aqui, nós testamos a visualização do livro de visitas com e sem registros. Vamos checkar se esses dois cenários passam em nosso critério do passo dois. Você provavelmente irá notar que cada um de nossas funções de testes começa com a palavra 'test.' Nós fazemos isso porque, quando SimpleTest executa essa classe, ela procura por todas as funções que começam com a palavra 'test' e os executa.

Em nossa classe de teste, nós também vamos usar alguns metodos de asserção, tais como assertTrue, assertIsA, e assertEquals. A função assertTrue verifica se um valor é ou não igual a true. AssertIsA verifica se uma variável é de um determinado tipo ou classe. E por ultimo, assertEquals verifica se uma variável é totalmente igual a um determinado valor.

Existe outros métodos de asserção providos por SimpleTest, que são:

assertTrue($x) Falha se $x é falso.
assertFalse($x) Falha se o $x é true.
assertNull($x) Falha se $x esta setado.
assertNotNull($x) falha se $x não esta setado
assertIsA($x, $t) falha se $x não é da classe ou tipo $t
assertNotA($x, $t) Falha se $x é da classe ou tipo $t
assertEqual($x, $y) Falha se $x == $y é falso.
assertNotEqual($x, $y) Falha se $x == $y for verdadeiro.
assertWithinMargin($x, $y, $m) Falha se abs($x - $y) < $m é falso.
assertOutsideMargin($x, $y, $m) Falha se abs($x, $y) < $m for verdadeiro
assertIdentical($x, $y) Falha se $x == $y for falso ou de tipo diferente
assertNotIdentical($x, $y) Falha se $x == $y for verdadeiro e forem do mesmo tipo.
assertReference($x, $y) Falha a menos que $x e $y forem a mesma variável
assertClone($x, $y) Falha a menos que $x e $y forem copias identicas
assertPattern($p, $x) Falha a menos que o regex $p encontre correspondencia em $x
assertNoPattern($p, $x) Falha se o regex $p bate $x
expectError($x) suprime qualquer erro de correspondencia.
assert($e) Falha caso objeto $e não seja retornado.

Lista de métodos de asserção cortesia de http://www.simpletest.org/en/unit_test_documentation.html


Passo 4. Falhar para Vencer

Uma vez que você tenha terminado de escrever o código, você deve executar o teste. A primeira vez que você rodar o teste, ele DEVE FALHAR. Se ele não falhar, então isso significa que seu teste realmente não esta testando nada.

Para executar seu teste, simplesmente execute guestbook_test.php no seu navegador. Você deve ver isso primeiramente:

Isto ocorre porque nós não criamos nossa classe guestbook ainda. Para fazer isso, crie guestbook.php dentro de nossa pasta de classes. A classe deve conter os métodos que nós estamos planejando usar, mas não deve conter nada neste primeiro momento. Lembre, nós estamos criando o teste primeiro antes de escrever qualquer código.

Quando você executar o teste novamente, ele deve parecer com o seguinte:

Como nós podemos ver aqui, nosso teste está vencendo por falhar. Isto significa que nosso teste esta pronto para obter "resposta".


Passo 5. Responda seu teste escrevendo código.


Em algum momento, todos nós nos sentiremos como esta criança quando estivermos programando.
cortesia de http://fermentation.typepad.com/fermentation

Agora que nós temos um teste automatizado funcionando, nós podemos começar escrever o código. Abra sua classe guestbook.php e comece criando a resposta para seu teste.

Esta classe guestbook.php tem alguns bugs de propósito, para que possamos ver como se parece quando nosso teste falha.

Uma vez que executemos nosso teste, nós devemos ver algo como isso:

A saida de nosso teste nos mostra em qual teste e em qual asserção nosso código falhou. A partir deste ponto, nós podemos facilmente delinear que a asserção que emitiu o erro foras os das linhas 16 e 17.

Isto claramente nos diz que o array retornado não possui as chaves corretas. Baseado nisso, nós vamos facilmente saber que parte de nosso código estará errado.

Agora, quando nós executarmos nosso teste novamente, ele vai nos mostrar o seguinte:


Passo 6. Refatorar e Refinar Seu Código

Desde que o código que estamos testando aqui seja muito simples, nosso teste e correção de bug não vai durar muito. Mas se for uma aplicação mais complexa, nós teremos que realizar multiplas modificações em nosso código, fazê-lo mais limpo para facilitar a manutenção, e um monte de outras coisas. O problema com isso, porém, é que a mudança geralmente introduz bugs adicionais. Neste ponto é onde nossos testes automatizados entram -- uma vez que nós realizamos uma mudança, nós podemos simplesmente executar novamente os testes. Se ainda passar, então nós não quebramos nada. Se falhar, então nós cometemos um erro. Isto também nos informa onde o problema esta, e, esperamos, como podemos corrigir isto.


Passo 7. Enxugue e Repita

Eventualmente, quando nosso programa requer novas funcionalidades, você irá precisar escrever novos testes. Isto é fácil! Enxugue e repita os procedimentos a partir do passo dois (desde que seus arquivos SimpleTest já estejam configurados), e comece o ciclo novamente.


Conclusão

Existe muito mais artigos aprofundados sobre desenvolvimento guiado por testes ai fora, e ainda mais funcionalidades em SimpleTest que foram mencionados neste artigo -- coisas como objetos mock, stubs que fazem a criação de testes muito mais faceis. Se você quiser ler mais, a página de Wikipedia test-driven development pode lhe mostrar o caminho. Se você estiver determinado a usar SimpleTest como seu framework de teste, leia a documentação online e se certifique de checar suas opções.

Testar é uma parte integral do ciclo de desenvolvimento, no entanto,  esta é uma das primeiras coisas a serem cortadas quando as entregas estão eminentes. Esperamos, depois de ter lido este artigo, você irá ver o quão útil é investir no desenvolvimento baseado nos testes.

Quais são seus pensamentos a respeito de Desenvolvimento Guiado por Testes?  É algo que você esteja interessado em implementar, ou você acha que é perda de tempo? Diga-me nos comentários!

Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.