﻿<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Bug Bang Theory &#187; JUnit</title>
	<atom:link href="http://www.bugbang.com.br/?feed=rss2&#038;tag=junit" rel="self" type="application/rss+xml" />
	<link>http://www.bugbang.com.br</link>
	<description>Qualidade e Engenharia de Software</description>
	<lastBuildDate>Thu, 20 May 2010 22:42:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Uma Introdução a TDD com JUnit</title>
		<link>http://www.bugbang.com.br/?p=839</link>
		<comments>http://www.bugbang.com.br/?p=839#comments</comments>
		<pubDate>Tue, 02 Mar 2010 13:56:27 +0000</pubDate>
		<dc:creator>Camilo Ribeiro</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Ferramentas]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Técnicas de Teste]]></category>
		<category><![CDATA[JUnit]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://www.camiloribeiro.com/blog/?p=839</guid>
		<description><![CDATA[Testes de unidade são uma realidade cada vez mais próxima das nossas fábricas de software, porem, é uma das coisas que tanto os profissionais de teste quando os profissionais de desenvolvimento desconhecem em sua maioria. Melhor dizendo, conhecer todos conhecem, mas ver funcionando, saber fazer e principalmente acreditar no benefício, não.
É um pouco difícil achar [...]]]></description>
			<content:encoded><![CDATA[<p>Testes de unidade são uma realidade cada vez mais próxima das nossas fábricas de software, porem, é uma das coisas que tanto os profissionais de teste quando os profissionais de desenvolvimento desconhecem em sua maioria. Melhor dizendo, conhecer todos conhecem, mas ver funcionando, saber fazer e principalmente acreditar no benefício, não.</p>
<p>É um pouco difícil achar exemplos em blogs, sites ou comunidades de desenvolvimento e/ou testes, principalmente em português, mas um ótimo exemplo da aplicação de testes de unidade usando a ferramenta Visual Studio, para a plataforma .Net, está no excelente post &#8220;<a href="http://gustavoquezada.blogspot.com/2010/01/vsts-visual-studio-team-system-para.html" target="_blank">VSTS – Visual Studio Team System para Testadores – Unit Test</a>&#8221; do Gustavo Quezada. No post ele descreve muito bem um resumo sobre o momento dos testes de unidade e também como aplicá-los tecnicamente.</p>
<p>Vou tentar elaborar aqui uma visão baseada em TDD (<a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank">Test-driven development</a>) usando a solução mais usada para Java, o Framework de testes de unidade <a href="http://www.junit.org/" target="_blank">JUnit</a>, Desenvolvido por Kent Beck (XP) e Erich Gamma (GoF).</p>
<p>Primeiramente vamos pensar em como deve ser o micro processo para a implementação de TDD em alto nível:<br />
1 &#8211; Escrever os Testes<br />
2 &#8211; Executar os testes e verificar as falhas<br />
3 &#8211; Escrever o código<br />
4 &#8211; Rodar os testes para identificar sucesso<br />
5 &#8211; Refatorar o código para corrigir defeitos e efetuar melhorias</p>
<p><a href="http://www.camiloribeiro.com/blog/wp-content/uploads/2010/03/Test-driven_development.png"><img class="aligncenter size-full wp-image-847" title="Test-driven_development" src="http://www.camiloribeiro.com/blog/wp-content/uploads/2010/03/Test-driven_development.png" alt="" width="683" height="490" /></a></p>
<p>Agora vamos ver isso funcionando:</p>
<p><strong>1 &#8211; Escrever os Testes:</strong><br />
É premissa para a escrita dos testes termos todos os requisitos especificados e detalhados de forma a podemos avaliar os dados de entrada e os resultados esperados. Se você é um analista de teste já deve ter notado uma semelhança. A composição básica do nosso teste de unidade é a mesma dos nossos casos de teste, porem, ao escrever testesde unidade não nos preocupamos com as pré condições, procedimentos de teste e outros detalhes. Nosso objetivo aqui é claro: Fornecer o que a classe que <strong>será</strong> escrita precisará e receber o que ela nos fornecerá.</p>
<p>Vamos supor que a lista de requisitos da nossa classe é a seguinte:<br />
&#8220;O programa deve ler 3 números inteiros. Os três valores serão  interpretados como os comprimentos dos lados de um triângulo. O programa imprime uma mensagem sobre o tipo do triângulo&#8221;</p>
<p>Vamos pensar em algumas opções de respostas que podemos ter:<br />
a &#8211; Se for isósceles<br />
b &#8211; Se for equilátero<br />
c &#8211; Se for Escaleno<br />
d &#8211; Se a soma de dois lados for igual a do terceiro<br />
e &#8211; Se a soma de dois lados for menor a do terceiro</p>
<p>Podemos listar também algumas opções de exceções:<br />
a &#8211; Se algum lado for negativo ;<br />
b &#8211; Se todos os comprimentos do triânngulo forem zero;<br />
c &#8211; Se algum comprimento do triângulo for zero;</p>
<p>Enfim, para isso podemos criar inúmeros casos de teste, mas para esse exercício vamos escrever apenas 14 (quatorze) considerando que o usuário sempre vá entrar com valores numéricos.</p>
<p>Abaixo os &#8220;casos de teste&#8221; ainda em formato texto:<br />
1 &#8211; Triângulo Escaleno<br />
2 &#8211; Triângulo Equilátero<br />
3 &#8211; Triângulo Isósceles<br />
4 &#8211; Triângulo Isósceles<br />
5 &#8211; Triângulo Isósceles<br />
6 &#8211; Triângulo com Lado Nulo<br />
7 &#8211; Triângulo com Lado Negativo<br />
8 &#8211; Triângulo cuja soma dos lados A e B é igual a C<br />
9 &#8211; Triângulo cuja soma dos lados A e C igual a B<br />
10 &#8211; Triângulo cuja soma dos lados C e B igual a A<br />
11 &#8211; Triângulo cuja soma dos dois lados menor que a terceiro&#8221;}<br />
12 &#8211; Triângulo onde todos os lados são Nulos<br />
13 &#8211; Triângulo cuja soma dos lados A e B é menor que C<br />
14 &#8211; Triângulo cuja soma dos lados B e C é menor que B</p>
<p>Abaixo vamos escrever os dados de entrada o que esperamos com eles usando a seguinte sintax<br />
(entradaA, entradaB, entradaC, resultadoEsperado), sendo que as entradas devem ser inteiros e o resultado uma String<br />
1 &#8211; {2, 9, 10,&#8221;Escaleno&#8221;}<br />
2 &#8211; {20, 20, 20, &#8220;Equilátero&#8221;}<br />
3 &#8211; {20, 20, 30, &#8220;Isósceles&#8221;}<br />
4 &#8211; {20, 30, 20, &#8220;Isósceles&#8221;}<br />
5 &#8211; {30, 20, 20, &#8220;Isósceles&#8221;},<br />
6 &#8211; {0, 2, 9, &#8220;Lado Nulo&#8221;}<br />
7 &#8211; {3, -2, 9, &#8220;Lado Negativo&#8221;}<br />
8 &#8211; {5, 6, 11, &#8220;Soma dos dois lados igual a terceiro&#8221;}<br />
9 &#8211; {5, 11, 6, &#8220;Soma dos dois lados igual a terceiro&#8221;}<br />
10 &#8211; {11, 6, 5, &#8220;Soma dos dois lados igual a terceiro&#8221;}<br />
11 &#8211; {5, 6, 12, &#8220;Soma dos dois lados menor que a terceiro&#8221;}<br />
12 &#8211; {0, 0, 0, &#8220;Todos os lados Nulos&#8221;}<br />
13 &#8211; {5, 12, 6, &#8220;Soma dos dois lados menor que a terceiro&#8221;}<br />
14 &#8211; {12, 5, 6, &#8220;Soma dos dois lados menor que a terceiro&#8221;}</p>
<p>É muito importante entender que o teste de unidade tem menos valor se aplicado após a classe estar escrita, principalmente porque a sua principal finalidade, economizar tempo na implementação da classe deixa de ser aproveitada, ficando somente os testes &#8220;de unidade de regressão&#8221; para modificações da classe. Portanto, é fundamental escrever os casos de teste antes mesmo que a classe que será testada, para essa atividade, é muito recomendável que o analista de teste e programador trabalhem juntos, pensando em caminhos e entradas que poderão ser usados na futura implementação.</p>
<p>Para escrever o teste vamos precisar do Eclipse e do JUnit.<br />
O JUnit pode ser baixado no link:  <a href="http://sourceforge.net/projects/junit/files/junit/">http://sourceforge.net/projects/junit/files/junit/</a> e incluído nas libraries do Java Build Path do projeto do eclipse.</p>
<p>Agora vamos entender o básico dos métodos (<em>notation </em>) do JUnit:<br />
<strong>@RunWith</strong>: Quando uma classe tem a <em>notation</em> @RunWith ou estende uma classe com o predecessor com @RunWith, JUnit irá chamar a classe que faz referência para executar os testes em que a classe em vez de o corredor construído em JUnit. Podemos implementar uma Suite de Testes com o parâmetro Suite.class ou uma lista de parâmetros com o parâmetro Parameterized.class (que será usada no nosso exemplo).</p>
<p><strong>@Parameters</strong>: A <em>notation </em>de um método que cria uma coleção, array, lista ou outra estrutura de dados, de forma a garantir que não precisemos de vários métodos para executar uma sequencia ordenada de testes, através de uma sequencia de parâmetros que serão enviados, um a um, para o construtor da classe ao instânciar um objeto (teste).</p>
<p><strong>@Test</strong>: A <em>notation </em>do método que realiza o teste. Normalmente esse método instância o objeto da classe que será testado e realiza comparações.</p>
<p><strong>org.junit.Assert.*</strong>: Os métodos de comparação. realizam várias comparações como mostrado abaixo:<br />
<strong> assertTrue </strong>: Verifica se o valor de retorno é true<br />
<strong> assertFalse </strong>: Verifica se o valor de retorno é false<br />
<strong> assertEquals </strong>: Compara dois valores de retorno<br />
<strong> assertNotNull </strong>:  Verifica se o valor de retorno não é null<br />
<strong> assertNull </strong>:  Verifica se o valor de retorno é null<br />
<strong> assertSame </strong>: Confere se dois objetos referenciam o mesmo objeto<br />
<strong> assertNotSame </strong>: Confere se dois objetos referenciam objetos diferentes<br />
<strong> fail </strong>: usado para criar falha no teste via programação do teste</p>
<p>Para a lista completa dos métodos assert: <a href="http://www.junit.org/apidocs/org/junit/Assert.html">http://www.junit.org/apidocs/org/junit/Assert.html<br />
</a>API completa do JUnit: <a href="http://www.junit.org/apidocs/">http://www.junit.org/apidocs/</a></p>
<p>Agora vamos ver a classe de teste desenvolvida com base nos nossos dados de entrada e devidamente comentada para facilitar o entendimento:</p>
<pre class="brush: java">

// Importamos as classes que precisamos para usar os métodos citados

// Importante importar essa como static, pois usamos os métodos estáticos para realizar as comparações.
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/* Usar o RunWith informando que vamos usar uma classe parametrizada.
*  Isso fará com que ao ser instanciada como JUnit Test, a classe crie um objeto usando os parâmetros informados
*  no método Parameters para realizar cada teste, economizando dezenas de linhas de código.
*/
@RunWith(Parameterized.class)

//Declaramos uma classe normal
public class TesteExemplo {

// Declaramos os inteiros que representarão os lados do triângulo
private int a;
private int b;
private int c;

// Declaramos a string que representará o resultado esperado
private String tipo;

// Criamos o construtor que receberá os parâmetros para execução do teste
public TesteExemplo(int a, int b, int c, String trianguloEsperado) {
super();

// Cada lado do triângulo recebe um valor que vem dos parâmetros da classe
this.a = a;
this.b = b;
this.c = c;

// O resultado esperado recebe o ultimo parâmetro
this.tipo = trianguloEsperado;
}

// Método que retorna uma coleção com os parâmetros que serão usados no construtor instânciado para os testes
@Parameters
public static Collection carregaTriangulosDeTeste(){
return Arrays.asList(
new Object [][]{

// Como array em Java começa no 0, vamos incluir o teste 1 na posição 0 do array e assim por diante

//Test0
{2, 9, 10,&quot;Escaleno&quot;},

//Test1
{20, 20, 20, &quot;Equilátero&quot;},

//Test2
{20, 20, 30, &quot;Isósceles&quot;},

//Test3
{20, 30, 20, &quot;Isósceles&quot;},

//Test4
{30, 20, 20, &quot;Isósceles&quot;},

//Test5
{0, 2, 9, &quot;Lado Nulo&quot;},

//Test6
{3, -2, 9, &quot;Lado Negatívo&quot;},

//Test7
{5, 6, 11, &quot;Soma dos dois lados igual a terceiro&quot;},

//Test8
{5, 11, 6, &quot;Soma dos dois lados igual a terceiro&quot;},

//Test9
{11, 6, 5, &quot;Soma dos dois lados igual a terceiro&quot;},

//Test10
{5, 6, 12, &quot;Soma dos dois lados menor que a terceiro&quot;},

//Test11
{0, 0, 0, &quot;Todos os lados Nulos&quot;},

//Test12
{5, 12, 6, &quot;Soma dos dois lados menor que a terceiro&quot;},

//Test13
{12, 5, 6, &quot;Soma dos dois lados menor que a terceiro&quot;},
}
);

}

// Método que executa o teste a cada instanciação do objeto da classe teste
@Test
public void validaTriangulo() {
// Vamos criar um objeto do tipo Trianglulo (nossa futura classe que ainda vai existir) e passar os parâmetros do seu construtor
Triangulo escalenoValido = new Triangulo(a, b, c);

// Realizamos a comparação entre o valor que foi retornado e o valor que é esperado
assertEquals(escalenoValido.retornarTipo(), tipo);
}
}
</pre>
<p><strong>2 &#8211; Executar os testes e verificar as falhas</strong></p>
<p style="text-align: center;">Agora vamos executar a primeira vez e verificar o que o JUnit nos retorna:<br />
<a href="http://www.camiloribeiro.com/blog/wp-content/uploads/2010/03/telaUnit01.png"><img class="aligncenter size-large wp-image-849" title="telaUnit01" src="http://www.camiloribeiro.com/blog/wp-content/uploads/2010/03/telaUnit01-1024x779.png" alt="" width="717" height="545" /></a></p>
<p>É importante que todos os testes falhem, para termos certeza que estão corretos (irônico não?). Isso porque os resultados esperados não podem existir, já que nem a classe do objeto que vamos testar existe.</p>
<p><strong>3 &#8211; Escrever o código</strong></p>
<p>Agora vou escrever uma classe com alguns erros de lógica e outros no conteúdo da resposta:</p>
<pre class="brush: java">
public class Triangulo {

private int a, b, c;

public Triangulo(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}

public String retornarTipo() {

// erro de lógica
if((this.a == 0) || (this.b == 0) || (this.c == 0))
return &quot;Todos os lados Nulos&quot;;

if((this.a == 0) || (this.b == 0) || (this.c == 0))
// Erro no retorno
return &quot;Lado Núlo&quot;;

if((this.a &lt; 0) || (this.b &lt; 0) || (this.c &lt; 0))
return &quot;Lado Negatívo&quot;;

if((this.a == this.b) &amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp; (this.b == this.c))
return &quot;Equilátero&quot;;

if(
((this.a != this.b) &amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp; (this.b == this.c))||
((this.a == this.b) &amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp; (this.b != this.c))||
((this.a == this.c) &amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp; (this.b != this.c))
)
// Erro no retorno
return &quot;Isóceles&quot;;

if( (this.a + this.b == this.c)||
(this.b + this.c == this.a)||
(this.c + this.a == this.b)
)
return &quot;Soma dos dois lados igual a terceiro&quot;;

if( (this.a + this.b &lt; this.c)||
(this.b + this.c &lt; this.a)||
(this.c + this.a &lt; this.b)
)
return &quot;Soma dos dois lados menor que a terceiro&quot;;

if((this.a != this.b) &amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp; (this.a != this.c))
return &quot;Escaleno&quot;;

return null;
}
}
</pre>
<p><strong>4 &#8211; Rodar os testes para identificar sucesso</strong></p>
<p style="text-align: left;">Agora vamos verificar a nova execução do testede unidade:<br />
<a href="http://www.camiloribeiro.com/blog/wp-content/uploads/2010/03/telaUnit02.png"><img class="size-large wp-image-851 alignnone" title="telaUnit02" src="http://www.camiloribeiro.com/blog/wp-content/uploads/2010/03/telaUnit02-1024x779.png" alt="" width="717" height="545" /></a></p>
<p>Na imágem acima  podemos ver que o teste nos retorna três informações muito importantes:<br />
1 &#8211; Quantos casos de teste de unidade passaram;<br />
2 &#8211; Quais casos de teste de unidade passaram;<br />
3 &#8211; Qual a diferença entre o resultado esperado e o resultado recebido</p>
<p>Essa ultima informação em especial é que dá o &#8220;caminho das pedras&#8221; para o desenvolvedor corrigir com maior facilidade.</p>
<p>5 &#8211; Refatorar o código para corrigir defeitos e efetuar melhorias</p>
<p>Efetuamos as melhorias:</p>
<pre class="brush: java">

import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)

public class TesteExemplo {

private int a;
private int b;
private int c;

private String tipo;

public TesteExemplo(int a, int b, int c, String trianguloEsperado) {
super();
this.a = a;
this.b = b;
this.c = c;
this.tipo = trianguloEsperado;
}

@Parameters
public static Collection carregaTriangulosDeTeste(){
return Arrays.asList(
new Object [][]{
//Test0
{2, 9, 10,&quot;Escaleno&quot;},

//Test1
{20, 20, 20, &quot;Equilátero&quot;},

//Test2
{20, 20, 30, &quot;Isósceles&quot;},

//Test3
{20, 30, 20, &quot;Isósceles&quot;},

//Test4
{30, 20, 20, &quot;Isósceles&quot;},

//Test5
{0, 2, 9, &quot;Lado Nulo&quot;},

//Test6
{3, -2, 9, &quot;Lado Negatívo&quot;},

//Test7
{5, 6, 11, &quot;Soma dos dois lados igual a terceiro&quot;},

//Test8
{5, 11, 6, &quot;Soma dos dois lados igual a terceiro&quot;},

//Test9
{11, 6, 5, &quot;Soma dos dois lados igual a terceiro&quot;},

//Test10
{5, 6, 12, &quot;Soma dos dois lados menor que a terceiro&quot;},

//Test11
{0, 0, 0, &quot;Todos os lados Nulos&quot;},

//Test12
{5, 12, 6, &quot;Soma dos dois lados menor que a terceiro&quot;},

//Test13
{12, 5, 6, &quot;Soma dos dois lados menor que a terceiro&quot;},
}
);

}
@Test
public void validaTriangulo() {
Triangulo escalenoValido = new Triangulo(a, b, c);
assertEquals(escalenoValido.retornarTipo(), tipo);
}
}
</pre>
<p style="text-align: center;">Agora efetuamos as melhorias necessárias e re-executamos os casos de teste até que todos passem:<br />
<a href="http://www.camiloribeiro.com/blog/wp-content/uploads/2010/03/telaUnit03.png"><img class="aligncenter size-large wp-image-852" title="telaUnit03" src="http://www.camiloribeiro.com/blog/wp-content/uploads/2010/03/telaUnit03-1024x775.png" alt="" width="717" height="543" /></a></p>
<p>Esse foi um exemplo de implementação de teste de unidade ou teste de unidade inspirados em TDD, prática ágil muito eficaz na identificação de defeitos. Nem todas as implementações são tão fáceis, ou gastam pouco tempo, mas, com o tempo e alguma prática, esse tipo de atividade pode se tornar menos custosa e mais eficiente.</p>
<p>Peço desculpas se algum conceito apresentado acima está divergente das melhores práticas ou de algum padrão ou conceito, e me prontifico a efetuar quaisquer correções. O exemplo citado aqui é ilustrativo.</p>
<p>TDD, testesde unidade, automação de testes funcionais e de performance, entre outras áreas das disciplinas de Teste de Software e Arquitetura de Software ainda são muito misteriosas e discutidas, mas pouco implementadas, principalmente aqui no Brasil. Porem, é muito importante que nossos analistas de teste busquem essa capacitação técnica para melhorar a nossa posição no mercado, melhorar a qualidade do software e da mão de obra brasileira e acabar com mitos como &#8220;o desenvolvedor é um profissional mais estudioso ou mais técnico do que o teste&#8221; ou &#8220;teste é uma atividade simples de clicar e executar alguns fluxos&#8221;.</p>
<p>Mantenho-me disponível para quaisquer esclarecimentos</p>
<p><em>Essa atividade é baseada em um exercício em sala no curso de Especialização em Ciência da Computação com Ênfase em Engenharia de Software da Universidade Federal de Minas Gerais (UFMG) .</em></p>
<p>Bons Testes <img src='http://www.bugbang.com.br/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/"><em><img style="border-width: 0;" src="http://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png" alt="Creative Commons License" /></em></a></p>
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License</a>.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Uma+Introdu%C3%A7%C3%A3o+a+TDD+com+JUnit+http://bit.ly/9Hpt6M+BugBang" title="Postar no Twitter"><img class="nothumb" src="http://www.bugbang.com.br/wp-content/plugins/tweet-this/icons/tt-twitter-big3.png" alt="Post to Twitter" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.bugbang.com.br/?feed=rss2&amp;p=839</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
