<?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>blog.caelum.com.br &#187; jbehave</title>
	<atom:link href="http://blog.caelum.com.br/tag/jbehave/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.caelum.com.br</link>
	<description>blog dos desenvolvedores da Caelum</description>
	<lastBuildDate>Thu, 09 Feb 2012 13:04:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Behavior Driven Development com JUnit</title>
		<link>http://blog.caelum.com.br/behavior-driven-development-com-junit/</link>
		<comments>http://blog.caelum.com.br/behavior-driven-development-com-junit/#comments</comments>
		<pubDate>Sat, 28 Feb 2009 07:53:39 +0000</pubDate>
		<dc:creator>Lucas Cavalcanti</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[behavior driven development]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[easyb]]></category>
		<category><![CDATA[jbehave]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[testes]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=589</guid>
		<description><![CDATA[Behavior Driven Development (BDD) é uma maneira de desenvolver software que, além de outras coisas, encoraja a escrita de testes mais parecidos com uma especificação, como sugerido pelo Dan North. A ideia é que seus testes descrevam o que um determinado módulo deveria fazer ou como uma determinada funcionalidade deveria funcionar. Algo como: Dado que <a href="http://blog.caelum.com.br/behavior-driven-development-com-junit/#more-589'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">Behavior Driven Development</a> (BDD) é uma maneira de desenvolver software que, além de outras coisas, encoraja a escrita de testes mais parecidos com uma especificação, como sugerido pelo <a title="Dan North" href="http://dannorth.net/introducing-bdd">Dan North</a>. A ideia é que seus testes descrevam o que um determinado módulo deveria fazer ou como uma determinada funcionalidade deveria funcionar. Algo como:</p>
<blockquote><p>Dado que eu estou na página principal, quando eu tento me logar, então meu nome aparece no canto da tela.</p></blockquote>
<p>Eu, Cauê Guerra e Cecilia Fernandes estávamos começando um projeto aqui na Caelum e resolvemos usar BDD no desenvolvimento. Começamos, então, a procurar ferramentas que ajudam o desenvolvimento em BDD. Em Ruby existem o <a title="Cucumber" href="http://cukes.info/">Cucumber</a> e o <a title="RSpec" href="http://rspec.info/">RSpec</a>, em Groovy tem o <a title="easyb" href="http://easyb.org/">Easyb</a> e, em Java, o <a title="JBehave" href="http://jbehave.org/">JBehave</a>, apenas para citar os mais famosos. Começamos a testar essas opções, mas logo no começo surgiram alguns problemas:</p>
<ul>
<li><strong>Cucumber + RSpec e Easyb</strong>: ambos eram muito parecidos em suas qualidades e defeitos: utilizam arquivos de texto para a descrição das histórias e são bem fáceis de escrever. No entanto, nenhum dos dois é feito em Java. Poderíamos usar, sem problemas, o JRuby e o próprio Groovy para acessar nosso código Java, mas por se tratar de um projeto open-source não queríamos obrigar futuros contribuidores a conhecer outras linguagens para começar a trabalhar em nosso projeto.Um outro problema foi que, usando o Eclipse como IDE, perderíamos o <em>code completion</em> e a habilidade de rodar os testes pela IDE &#8211; seria preciso criar alguma <em>task ant</em> ou um Rakefile para isso, rodando tudo pela linha de comando e tendo que interpretar os resultados obtidos fora da IDE.</li>
<li><strong>JBehave</strong>: o JBehave adiciona um pouco de complexidade para escrever os testes (anotações, arquivos de texto não compilados, algumas restrições sobre como as classes devem ser escritas), e achamos que o ganho que teríamos ao usar o JBehave não valeria a pena por causa dessa complexidade. Além disso, teríamos problemas para reaproveitar o código dos <em>steps</em>, dificultando a manutenção dos testes. Existem outros problemas, mas vamos deixar isso para outro post.</li>
</ul>
<p>Daí nos questionamos: será que precisamos mesmo de alguma ferramenta especial para usar BDD? E a resposta que surgiu foi: <em>Não, podemos fazer tudo usando apenas o <a title="JUnit" href="http://www.junit.org/">JUnit</a></em>! O bom e velho JUnit! Mas não bastava só usá-lo. Precisávamos de um jeito de organizar como uma especificação. Então pensamos e chegamos no seguinte padrão de testes:</p>
<pre class="brush: java; title: ; notranslate">
@Test
public void nomeDoCenarioDeTestes() {
  given.algumContexto();
  when.euExecutoAlgumaAcaoNoSistema();
  then.algumaCondiçãoTemQueSerVerdadeira();
}
</pre>
<p>Por exemplo, usando o cenário que eu tinha escrito acima:</p>
<pre class="brush: java; title: ; notranslate">
@Test
public void login() {
  given.iAmOnTheMainPage();
  when.iLoginAs(&quot;Lucas&quot;);
  then.myNameAppearsOnTheScreen(&quot;Lucas&quot;);
}
</pre>
<p>Um código simples, que qualquer pessoa que sabe inglês entenderia, e que nos diz o que esperamos que aconteça quando alguém se loga no sistema. Mas o que exatamente são esses &#8220;<em>given</em>&#8220;, &#8220;<em>when</em>&#8221; e &#8220;<em>then</em>&#8220;? São objetos simples, que não precisam implementar nenhuma interface nem estender classe alguma &#8211; vão apenas executar o que lhes foi pedido pelo teste.</p>
<p>Mesmo assim resolvemos usar uma convenção para dar o nome a esses objetos, de acordo com suas responsabilidades:</p>
<ul>
<li><strong>GivenSteps given</strong> =&gt; objeto que vai preparar o contexto inicial do teste em questão. Ex: Entrar em uma página, inserir determinados objetos no banco, logar-se com um dado usuário, etc.</li>
<li><strong>WhenSteps when</strong> =&gt; objeto que vai executar as ações do teste em si, utilizando o contexto definido pelo objeto <em>given</em>. É a parte mais importante do teste. Ex: Preencher um formulário, clicar no botao <em>Enviar</em>, selecionar um item em alguma comboBox, etc.</li>
<li><strong>ThenSteps then</strong> =&gt; objeto que verifica se o resultado das ações executadas é o esperado. Ex: O usuário está logado? Apareceu a mensagem &#8220;<em>Inserido com sucesso</em>&#8220;? Deu erro de validação?</li>
</ul>
<p>Para que os testes ficassem o mais limpo possível e o mais parecidos com um arquivo de texto descrevendo os cenários de uma história, separamos toda a configuração de testes e a criação dos nossos objetos <em>given</em>, <em>when</em> e <em>then</em> em uma classe abstrata que vai ser superclasse desses testes &#8211; que representam uma <strong>história</strong>. Também podemos colocar a descrição da história como comentário no começo do arquivo. Vejam um exemplo completo de um Cenário de teste, com todas as classes:</p>
<pre class="brush: java; title: ; notranslate">
/**
 * In order to use the system
 * As a user
 * I want to login
 */
public class LoginStory extends Story {
  @Test
  public void login() {
    given.iAmOnTheMainPage();
    when.iLoginAs(&quot;Lucas&quot;);
    then.myNameAppearsOnTheScreen(&quot;Lucas&quot;);
  }
}  

public abstract class Story {

  protected GivenSteps given;
  protected WhenSteps when;
  protected ThenSteps then;  

  @Before
  public void setUp() {
    Browser browser = createSeleniumDSL();
    given = new GivenSteps(browser);
    when = new WhenSteps(browser);
    then = new ThenSteps(browser);
  }
}
public class GivenSteps {

  private final Browser browser;

  public GivenSteps(Browser browser) {
    this.browser = browser;
  }

  public void iAmOnTheMainPage() {
    browser.open(&quot;index.jsp&quot;);
  }
}  

public class WhenSteps {

  private final Browser browser;

  public WhenSteps(Browser browser) {
    this.browser = browser;
  }

  public void iLoginAs(String login) {
    browser.form(&quot;login&quot;)
      .field(&quot;username&quot;).type(login)
      .field(&quot;password&quot;).type(login)
      .submit();
  }
}  

public class ThenSteps {

  private final Browser browser;

  public ThenSteps(Browser browser) {
    this.browser = browser;
  }

  public void myNameAppearsOnTheScreen(String login) {
    String div = browser.currentPage()
      .div(&quot;user&quot;).innerHTML();
    Assert.assertThat(div, containsString(login));
    Assert.assertThat(div, containsString(&quot;Logout&quot;));
  }
}
</pre>
<p>O arquivo de teste mesmo fica bem limpo, apenas com o roteiro que o teste vai seguir, e o trabalho &#8220;sujo&#8221; da implementação fica nos <em>given</em>, <em>when</em> e <em>then</em>, que podem ser reutilizados por qualquer teste. Esses objetos não precisam nem ser diferentes, não há necessidade de ter apenas um de cada na aplicação: você pode organizá-los da maneira que quiser. O importante é que no final o seu arquivo de teste fique limpo e escrito como se fosse uma especificaçao de uma funcionalidade ou a descrição de um cenário. Usando esse padrão fica fácil criar geradores de relatório, que analisam o arquivo da história e geram uma página HTML ou um arquivo de texto com as histórias que passaram e as que falharam.</p>
<p>Para conferir o resultado, você pode baixar o projeto que está usando essas idéias em: <a title="https://github.com/caelum/calopsita" href="https://github.com/caelum/calopsita">http://github.com/caueguerra/calopsita</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/behavior-driven-development-com-junit/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>

