Aplicando TDD ( Test Driven Development ) com Adobe FlexUnit


Muitos de nós já ouvimos e compreendemos a importancia dos testes no processo de desenvolvimento de software tanto em pequena quanto em grande escala. O teste por si só nos dá a segurança de construção, atualização e manuntenção dos projetos que os implementam. Linguagens bem difundidas como Java, PHP ou C++ já têm uma vasta aplicabilidade dos testes para uma boa producao de software de qualidade.

TDD (Test Driven Deployment) ou Desenvolvimento Dirigido a Testes é uma técnica aplicada ao desenvolvimento de software que utiliza alguns conceitos ágeis de desenvolvimento que tange as pequenas Iterações nas quais os casos de teste sempre sao os primeiros a serem escritos. Todos os testes, ao final de cada iteração devem ser realizados com sucesso, caso contrário, a iteração tende a falhar.

De qualquer forma, devemos sempre desenvolver alicacoes tendo como base as ideias de TDD. Dessa forma, consegue-se uma qualidade de software relativamente grande e uma economia de tempo e, consequentemente, de dinheiro.

Em Flex/ActionScript, o TDD pode ser aplicado usando o framework FlexUnit que implementa árias ferramentas para testes de unidade.

Nesse escopo iremos desenvolver uma aplicação de um sistema de conta bancária aplicando TDD. Definindo os requisitos para esse sistema, temos:

  • É necessário guardar, retornar e modificar o saldo de uma conta bancária;
  • O sistema deverá creditar ou debitar algum valor no saldo da conta corrente com duas casas decimais;
  • Não será permitido debitar quando o valor do saldo estiver negativo.

Lembramos que quando desenvolvemos em TDD, as alterações na arquitetura e na estrutura do software vão aparecendo a medida que os testes vão nascendo, logo, cuidado ao manter a linha de conduta com relação aos requisitos.

Desenvolvemos então a base para a conta corrente:

package
{
    public class Account
    {
        public function Account(){
        }
        public function getBalance():Number{
        }
        public function credit(value:Number):void{
        }
        public function debit(value:Number):void{
        }
    }
}

Após desenvolver o esboço da entidade, vamos fazer os testes para validar os métodos da Account. Para isso, temos que fazer os seguintes passos:

1º Desenvolver o arquivo AccountTest:

package

{

import flexunit.framework.TestCase

import flexunit.framework.TestSuite

public class AccountTest extends TestCase

{

public function AccountTest(methodName : String){

super(methodName)

}

public static function suite():TestSuite{

var accountTS:TestSuite = new TestSuite()

return accountTS

}

}

}

Notamos que a classe de teste deve herdar de TestCase. O método suíte deve conter todas as rotinas de teste que deverão ser executadas pelo caso de teste (TestCase). As rotinas de teste deverão ser adicionadas no método suíte() da seguinte forma:

public static function suite():TestSuite{

var accountTS:TestSuite = new TestSuite()

accountTS.addTest(new AccountTest(“testNew”))

return accountTS

}

Usando o método addTest() passamos de parâmetro um TestCase com o nome da rotina que realizará o teste. Para cada rotina, executamos o método addTest() para registrar o teste.

Desenvolvemos então um teste para a classe Account. Vamos desenvolver o teste para confirmar satisfação do primeiro requisito (“Quando o cliente abre uma conta, seu saldo deverá ser 0”):

public function testNew():void{

var account:Account = new Account()

assertEquals(“Expecting zero account balance”, 0, account.getBalance())

}

Criamos uma nova Account e verificamos, através de uma asserção, se o valor do saldo é zero.

Uma Asserção (assertion) é uma expressão que se usa para descrever a segurança que o resultado está em conformidade com o esperado. Uma asserção assegura que a rotina em teste esteja funcionando corretamente segundo suas especificações.

No FlexUnit temos as seguintes asserções: assertContained(), assertEquals(), assertFalse(), assertMatch(), assertNoMatch(), assertNotContained(), assertNotNull(), assertNotUndefined(), assertNull(), assertStrictlyNull(), assertTrue() e assertUndefined().

Por exemplo: a asserção assertEquals(message:String, obj1:Object, obj2:Object) assegura que obj1 seja igual ao obj2, logo

assertEquals(“Expecting zero account balance”, 0, acc.getBalance())

asseguraria que o valor do saldo da conta seja igual a zero, caso contrario, o método getBalance() não passaria no teste.

Concluindo os outros testes, iremos criar um teste para diversas situações em que a aplicação possa encontrar. Para a rotina de credit() temos alguns testes que podem ser feitos:

public function testCreditWithNullValue():void{

var acc:Account = new Account()

acc.credit(1)

acc.credit(null)

assertEquals(“Expecting 1 acc balance”, 1, acc.getBalance())

}

public function testCreditWithRealValue():void{

var acc:Account = new Account()

acc.credit(12.34)

assertEquals(“Expecting account balance with pounds and pence.”,

12.34, acc.getBalance())

acc.credit(12.343)

assertEquals(“Expecting account balance with pounds and pence.”,

24.68, acc.getBalance())

}

Registrando os testes temos:

public static function suite():TestSuite{

var accountTS:TestSuite = new TestSuite();

accountTS.addTest(new AccountTest(“testNew”));

accountTS.addTest(new AccountTest(“testCreditWithNullValue”));

accountTS.addTest(new AccountTest(“testCreditWithRealValue”));

return accountTS;

}

Lembrando que esses trechos devem ser escritos na classe do TestCase AccountTest.

2º Criar uma Application para executar os testes

Nesse ponto, devemos criar uma application em Flex e acrescentar os TestCases para serem executados:

<?xml version=”1.0″ encoding=”utf-8″?>

<mx:Application

xmlns:mx=http://www.adobe.com/2006/mxml&#8221;

xmlns:flexunit=“flexunit.flexui.*”

creationComplete=“onCreationComplete()”

>

<mx:Script>

<![CDATA[

private function onCreationComplete():void

{

testRunner.test = AccountTest.suite();

testRunner.startTest();

}

]]>

</mx:Script>

<flexunit:TestRunnerBase

id=“testRunner” width=“100%” height=“100%” />

</mx:Application>

Nesse recorte, estamos configurando uma application para executar os testes. O TestRunnerBase testRunner recebe como suíte de teste a suíte definida em AccountTest. Logo apos, começa a execução dos testes.

Terminada a confecção dessas duas partes, podemos executar essa application e ver se o método foi ou não validado:

Executando temos:

Visual Test Fail With FlexUnit

Visual Test Fail With FlexUnit

Verificamos então que os testes não passaram. Era de se esperar, pois a Entidade Account ainda não foi implementada.

3º Implementar a classe Account

Vamos então implementar a classe:

package

{

public class Account

{

private var _balance:Number;

public function Account(){

_balance = 0

}

public function getBalance():Number{

return _balance

}

public function credit(amount:Number):void{

var rounded = Math.floor(amount * 100)/100

_balance += rounded

}

public function debit(amount:Number):void{

credit(-amount)

}

}

}

Veja que colocamos em credit() já o arredondamento para que não seja possível acrescentar valores com mais de duas casas decimais. Executando os testes novamente temos:

Visual Test Done With FlexUnit

Visual Test Done With FlexUnit

Sucesso! Todos os testes foram executados com sucesso. A aplicação está funcionando conforme os testes escritos.

Testes não vieram para atrapalhar o desenvolvimento ou atrasar o projeto, eles tem função essencial no processo de desenvolvimento do software sendo aqueles parte fundamental descritas em normas de processo de software.

Testes são do bem, desenvolve-los podem atenuar vários problemas que acontecem em praticamente todas as partes do projeto, mas não são suficientes para resolver todos nossos problemas.

TDD em geral é uma forma mais limpa de ter um feedback de alterações e modificações no fonte da aplicação de modo que podemos saber certamente onde persiste o problema.

Esse artigo não é o suficiente, para completar o aprendizado, sugiro ler algumas bibliografias encontradas na Adobe – Developer Center e em outros Blogs/Sites.

Espero que a informação tenha sido útil. Ate a próxima!

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s