Vamos ver na prática como trabalhar com TDD no ColdFusion.
Caso você não saiba sobre TDD e/ou MXUnit, aconselho a ler primeiramente os seguintes posts:
– TDD – Desenvolvimento Guiado por Testes;
– TDD com ColdFusion – Parte 1 (Instalação do MXUnit);
– TDD com ColdFusion – Parte 2 (Configuração do MXUnit);
– MXUnit – funções setUp() e tearDown().
Para exemplificar vamos criar uma Calculadora com as 4 operações básicas. O ideal para escrever os testes unitários é utilizando um ciclo de Desenvolvimento, tal como:
– Criar o teste;
– Executar o teste;
– Escrever o código propriamente dito;
– Executar os testes novamente e ajustar o código até passarem sem erro;
– Refatorar; e
– Repetir este ciclo.
Primeiramente vamos criar nossa classe Calculadora sem a implementação interna dos métodos, ou seja, apenas retornando 0 (zero) e depois na medida que os testes forem sendo criados e executados nós iremos evoluindo/refatorando o código:
Calculadora.cfc
<cfcomponent displayname="Calculadora" output="false"> <cffunction name="init" access="public" returntype="Calculadora"> <cfreturn this /> </cffunction> <cffunction name="somar" access="public" returntype="numeric"> <cfargument name="n1" type="numeric" required="true"> <cfargument name="n2" type="numeric" required="true"> <cfreturn 0 /> </cffunction> </cfcomponent>
Com a classe criada, agora é a vez de codificar o teste unitário dessa classe:
CalculadoraTest.cfc
É uma boa prática utilizar exatamente o nome do componente com sufixo Test.
<cfcomponent displayname="CalculadoraTest" extends="mxunit.framework.TestCase"> <cffunction name="setUp" returntype="void" access="public" hint="Configuracoes a serem executadas antes do teste"> <!--- Instancia o componente que será testado ---> <cfset this.calculadora = createObject("component","Calculadora").init() > </cffunction> <cffunction name="testSomar" returntype="void" access="public" hint="Teste da funcao somar"> <cfset assertEquals( 9, this.calculadora.somar(8,1),"Deve retornar 9" ) /> <cfset assertEquals( 7, this.calculadora.somar(5,2), "Deve retornar 7" ) /> <cfset assertEquals( 4, this.calculadora.somar(2,2), "Deve retornar 4" ) /> </cffunction> <cffunction name="tearDown" returntype="void" access="public" hint="Funcoes a serem executadas apos o teste"> </cffunction> </cfcomponent>
Note que a classe de teste estende o “TestCase” do framework MXUnit. Observe também que possui 2 métodos: setUp() e tearDown(). Caso não saiba do que se trata veja aqui.
Dentro da classe de teste é uma boa prática nomear os métodos com o prefixo “test” + “nome da função” que iremos testar.
O assertEquals é uma função própria do framework e recebe 3 parâmetros:
1 – Valor esperado;
2 – Valor retornado;
3 – Mensagem no caso de erro.
Por exemplo:
<cfset assertEquals( 9, this.calculadora.somar(8,1),"Deve retornar 9" ) />
Neste caso dizemos que ao executar o método somar() e passando os valores 8 e 1 o resultado deve ser 9.
Feito isso vamos executar o teste, clique com o botão direito e vá em “Run MXUnit Test”:
Após executar os testes deve abrir uma tela como essa:
Como percebemos o teste falhou, pois o retorno deveria ser 9 e como nosso método está retornando 0 deu erro. Agora vamos voltar na classe Calculadora e incrementar a função “somar()” colocando o cálculo.
Calculadora.cfc
<cfcomponent displayname="Calculadora" output="false"> <cffunction name="init" access="public" returntype="Calculadora"> <cfreturn this /> </cffunction> <cffunction name="somar" access="public" returntype="numeric"> <cfargument name="n1" type="numeric" required="true"> <cfargument name="n2" type="numeric" required="true"> <cfreturn arguments.n1 + arguments.n2 /> </cffunction> </cfcomponent>
Feito isso vamos executar o teste novamente:
Pronto! O teste passou. Este é o ciclo do TDD.
Feito isso, vamos criar os outros métodos no mesmo estilo. Para simplificar vou colocar os códigos completos abaixo:
Calculadora.cfc
<cfcomponent displayname="Calculadora" output="false"> <cffunction name="init" access="public" returntype="Calculadora"> <cfreturn this /> </cffunction> <cffunction name="somar" access="public" returntype="numeric"> <cfargument name="n1" type="numeric" required="true"> <cfargument name="n2" type="numeric" required="true"> <cfreturn arguments.n1 + arguments.n2 /> </cffunction> <cffunction name="subtrair" access="public" returntype="numeric"> <cfargument name="n1" type="numeric" required="true"> <cfargument name="n2" type="numeric" required="true"> <cfreturn arguments.n1 - arguments.n2 /> </cffunction> <cffunction name="multiplicar" access="public" returntype="numeric"> <cfargument name="n1" type="numeric" required="true"> <cfargument name="n2" type="numeric" required="true"> <cfreturn arguments.n1 * arguments.n2 /> </cffunction> <cffunction name="dividir" access="public" returntype="numeric"> <cfargument name="n1" type="numeric" required="true"> <cfargument name="n2" type="numeric" required="true"> <cfreturn arguments.n1 / arguments.n2 /> </cffunction> </cfcomponent>
CalculadoraTest.cfc
<cfcomponent displayname="CalculadoraTest" extends="mxunit.framework.TestCase"> <cffunction name="setUp" returntype="void" access="public" hint="Configuracoes a serem executadas antes do teste"> <!--- Instancia o componente que será testado ---> <cfset this.calculadora = createObject("component","Calculadora").init() > </cffunction> <cffunction name="testSomar" returntype="void" access="public" hint="Teste da funcao somar"> <cfset assertEquals( 9, this.calculadora.somar(8,1),"Deve retornar 9" ) /> <cfset assertEquals( 7, this.calculadora.somar(5,2), "Deve retornar 7" ) /> <cfset assertEquals( 4, this.calculadora.somar(2,2), "Deve retornar 4" ) /> </cffunction> <cffunction name="testSubtrair" returntype="void" access="public" hint="Teste da funcao subtrair"> <cfset assertEquals( 2, this.calculadora.subtrair(5,3), "Deve retornar 2" ) /> <cfset assertEquals( 8, this.calculadora.subtrair(9,1), "Deve retornar 8" ) /> <cfset assertEquals( 1, this.calculadora.subtrair(7,6), "Deve retornar 1" ) /> </cffunction> <cffunction name="testMultiplicar" returntype="void" access="public" hint="Teste da funcao multiplicar"> <cfset assertEquals( 10, this.calculadora.multiplicar(2,5), "Deve retornar 10" ) /> <cfset assertEquals( 48, this.calculadora.multiplicar(8,6), "Deve retornar 48" ) /> <cfset assertEquals( 4, this.calculadora.multiplicar(2,2), "Deve retornar 4" ) /> </cffunction> <cffunction name="testDividir" returntype="void" access="public" hint="Teste da funcao multiplicar"> <cfset assertEquals( 4, this.calculadora.dividir(200,50), "Deve retornar 4" ) /> <cfset assertEquals( 20, this.calculadora.dividir(600,30), "Deve retornar 20" ) /> </cffunction> <cffunction name="tearDown" returntype="void" access="public" hint="Funcoes a serem executadas apos o teste"> </cffunction> </cfcomponent>
Agora iremos rodar o teste novamente e verificar se eles passaram com sucesso:
Isso foi um exemplo bem básico sobre teste unitário no ColdFusion, nos próximos posts iremos nos aprofundando no assunto.
Espero que tenham gostado.
Até a próxima, abraço.
Anderson Straube
Post original
Calculadora.cfc