<?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>marcuscavalcanti.net &#187; Tecnologia, Software &amp; Desenvolvimento</title>
	<atom:link href="http://www.marcuscavalcanti.net/blog/category/tecnologia-software-e-desenvolvimento/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.marcuscavalcanti.net/blog</link>
	<description>Software, tecnologia e etc.</description>
	<lastBuildDate>Sun, 22 Jan 2012 21:18:00 +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>Usando funções da Oracle com HSQLDB</title>
		<link>http://www.marcuscavalcanti.net/blog/2011/09/02/usando-funcoes-da-oracle-com-hsqldb/</link>
		<comments>http://www.marcuscavalcanti.net/blog/2011/09/02/usando-funcoes-da-oracle-com-hsqldb/#comments</comments>
		<pubDate>Fri, 02 Sep 2011 13:39:46 +0000</pubDate>
		<dc:creator>Marcus Cavalcanti</dc:creator>
				<category><![CDATA[Tecnologia, Software & Desenvolvimento]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[HSQLDB]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Teste]]></category>

		<guid isPermaLink="false">http://www.marcuscavalcanti.net/blog/?p=1462</guid>
		<description><![CDATA[Essa é uma dica simples e rápida para quem usa o banco de dados HSQLDB No meu caso específico, uso o HSQLDB para execução de testes funcionais e como a maioria desses projetos usam BD Oracle para desenvolvimento/produção, algumas queries acabam por conter funções específicas do Oracle, como: to_char, to_date, etc. Antes de dar a [...]]]></description>
			<content:encoded><![CDATA[<p>Essa é uma dica simples e rápida para quem usa o banco de dados <a href="http://hsqldb.org/" target="_blank" style="text-decoration: underline">HSQLDB</a></p>
<p>No meu caso específico, uso o HSQLDB para execução de <a href="http://testersoftware.blogspot.com/2010/08/casos-de-testes-funcionais.html" target="_blank" style="text-decoration: underline">testes funcionais</a> e como a maioria desses projetos usam BD Oracle para desenvolvimento/produção, algumas <em>queries</em> acabam por conter <a href="http://www.techonthenet.com/oracle/functions/" target="_blank" style="text-decoration: underline">funções</a> específicas do Oracle, como: to_char, to_date, etc.</p>
<p>Antes de dar a dica, é preciso dizer que esse recurso só funciona para as versões > 2.x do HSQLDB, portanto caso tentem usá-lo na versão 1.8 por exemplo, não será possível. Inclusive tive esse problema no meu projeto, pois como estou usando <a href="http://grails.org/1.3.7+Release+Notes" target="_blank" style="text-decoration: underline">Grails 1.3.7</a>, o <em>framework</em> por si só já vem com a dependência do HSQLDB 1.8 incluída por padrão e a solução encontrada para contornar isso foi usar o arquivo BuildConfig.groovy, primeiro removendo a dependência da versão 1.8 e depois incluindo a dependência da versão 2.x. Segue:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="groovy"><ol><li class="li1"><pre class="de1">grails.<span class="me1">project</span>.<span class="me1">dependency</span>.<span class="me1">resolution</span> <span class="sy0">=</span> <span class="br0">&#123;</span>   </pre></li><li class="li1"><pre class="de1">    inherits<span class="br0">&#40;</span><span class="st0">&quot;global&quot;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">		excludes<span class="br0">&#40;</span><span class="br0">&#91;</span>group: <span class="st0">'hsqldb'</span>, name: <span class="st0">'hsqldb'</span>, version:<span class="st0">'1.8.0.10'</span><span class="br0">&#93;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">    log <span class="st0">&quot;warn&quot;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">    repositories <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">		<span class="co1">// Repositorios para os plugins do grails</span></pre></li><li class="li1"><pre class="de1">		grailsHome<span class="br0">&#40;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">		grailsRepo <span class="st0">&quot;http://plugins.grails.org&quot;</span></pre></li><li class="li1"><pre class="de1">		grailsRepo <span class="st0">&quot;http://svn.codehaus.org/grails/trunk/grails-plugins&quot;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">		<span class="co1">// Repositorio necessario pois o maven baixa as dependencias e o grails as encontra no repositorio local</span></pre></li><li class="li1"><pre class="de1">		mavenLocal<span class="br0">&#40;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">		<span class="co1">// Repositorios da Ideais</span></pre></li><li class="li1"><pre class="de1">		mavenRepo <span class="st0">&quot;http://intranet/archiva/repository/internal/&quot;</span></pre></li><li class="li1"><pre class="de1">		mavenRepo <span class="st0">&quot;http://intranet/archiva/repository/ideais/&quot;</span></pre></li><li class="li1"><pre class="de1">		mavenRepo <span class="st0">&quot;http://intranet/archiva/repository/ideais-snapshots/&quot;</span></pre></li><li class="li1"><pre class="de1">		mavenRepo <span class="st0">&quot;http://intranet/archiva/repository/thirdparty/&quot;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">		<span class="co1">// Repositorio necessario para que o grails baixe suas proprias dependencias</span></pre></li><li class="li1"><pre class="de1">		mavenCentral<span class="br0">&#40;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">    <span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">    dependencies <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">		runtime<span class="br0">&#40;</span></pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'com.oracle'</span>, name:<span class="st0">'ojdbc14'</span>, version:<span class="st0">'10.2.0.3.0'</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">		<span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">		compile<span class="br0">&#40;</span></pre></li><li class="li1"><pre class="de1">			<span class="co1">//Lib para criptografia/descriptografia/mascaramento de numeros de cartao de credito</span></pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'com.b2w.billing'</span>, name:<span class="st0">'jsitef'</span>, version:<span class="st0">'1.0'</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">			<span class="co1">//Lib para resolver a dependencia do JAXB em ambiente de producao</span></pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'xalan'</span>, name:<span class="st0">'serializer'</span>, version:<span class="st0">'2.7.1'</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">			<span class="co1">//Libs para o spring-ws plugin</span></pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'org.springframework.ws'</span>,name:<span class="st0">'spring-ws'</span>,version:<span class="st0">'1.5.8'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'javax.activation'</span>,name:<span class="st0">'activation'</span>,version:<span class="st0">'1.1.1'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'com.russmiles.groovy.webservices'</span>,name:<span class="st0">'client'</span>,version:<span class="st0">'1.0-SNAPSHOT'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'org.springframework.security'</span>, name:<span class="st0">'spring-security-core'</span>, version:<span class="st0">'2.0.4'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'javax.xml.soap'</span>, name:<span class="st0">'saaj-api'</span>, version:<span class="st0">'1.3'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'javax.xml.soap'</span>, name:<span class="st0">'saaj-impl'</span>, version:<span class="st0">'1.3.2'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'org.bouncycastle'</span>, name:<span class="st0">'bcprov-jdk14'</span>, version:<span class="st0">'1.43'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'stax'</span>, name:<span class="st0">'stax-api'</span>, version:<span class="st0">'1.0.2'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'wsdl4j'</span>, name:<span class="st0">'wsdl4j'</span>, version:<span class="st0">'1.6.2'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'org.apache.ws.security'</span>, name:<span class="st0">'wss4j'</span>, version:<span class="st0">'1.5.8'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'org.apache.ws.commons.schema'</span>, name:<span class="st0">'XmlSchema'</span>, version:<span class="st0">'1.4.5'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>, </pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'xml-security'</span>, name:<span class="st0">'xmlsec'</span>, version:<span class="st0">'1.4.3'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">			<span class="co1">//Libs para o export plugin</span></pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'com.lowagie'</span>,name:<span class="st0">'itext'</span>,version:<span class="st0">'2.1.4'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'com.lowagie'</span>,name:<span class="st0">'iTextAsian'</span>,version:<span class="st0">'2.1.5'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'com.lowagie'</span>,name:<span class="st0">'itext-rtf'</span>,version:<span class="st0">'2.1.5'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'net.sourceforge.jexcelapi'</span>,name:<span class="st0">'jxl'</span>,version:<span class="st0">'ideais-commerce'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'org.openoffice.odf'</span>,name:<span class="st0">'odfdom'</span>,version:<span class="st0">'ideais-commerce'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'net.sf.opencsv'</span>,name:<span class="st0">'opencsv'</span>,version:<span class="st0">'1.8'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'xerces'</span>,name:<span class="st0">'xercesImpl'</span>,version:<span class="st0">'ideais-commerce'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">			<span class="co1">//Libs para o WSClient</span></pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'org.codehaus.groovy.modules'</span>,name:<span class="st0">'groovyws'</span>,version:<span class="st0">'0.5.1'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'org.apache.cxf'</span>, name: <span class="st0">'cxf-bundle'</span>, version: <span class="st0">'2.2.4'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'com.sun.xml.fastinfoset'</span>, name: <span class="st0">'FastInfoset'</span>, version: <span class="st0">'1.2.7'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'org.apache.geronimo.specs'</span>, name: <span class="st0">'geronimo-activation_1.1_spec'</span>, version: <span class="st0">'1.0.2'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'org.apache.geronimo.specs'</span>, name: <span class="st0">'geronimo-annotation_1.0_spec'</span>, version: <span class="st0">'1.1.1'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'org.apache.geronimo.specs'</span>, name: <span class="st0">'geronimo-javamail_1.4_spec'</span>, version: <span class="st0">'1.6'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'org.apache.geronimo.specs'</span>, name: <span class="st0">'geronimo-jaxws_2.1_spec'</span>, version: <span class="st0">'1.0'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'org.apache.geronimo.specs'</span>, name: <span class="st0">'geronimo-stax-api_1.0_spec'</span>, version: <span class="st0">'1.0.1'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'org.apache.geronimo.specs'</span>, name: <span class="st0">'geronimo-ws-metadata_2.0_spec'</span>, version: <span class="st0">'1.1.2'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'javax.xml'</span>, name: <span class="st0">'jaxb-api'</span>, version: <span class="st0">'2.1'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'com.sun.xml.bind'</span>, name: <span class="st0">'jaxb-impl'</span>, version: <span class="st0">'2.1.12'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'com.sun.xml.bind'</span>, name: <span class="st0">'jaxb-xjc'</span>, version: <span class="st0">'2.1.12'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'jaxen'</span>, name: <span class="st0">'jaxen'</span>, version: <span class="st0">'1.1'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'jdom'</span>, name: <span class="st0">'jdom'</span>, version: <span class="st0">'1.1'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'org.apache.neethi'</span>, name: <span class="st0">'neethi'</span>, version: <span class="st0">'2.0.4'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'woodstox'</span>, name: <span class="st0">'wstx-asl'</span>, version: <span class="st0">'3.2.7'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group: <span class="st0">'xml-resolver'</span>, name: <span class="st0">'xml-resolver'</span>, version: <span class="st0">'1.2'</span>, transitive: <span class="kw2">false</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">		<span class="br0">&#41;</span> </pre></li><li class="li1"><pre class="de1">		test<span class="br0">&#40;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">			<span class="co1">//Libs para integracao do GEB com SPOCK e do GEB com Webdriver</span></pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">&quot;org.codehaus.geb&quot;</span>, name:<span class="st0">&quot;geb-spock&quot;</span>, version:<span class="st0">&quot;0.6.0&quot;</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'org.seleniumhq.selenium'</span>, name:<span class="st0">'selenium-firefox-driver'</span>, version:<span class="st0">'2.0.0'</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'org.seleniumhq.selenium'</span>, name:<span class="st0">'selenium-chrome-driver'</span>, version:<span class="st0">'2.0.0'</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'org.seleniumhq.selenium'</span>, name:<span class="st0">'selenium-ie-driver'</span>, version:<span class="st0">'2.0.0'</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">			<span class="br0">&#91;</span>group:<span class="st0">'org.hsqldb'</span>, name:<span class="st0">'hsqldb'</span>, version:<span class="st0">'2.2.4'</span><span class="br0">&#93;</span>,</pre></li><li class="li1"><pre class="de1">		<span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">    <span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">&#125;</span></pre></li></ol></div></div></div></div></div></div></div>


<p>Já para usar sintaxes do Oracle com o HSQLDB, basta incluir a seguinte instrução no início do script SQL:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="sql"><pre class="de1"><span class="kw1">SET</span> <span class="kw1">DATABASE</span> <span class="kw1">SQL</span> SYNTAX ORA <span class="kw1">TRUE</span>;</pre></div></div></div></div></div></div></div>


<p>Para deixar isso automático, foi criado no arquivo <a href="http://www.grails.org/Bootstrap+Classes" target="_blank" style="text-decoration: underline">BootStrap.groovy</a> a seguite rotina:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="groovy"><ol><li class="li1"><pre class="de1"><span class="kw2">def</span> init <span class="sy0">=</span> <span class="br0">&#123;</span> servletContext <span class="sy0">-&gt;</span></pre></li><li class="li1"><pre class="de1">		<span class="kw2">def</span> envs <span class="sy0">=</span> <span class="br0">&#91;</span><span class="kw3">Environment</span>.<span class="me1">DEVELOPMENT</span>, <span class="kw3">Environment</span>.<span class="me1">TEST</span> <span class="br0">&#93;</span></pre></li><li class="li1"><pre class="de1">		<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">Environment</span>.<span class="me1">current</span> <span class="kw1">in</span> envs<span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">			<span class="kw1">if</span><span class="br0">&#40;</span><span class="kw3">Environment</span>.<span class="me1">current</span> <span class="sy0">==</span> <span class="kw3">Environment</span>.<span class="me1">TEST</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">				executeHSQLDBWithOracleQuerySyntax<span class="br0">&#40;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">			<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1">		<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw2">def</span> executeHSQLDBWithOracleQuerySyntax<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">		<span class="kw2">def</span> sqlString <span class="sy0">=</span> <span class="st0">&quot;SET DATABASE SQL SYNTAX ORA TRUE;&quot;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">		<span class="kw2">def</span> sql <span class="sy0">=</span> <span class="kw9">Sql</span>.<span class="me1">newInstance</span><span class="br0">&#40;</span></pre></li><li class="li1"><pre class="de1">			ConfigurationHolder.<span class="me1">config</span>.<span class="me1">dataSource</span>.<span class="me1">url</span>, </pre></li><li class="li1"><pre class="de1">			ConfigurationHolder.<span class="me1">config</span>.<span class="me1">dataSource</span>.<span class="me1">username</span>, </pre></li><li class="li1"><pre class="de1">			ConfigurationHolder.<span class="me1">config</span>.<span class="me1">dataSource</span>.<span class="me1">password</span>, </pre></li><li class="li1"><pre class="de1">			ConfigurationHolder.<span class="me1">config</span>.<span class="me1">dataSource</span>.<span class="me1">driverClassName</span></pre></li><li class="li1"><pre class="de1">		<span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">		sql.<span class="kw9">execute</span><span class="br0">&#40;</span>sqlString<span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span></pre></li></ol></div></div></div></div></div></div></div>


<p>Simples assim, agora a todo <em>start-up</em> da aplicação, quando o escopo for de teste, o HSQLDB já estará pronto para aceitar funções inerentes ao banco de dados Oracle.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuscavalcanti.net/blog/2011/09/02/usando-funcoes-da-oracle-com-hsqldb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Groovy + Grails</title>
		<link>http://www.marcuscavalcanti.net/blog/2011/07/29/groovy-grails/</link>
		<comments>http://www.marcuscavalcanti.net/blog/2011/07/29/groovy-grails/#comments</comments>
		<pubDate>Fri, 29 Jul 2011 05:21:26 +0000</pubDate>
		<dc:creator>Marcus Cavalcanti</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Tecnologia, Software & Desenvolvimento]]></category>
		<category><![CDATA[grails groovy jvm java framework]]></category>

		<guid isPermaLink="false">http://www.marcuscavalcanti.net/blog/?p=1410</guid>
		<description><![CDATA[Desenvolver para WEB com Java nunca foi algo prazeroso, eu particularmente que sou oriundo de linguagens dinâmicas e de frameworks RoR like, nunca gostei de desenvolver com Java para WEB. Já tive a oportunidade de participar de projetos que utilizam frameworks como: Apache Beehive, Struts e Mentawaii. Assim como também tive a oportunidade de testar [...]]]></description>
			<content:encoded><![CDATA[<p>Desenvolver para WEB com Java nunca foi algo prazeroso, eu particularmente que sou oriundo de <a href="http://en.wikipedia.org/wiki/Dynamic_programming_language" target="_blank" style="text-decoration: underline">linguagens dinâmicas</a> e de frameworks <a href="http://www.rubyonrails.org" target="_blank" style="text-decoration: underline">RoR</a> <em>like</em>, nunca gostei de desenvolver com Java para WEB. Já tive a oportunidade de participar de projetos que utilizam <em>frameworks</em> como: <a href="http://beehive.apache.org/" target="_blank" style="text-decoration: underline">Apache Beehive</a>, <a href="http://struts.apache.org/" target="_blank" style="text-decoration: underline">Struts</a> e <a href="http://www.mentaframework.org/" target="_blank" style="text-decoration: underline">Mentawaii</a>. Assim como também tive a oportunidade de testar outros como: <a href="http://wicket.apache.org/" target="_blank" style="text-decoration: underline">Wicket</a>, <a href="http://tapestry.apache.org/" target="_blank" style="text-decoration: underline">Tapestry</a>, <a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html" target="_blank" style="text-decoration: underline">Spring-MVC</a>, etc. Desses, o que mais se aproximou de algo razoável foi o Spring-MVC, que parece nunca ser levado a sério pela própria <a href="http://www.springsource.com/" target="_blank" style="text-decoration: underline">SpringSource</a>, que lançou a versão 3, mas nunca de forma realmente oficial, uma prova disso é que documentações a seu respeito são um tanto difíceis de serem achadas.</p>
<p>Quanto a <a href="http://www.oracle.com/technetwork/java/javaee/servlet/index.html" target="_blank" style="text-decoration: underline">Servlets</a> (um mal necessário) e <a href="http://www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html" target="_blank" style="text-decoration: underline">JSF</a> (e suas <a href="http://en.wikipedia.org/wiki/JavaServer_Faces" target="_blank" style="text-decoration: underline">N implementações</a>), prefiro nem citar a minha opinião.</p>
<p>Paralelo a isso, aconteceu toda uma <a href="http://www.marcuscavalcanti.net/blog/2009/03/17/ponto-para-o-rails/" target="_blank" style="text-decoration: underline">revolução</a> na maneira de pensar em desenvolvimento para WEB com o lançamento do Ruby on Rails &#8211; <em>framework</em> WEB da linguagem Ruby &#8211; que foi um verdadeiro marco e que acabou impactando quase todas as outras linguagens, inclusive o próprio Java. A <a href="http://en.wikipedia.org/wiki/KISS_principle" target="_blank" style="text-decoration: underline">idéia</a> do RoR é simples: facilitar, simplificar e tornar prazeroso o desenvolvimento para web. Seguir essa idéia sempre me pareceu uma boa opção.</p>
<h3>Java como plataforma</h3>
<p>Com todo esse advento dos novos <em>frameworks</em> WEB baseados no RoR e do crescimento de algumas linguagens como o próprio <a href="http://www.ruby-lang.org/en/" target="_blank" style="text-decoration: underline">Ruby</a>, <a href="http://www.python.org/" target="_blank" style="text-decoration: underline">Python</a> e até linguagens de <a href="http://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_funcional" target="_blank" style="text-decoration: underline">programação funcional</a>, o Java, que já tem um estigma de ser uma linguagem complexa e que demora a evoluir, acabou perdendo força na comunidade como linguagem, mas em compensação passou a ser mais notada  como plataforma, principalmente por causa do poder da <a href="http://en.wikipedia.org/wiki/Java_Virtual_Machine" target="_blank" style="text-decoration: underline">JVM</a> e das possibilidades que a mesma trás, com isso alguns projetos interessantes como <a href="http://www.jython.org/" target="_blank" style="text-decoration: underline">Jython</a> e <a href="http://www.jruby.org/" target="_blank" style="text-decoration: underline">JRuby</a> surgiram e esses projetos nada mais são do que outras linguagens rodando em cima da JVM, ou seja, é possível desenvolver código Python e no final o mesmo virar <em><a href="http://en.wikipedia.org/wiki/Java_bytecode" target="_blank" style="text-decoration: underline">byte-code</a></em> e ser executado pela JVM.</p>
<p>E é nesse ponto que eu quero chegar, o assunto do próximo tópico.</p>
<h3>Groovy</h3>
<p><a href="http://groovy.codehaus.org/" target="_blank" style="text-decoration: underline">Groovy</a> é uma nova linguagem, que roda em cima da JVM e que foi pensada de uma forma para ser dinâmica, simples e enxuta e ainda com a vantagem de poder se usar as <a href="http://en.wikipedia.org/wiki/Application_programming_interface" target="_blank" style="text-decoration: underline">API&#8217;s</a> do Java.</p>
<p>Fora isso, foram criadas API&#8217;s específicas do próprio Groovy que facilitam muito o uso de alguns recursos/api&#8217;s do Java, como: coleções, mapas, strings, arquivos, etc.</p>
<p>A grande diferença do Groovy para o Java, é que o Groovy é uma linguagem de tipagem dinâmica, o que inicialmente pode ser um perigo para programadores habituados com Java, mas depois desse &#8220;trauma&#8221; inicial, a linguagem se mostra extremamente poderosa através de recursos como a possibilidade de se definir <a href="http://martinfowler.com/bliki/DomainSpecificLanguage.html" target="_blank" style="text-decoration: underline">DSL&#8217;s</a>.</p>
<p>Outra possibilidade interessante, é que é possível construir <em>scripts</em> com a linguagem Groovy, o que é uma verdadeira mão na roda para criação de rotinas de automatização, <em>builds</em>, etc.</p>
<h3>Grails</h3>
<p><a href="http://grails.org/" target="_blank" style="text-decoration: underline">Grails</a> é um <em>framework</em> Groovy para WEB baseado no RoR e que tenta resolver todos os problemas já citados da burocracia de se desenvolver para WEB com Java.</p>
<p>Dentro do &#8220;pacotão&#8221; do Grails, já vem embutidos recursos como: <a href="http://www.grails.org/doc/1.3.7/guide/8.%20The%20Service%20Layer.html#8.3%20Dependency%20Injection%20and%20Services" target="_blank" style="text-decoration: underline">injeção de dependência</a>, <a href="http://grails.org/doc/1.3.7/guide/5.%20Object%20Relational%20Mapping%20%28GORM%29.html" target="_blank" style="text-decoration: underline">mapeamento objeto relacional</a>, segurança, <a href="http://www.grails.org/doc/1.3.7/guide/9.%20Testing.html" target="_blank" style="text-decoration: underline">testes</a> (unitários e funcionais), <a href="http://grails.org/doc/1.3.7/ref/Constraints/Usage.html" target="_blank" style="text-decoration: underline">validações</a>, etc. Além do que, o <em>framework</em> é completamente focado em uma abordagem <em><a href="http://en.wikipedia.org/wiki/Anemic_Domain_Model" target="_blank" style="text-decoration: underline">rich domain</a></em>, diferentemente de outros <em>frameworks</em>.</p>
<p>Outro recurso muito interessante são os <em><a href="http://www.grails.org/plugins/" target="_blank" style="text-decoration: underline">plugins</a></em>, que são como mini-aplicações que podem ser instaladas dentro do Grails de acordo com a sua necessidade. Atualmente existem muitos plugins disponíveis no repositório do Grails e que atendem as mais variadas necessidades.</p>
<p>O <em>framework</em> é todo baseado em <a href="http://en.wikipedia.org/wiki/Convention_over_configuration" target="_blank" style="text-decoration: underline">convenções</a> e dispensa o uso de complexos arquivos XML para fins de configurações, o que no final das contas acaba sendo mais um fator para facilitar e agilizar o desenvolvimento, pois dessa maneira a equipe de desenvolvimento acaba ficando focada no que realmente interessa, que são os requisitos de negócio.</p>
<h3>Porque escolhi Groovy+Grails</h3>
<p>Antes de mais nada, escolhi por todos os motivos apresentados anteriormente, talvez até não tivesse toda essa visibilidade no começo do projeto, mas como o projeto novo não apresentava desafios muito grandes e ao mesmo tempo não era tão crítico, pensei que uma boa maneira em deixar minha equipe motivada seria investir em uma nova tecnologia.</p>
<p>Fora o fato, que como a equipe tinha experiência com Java, na pior das hipóteses, no caso da não adaptação da equipe com o Groovy, poderíamos usar códigos Java dentro do projeto, já que a linguagem permite isso, ou seja, foi um risco, mas um risco controlado e calculado.</p>
<p>Outro fator que contou muito para escolha dessa dobradinha, foi que passamos a adotar uma abordagem mais ágil e interativa com a presença mais próxima do cliente junto ao time de desenvolvimento e isso significava que deveríamos ter algo entregável toda semana, que foi a periodicidade que definimos para as nossas iterações. A adoção do Groovy e Grails agilizaria nosso tempo de desenvolvimento, consequentemente conseguiríamos produzir mais <em>features</em> em menos tempo, que era exatamente o que estavámos buscando.</p>
<h3> Qual tem sido a minha experiência</h3>
<p>A melhor possível. Quando eu digo a melhor possível, é porque tem sido melhor que o esperado, mas obviamente, como tudo na vida, tem seus prós e contras.</p>
<p>Um dos pontos positivos, foi que a curva de aprendizado foi bem menor do que o esperado, ou seja, a equipe entrou no &#8220;ritmo&#8221; do <em>framework</em> bem rápido.</p>
<p>Outro ponto positivo, é a abordagem do <em>framework</em> de ser realmente orientado a objetos, favorecendo uso de uma modelagem focada em domínio rico e testes. Para toda entidade, <em>service</em>, ou <em>controller</em> novos criados, automaticamente um teste já é criado, ou seja, isso torna claro para o desenvolvedor, que seguindo os conceitos do <a href="http://www.agiledata.org/essays/tdd.html" target="_blank" style="text-decoration: underline">TDD</a>, o mais aconselhável é que os testes sejam criados antes da implementação, pois só dessa maneira o <em>design</em> do seu código será influenciado para se tornar mais coeso, menos acoplado e com as camadas bem definidas de acordo com a sua responsabilidade dentro do contexto.</p>
<p>Como o <em>framework</em> é <em>full-stack</em> e baseado em convenções, configurar um projeto e rodar tem o custo quase zero, ou seja, muito pouco tempo é disperdiçado.</p>
<p>Como nem tudo são flores, tivemos um impacto inicial com a curva de aprendizado de uma linguagem dinâmica (para quem não tinha prática com isso), fora os novos conceitos do próprio <em>framework</em>. Mas volto a repetir: o impacto foi menor que o previsto. Para resolver esse tipo de problema, adotamos algumas medidas como: <em><a href="http://www.extremeprogramming.org/rules/pair.html" target="_blank" style="text-decoration: underline">pair programming</a></em> e um grupo de estudo interno para troca de conhecimento, onde cada um deveria mostrar algum tópico em que já tivesse mais avançado, para o restante.</p>
<p>Outro impacto que tivemos foram de algumas peculiaridades do <em>framework</em>, que apesar de ser muito bom, ainda apresenta alguns pequenos <em>bugs</em> (e até manhas) que demoram a serem notados. Como o <em>framework</em> está em evolução e ainda em versão 1.*, é normal que esteja um pouco imaturo, portanto não o recomendaria ainda para um projeto mais complexo e crítico.</p>
<p><a href="http://en.wikipedia.org/wiki/Integrated_development_environment" target="_blank" style="text-decoration: underline">IDE&#8217;s</a> ainda são um problema quando se pensa em Groovy + Grails, na verdade, existe uma IDE muito boa, mas que é paga e não é o <a href="http://www.eclipse.org/home/categories/index.php?category=ide" target="_blank" style="text-decoration: underline">Eclipse</a>, IDE no qual a maioria dos desenvolvedores Java já está acostumada. Essa IDE é o <a href="http://www.jetbrains.com/idea/" target="_blank" style="text-decoration: underline">Intellij</a> da Jet Brains, no qual já testei e realmente é a melhor opção no mercado.</p>
<h3>Conclusão</h3>
<p>Recomendaria Groovy+Grails se você tem uma visão semelhante a minha sobre desenvolvimento para WEB com Java e também se você tiver a oportunidade de usá-los em algum projeto sem muita criticidade e complexidade (apesar de existirem alguns <em><a href="http://www.grails.org/Success+Stories" target="_blank" style="text-decoration: underline">cases</a></em>), mas é importante mensurar sempre os riscos da adoção de algo novo, pois no final isso pode ser irreversível.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuscavalcanti.net/blog/2011/07/29/groovy-grails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testes: TDD e BDD.</title>
		<link>http://www.marcuscavalcanti.net/blog/2011/07/26/testes-tdd-e-bdd/</link>
		<comments>http://www.marcuscavalcanti.net/blog/2011/07/26/testes-tdd-e-bdd/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 15:44:47 +0000</pubDate>
		<dc:creator>Marcus Cavalcanti</dc:creator>
				<category><![CDATA[Tecnologia, Software & Desenvolvimento]]></category>
		<category><![CDATA[teste testes tdd bdd]]></category>

		<guid isPermaLink="false">http://www.marcuscavalcanti.net/blog/?p=1395</guid>
		<description><![CDATA[Há algum tempo atrás, havia escrito sobre BDD e a verdade é que minha opinião sobre BDD não mudou, mas acho válido explicar um pouco melhor sobre a relação TDD e BDD, suas diferenças e da viabilidade de usar uma ou outra abordagem, pois tenho visto algumas pessoas fazendo confusão sobre os dois conceitos. Diferenças [...]]]></description>
			<content:encoded><![CDATA[<p>Há algum tempo atrás, havia <a href="http://www.marcuscavalcanti.net/blog/2010/01/07/algumas-observacoes-sobre-bdd/" style="text-decoration: underline" target="_blank">escrito sobre BDD</a> e a verdade é que minha opinião sobre BDD não mudou, mas acho válido explicar um pouco melhor sobre a relação TDD e BDD, suas diferenças e da viabilidade de usar uma ou outra abordagem, pois tenho visto algumas pessoas fazendo confusão sobre os dois conceitos.</p>
<h3>Diferenças</h3>
<p>Enquanto TDD é focado em testes unitários, BDD é focado em <a href="http://www.extremeprogramming.org/rules/functionaltests.html" style="text-decoration: underline" target="_blank">testes de aceitação</a>, a grande diferença que isso trás é que o BDD é algo muito mais &#8220;<em>human-readable</em>&#8221; e o ganho disso é que a equipe de desenvolvimento consegue definir os testes juntamente com a equipe de negócios, ou com o <a href="http://epf.eclipse.org/wikis/scrumpt/Scrum/roles/product_owner_10E7BD3.html" style="text-decoration: underline" target="_blank">PO</a>. Na verdade, acredito que o cenário é ideal é onde junto a um cartão de uma nova funcionalidade/mudança, já venha o seu teste de aceitação, ambos criados pelo PO.</p>
<p>Se for o caso da equipe criar o teste funcional, ou de aceitação (como preferir), a equipe pode alinhar junto com o cliente se aquele teste atende a funcionalidade/alteração pedida. Dessa maneira, temos quase uma garantia de que o que vai ser entregue está dentro do que realmente o cliente espera.</p>
<p>Para guiar <em>design</em> do código, eu particularmente acho que TDD é muito mais eficiente, pois através dos testes unitários e principalmente pelo ciclo do TDD, é muito mais fácil notar alguns conceitos como alta coesão/baixo acoplamento e também a <a href="http://www.devmedia.com.br/post-18699-Amadurecendo-com-Separation-Of-Concerns.html" style="text-decoration: underline" target="_blank">divisão de responsabilidades</a> (<em>separation of concerns</em>).</p>
<h3>Uma abordagem anula a outra?</h3>
<p>A resposta é não. Eu particularmente gosto muito de trabalhar com as duas abordagens em meus projetos, onde TDD guia o desenvolvimento (<em>design</em> de código, <em>refactoring</em>, etc) e o BDD dá o suporte necessário para testes e prevenção de <em>bugs</em>.</p>
<p>Inclusive, uma abordagem que eu adoto junto a minha equipe e que acho muito eficiente, é para cada <em>bug</em> reportado pelo cliente, de criar um teste funcional para o mesmo, dessa maneira evitamos o clássico problema de <em>bugs</em> recorrentes.</p>
<p>Em ferramentas de <a href="http://improveit.com.br/xp/praticas/integracao" style="text-decoration: underline" target="_blank">integração contínua</a>, inclusive costumamos separar os <em>builds</em>. Temos um <em>build</em> de compilação + testes unitários, outro de testes funcionais e outro de testes integrados. A razão dessa separação, é evitar que os <a href="http://jamesshore.com/Blog/Forces-Affecting-Continuous-Integration.html" style="text-decoration: underline" target="_blank"><em>builds</em> fiquem excessivamente lentos</a> e fazer com que a equipe perca o valor principal da integração contínua que é o <em>feedback</em> rápido, mas todo dia temos um <em>nightly build</em> que executa todos os tipos de teste, assim como em dia de entregas oficiais, já que também rodamos o <em>build</em> com todos esses testes.</p>
<p>Ah, usar BDD para testes integrados também acho uma abordagem muito válida. Minha equipe tem trabalhado em um projeto <a href="http://groovy.codehaus.org/" style="text-decoration: underline" target="_blank">Groovy</a>/<a href="http://grails.org/" style="text-decoration: underline" target="_blank">Grails</a> e estamos usando o <a href="http://spockframework.org/" style="text-decoration: underline" target="_blank">Spock</a> + <a href="http://www.gebish.org/" style="text-decoration: underline" target="_blank">GEB</a> e os resultados tem sido muito bons.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuscavalcanti.net/blog/2011/07/26/testes-tdd-e-bdd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lidando com o fim de um projeto</title>
		<link>http://www.marcuscavalcanti.net/blog/2010/12/28/lidando-com-o-fim-de-um-projeto/</link>
		<comments>http://www.marcuscavalcanti.net/blog/2010/12/28/lidando-com-o-fim-de-um-projeto/#comments</comments>
		<pubDate>Wed, 29 Dec 2010 02:24:23 +0000</pubDate>
		<dc:creator>Marcus Cavalcanti</dc:creator>
				<category><![CDATA[Tecnologia, Software & Desenvolvimento]]></category>
		<category><![CDATA[projeto escopo]]></category>

		<guid isPermaLink="false">http://www.marcuscavalcanti.net/blog/?p=1379</guid>
		<description><![CDATA[É inevitável que um projeto chegue ao fim, na verdade, se pensarmos na teoria, todo projeto deve começar com o seu escopo bem definido e isso inclui uma data de entrega. O pessoal que trabalha com ágil pode dizer &#8220;mas nós trabalhamos com ciclos interativos e é o cliente quem define as prioridades&#8221;, sim, é [...]]]></description>
			<content:encoded><![CDATA[<p>É inevitável que um <a href="http://pt.wikipedia.org/wiki/Projeto" target="_blank" style="text-decoration: underline">projeto</a> chegue ao fim, na verdade, se pensarmos na teoria, todo projeto deve começar com o seu escopo bem definido e isso inclui uma data de entrega. O pessoal que trabalha com <a href="http://pt.wikipedia.org/wiki/Desenvolvimento_%C3%A1gil_de_software" target="_blank" style="text-decoration: underline">ágil</a> pode dizer &#8220;mas nós trabalhamos com ciclos interativos e é o cliente quem define as prioridades&#8221;, sim, é verdade, mas todo cliente quer uma data de quando o projeto será entregue. Até mesmo, porque o cliente tem seu planejamento e seu orçamento e tudo isso gira em torno do tempo de execução do projeto.</p>
<p>No final do projeto, é normal que a equipe começe a ter ciclos de ociosidade, justamente porque novas <em>features</em> não serão adicionadas, <em>bugs</em> críticos já foram corrigidos e o projeto já está estável o suficiente para ir para produção. Só que essa ociosidade da equipe, pode trazer danos irreverssíveis, como: insatisfação, desinteresse, frear o ritmo da equipe, esquecimento de pontos específicos do projeto, etc. </p>
<p>Imagino que nenhuma equipe queira passar pelos problemas expostos acima, por isso o final do projeto deve ser enxergado como uma oportunidade de melhorar o que já existe, de mudar alguma tecnologia que esteja &#8220;desatualizada&#8221;, de documentar o que for necessário e de refletir sobre erros e acertos. Uma estratégia que tenho usado e que tem me ajudado muito nesses momentos, é de criar uma espécie <em><a href="http://improveit.com.br/scrum/product_backlog"  target="_blank" style="text-decoration: underline">backlog</a></em> de tudo que pode ser melhorado no projeto, mas que não é crítico em determinado momento, depois, conforme for sobrando tempo, vou priorizando esse <em>backlog</em> e executando com a equipe as melhorias pontualmente.</p>
<p>Atualmente estou em um projeto, que devido ao escopo ser muito apertado, eu e minha equipe tivemos que abrir mão de qualidade para podermos entregar o projeto no tempo estimado. Isso, como pode-se imaginar, gerou alguns códigos difíceis de manter. Minha equipe também era um pouco imatura no início do projeto e isso também impactou diretamente na qualidade do código. Para piorar, muitas regras de negócio foram sendo definidas em <em>runtime</em> pelo cliente e é claro que isso também impactou na qualidade do projeto. Como o projeto está de certa forma estabilizado, o momento para pensar em melhorias e algumas mudanças é agora e isso passa a ser a arma do líder de projeto para manter sua equipe motivada, ocupada e no seu ritmo. Sem contar o fato de que as melhorias, tirarão das costas própria equipe o trabalho árduo de manutenção no futuro (o que poderia também desmotivar a equipe).</p>
<p>Vale ressaltar, que nesse momento do projeto, o líder deve ter todo cuidado para que essas melhorias feitas através de técnicas de <a href="http://pt.wikipedia.org/wiki/Refatora%C3%A7%C3%A3o"  target="_blank" style="text-decoration: underline">refatoração</a> não impactem o funcionamento do projeto, afinal a definição mais simplista de refatoração é: melhorar algo que já existe, mas mantendo o seu comportamento original. </p>
<p>Além disso, o líder sempre deve contar com a possibilidade do cliente solicitar alguma mudança ou resolução de algum <em>bug</em> durante esse processo de melhoria, e para não ser pego de surpresa, o que eu indico é que o processo de melhoria seja feito paralelamente a última versão de código do projeto entregue ao cliente. Como fazer isso? Usando o famoso <em><a href="http://en.wikipedia.org/wiki/Trunk_(software)"  target="_blank" style="text-decoration: underline">trunk</a></em> (última versão entregue ao cliente) e <em><a href="http://en.wikipedia.org/wiki/Branching_(software)"  target="_blank" style="text-decoration: underline">branch</a></em> (versão gerada a partir do <em>trunk</em> e onde será feita o processo de melhoria). Depois, todo cuidado é pouco durante o <a href="http://www.sepcot.com/blog/2007/04/SVN-Merge-Branch-Trunk"  target="_blank" style="text-decoration: underline"><em>merge</em></a> dessas alterações e é nesse momento, onde os <a href="http://pt.wikipedia.org/wiki/Teste_de_software"  target="_blank" style="text-decoration: underline">testes</a>, que inicialmente foram esquecidos, irão ajudar muito!</p>
<p>O principal objetivo do <a href="http://pt.wikipedia.org/wiki/Test_Driven_Development" target="_blank" style="text-decoration: underline">desenvolvimento orientado a testes (TDD)</a> é direcionar o <em>design</em> do código para que o mesmo fique claro e legível o suficiente para suportar manutenções e ser escalável, mas outro ponto do TDD, é que os testes sejam uma maneira de fornecer segurança aos programadores para realização de melhorias (refatorações), por isso, se você teve que abrir mão de testes no começo do projeto, não deixe de pensar neles no final, mesmo que isso não seja o mais indicado e que o  ciclo do TDD não indique isso, mas como já sabemos, na teoria as coisas são de um jeito, na prática elas são de outra.</p>
<p>Seguem algumas dicas de tarefas que podem ser executadas/pensadas na fase de término do projeto:</p>
<p>- <a href="http://pt.wikipedia.org/wiki/Teste_de_unidade" target="_blank" style="text-decoration: underline">Testes unitários</a><br />
- <a href="http://pt.wikipedia.org/wiki/Teste_de_aceita%C3%A7%C3%A3o" target="_blank" style="text-decoration: underline">Testes de interface/aceitação</a><br />
- <a href="http://pt.wikipedia.org/wiki/Teste_de_integra%C3%A7%C3%A3o" target="_blank" style="text-decoration: underline">Testes integrados</a><br />
- <a href="http://improveit.com.br/xp/praticas/programacao_par"  target="_blank" style="text-decoration: underline">Programação em par</a> (o uso em processos de refatoração é muito válido e tem um resultado muito positivo)<br />
- <a href="http://imasters.com.br/artigo/15444/desenvolvimento/coding_standards/" target="_blank" style="text-decoration: underline">Padronização do código</a><br />
- Documentação do código<br />
- Estudo de novas tecnologias/frameworks/linguagens (para os próximos projetos ou até mesmo projeto atual)<br />
- Melhoria de performance de algum ponto da aplicação que possivelmente possa ser um gargalo no futuro<br />
- Troca de opiniões entre a equipe para melhoria do processo de desenvolvimento<br />
- Reuniões para discussão de erros e acertos do projeto</p>
<p>Para finalizar, gostaria de ressaltar que essas são observações baseadas na minha própria experiência como líder de projeto e que não tem relação direta com nenhuma metodologia, na verdade são pontos relevantes e que certamente muitos tem como referência pontos específicos de diversas metodologias.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuscavalcanti.net/blog/2010/12/28/lidando-com-o-fim-de-um-projeto/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>BDD com JBehave</title>
		<link>http://www.marcuscavalcanti.net/blog/2010/01/08/bdd-com-jbehave/</link>
		<comments>http://www.marcuscavalcanti.net/blog/2010/01/08/bdd-com-jbehave/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 19:39:55 +0000</pubDate>
		<dc:creator>Marcus Cavalcanti</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Tecnologia, Software & Desenvolvimento]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Testes]]></category>

		<guid isPermaLink="false">http://www.marcuscavalcanti.net/blog/?p=1304</guid>
		<description><![CDATA[Conforme prometido no tópico anterior, irei mostrar o conceito de BDD através da utilização do framework JBehave, que é o framework de BDD mais famoso para Java e que foi desenvolvido pelo Dan North, o idealizador deste conceito. Antes de mais nada, vamos citar alguns conceitos importantes de BDD. Estórias e Cenários BDD é baseado [...]]]></description>
			<content:encoded><![CDATA[<p>Conforme prometido no <a href="http://www.marcuscavalcanti.net/blog/2010/01/07/algumas-observacoes-sobre-bdd/" style="text-decoration: underline" target="_blank">tópico anterior</a>, irei mostrar o conceito de <a href="http://dannorth.net/introducing-bdd" style="text-decoration: underline" target="_blank">BDD</a> através da utilização do <em>framework</em> <a href="http://jbehave.org/" style="text-decoration: underline" target="_blank">JBehave</a>, que é o <em>framework</em> de BDD mais famoso para Java e que foi desenvolvido pelo <a href="http://dannorth.net/" style="text-decoration: underline" target="_blank">Dan North</a>, o idealizador deste conceito.</p>
<p>Antes de mais nada, vamos citar alguns conceitos importantes de BDD.</p>
<h3>Estórias e Cenários</h3>
<p>BDD é baseado em estórias e cenários, e para criarmos ambos, vamos seguir alguns padrões pré-definidos por autores de BDD. Uma vez que BDD é focado em comportamento e sequência, as estórias e cenários devem ter um formato rígido para que as ferramentas consigam entendê-los e interpretá-los.</p>
<p>As estórias, possuem o seguinte formato:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">As I [X]
I want [Y]
so that [Z]</pre></div></div></div></div></div></div></div>


<p>E os cenários possuem o seguinte formato:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">Given some initial context (the givens),
When an event occurs,
then ensure some outcomes.</pre></div></div></div></div></div></div></div>


<p>Ou seja, isso quer dizer que devemos pensar em nossos requisitos de maneira que possam ser escritos baseados nessa convenção.</p>
<p>O JBehave é originalmente escrito para entender estórias em inglês, entretanto como BDD é focado em pessoas (<em>stakeholders</em>) e na descrição de situações reais, faz muito mais sentido semanticamente que as estórias e cenários sejam escritos em português e para resolver isso, usei uma <a href="http://codificando.com/2009/04/15/jbehave-brasil-bdd-em-java-no-nosso-idioma/" target="_blank" style="text-decoration: underline">contribuição</a> do <a href="http://codificando.com/" target="_blank" style="text-decoration: underline">Emerson Macedo</a> para que os cenários possam ser escritos e entendidos em português pelo JBehave.</p>
<h3>Começando com o JBehave</h3>
<p>O primeiro passo para utilização do JBehave, é fazer <em><a href="http://jbehave.org/software/download/" target="_blank" style="text-decoration: underline" class="broken_link">download</em> do JAR</a> do projeto e incluí-lo no <em>classpath</em> do seu projeto.</p>
<p>O próximo passo é escrever a estória juntamente com o cenário e para tal resolvi criar um exemplo simples para que o entendimento do conceito possa ser casado através do código a ser desenvolvido. </p>
<p>O exemplo escolhido é baseado no requisito: <strong>Compra de produtos em promoção com aviso por email</strong>. E é isso que nosso cenário BDD deve descrever.</p>
<p>Por questão de organização, resolvi quebrar a estória em 3 cenários diferentes, onde a primeira parte representa a verificação de produtos em promoção, a segunda representa a compra desses produtos e o terceiro é a finalização da compra e o envio de email. Então, a estória e os cenários ficaram assim:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">Compra de produtos em promoção com aviso por email
&nbsp;
Narrativa:
Como um usuário
Eu quero comprar produtos em promoção
E então receber um email de confirmação
&nbsp;
Cenário: Verificar produtos em promoção
Dado Que uma loja possui 10 produtos
E Que 5 estão em promoção
Quando Eu verifico quais estão em promoção
Então Preencho minha sacola apenas com produtos em promoção
&nbsp;
Cenário: Comprar produtos em promoção
Dado Que minha sacola de compras está preenchida com 5 produtos em promoção
Quando Eu verifico o somatório de produtos
Então Devo ter somente um total de 500 reais em produtos
&nbsp;
Cenário: Enviar email
Dado Que minha sacola está preenchida de produtos
Quando Enviar um email de confirmação
Então Devo receber o status do envio &quot;true&quot;</pre></div></div></div></div></div></div></div>


<p>A primeira linha do arquivo texto representa o título da nossa estória, o requisito de fato. A narrativa é um resumo do que essa estória deve cumprir e a seguir vem os três cenários, que no caso são as três etapas da estória.</p>
<p>É importante notar, que as palavras chaves em inglês (<em>Given</em>, <em>When</em>, <em>Then</em>, <em>And</em>) foram substituídas  por palavras em português (Dado, Quando, Então, E).</p>
<p>Esse arquivo texto deve ser salvo com a extensão <em>*.cenario</em> e o seu nome está diretamente ligado a classe que irei criar no passo a seguir, que no caso é a classe que representa a estória e a associação com os cenários.</p>
<h3>Criando a classe que irá comportar os cenários</h3>
<p>Nesse passo irei criar a classe que irá apontar os cenários que compõe a estória e essa classe deve extender a classe <a href="http://jbehave.org/reference/stable/concepts.html" target="_blank" style="text-decoration: underline"><em>Scenario</em></a> do JBehave. Dessa forma, a classe ficaria assim:</p>
<p><strong>PrecoPromocaoTeste.java</strong></p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">package</span> <span class="co2">scenario1</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">scenario1.steps.CompraSteps</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">scenario1.steps.EmailSteps</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">scenario1.steps.PromocaoSteps</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">scenario1.util.PtBRScenario</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">class</span> PrecoPromocaoTeste <span class="kw1">extends</span> PtBRScenario <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw1">public</span> PrecoPromocaoTeste<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">           addSteps<span class="br0">&#40;</span><span class="kw1">new</span> PromocaoSteps<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">           addSteps<span class="br0">&#40;</span><span class="kw1">new</span> CompraSteps<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">           addSteps<span class="br0">&#40;</span><span class="kw1">new</span> EmailSteps<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">&#125;</span></pre></li></ol></div></div></div></div></div></div></div>


<p>No exemplo acima, estou extendo a classe <em>PtBRScenario</em> só para que a estória e o cenário sejam escritos em português, mas essa classa herda a classe <em>Scenario</em> como descrito anteriormente.</p>
<p>No construtor da classe, inclui os passos que a estória deve seguir para ser satisfeita e como quebrei a estória em três pedaços, precisei incluir três passos sequenciados.</p>
<h3>Criando os passos da estória</h3>
<p>Como a estória foi quebrada em três partes, se faz por necessário a criação de 3 classes que irão representar os passos da estória e todas essas classes devem herdar a classe <em><a href="http://jbehave.org/reference/stable/concepts.html" target="_blank" style="text-decoration: underline">Steps</a></em> do JBehave.</p>
<p>Pela ordem definida na nossa classe de cenário, vamos aos passos:</p>
<p><strong>PromocaoSteps.java</strong></p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">package</span> <span class="co2">scenario1.steps</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">java.util.List</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">junit.framework.Assert</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.jbehave.scenario.annotations.Given</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.jbehave.scenario.annotations.Then</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.jbehave.scenario.annotations.When</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">scenario1.entity.Loja</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">scenario1.entity.Produto</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">scenario1.util.PtBRSteps</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">scenario1.vo.Sacola</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">class</span> PromocaoSteps <span class="kw1">extends</span> PtBRSteps <span class="br0">&#123;</span>	</pre></li><li class="li1"><pre class="de1">	Loja loja 		<span class="sy0">=</span> <span class="kw1">new</span> Loja<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	Sacola sacola 	<span class="sy0">=</span> <span class="kw1">new</span> Sacola<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	List<span class="sy0">&lt;</span>Produto<span class="sy0">&gt;</span> listaProdutoPromocao<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw4">int</span> quantidadeProdutoPromocao<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">	@Given<span class="br0">&#40;</span><span class="st0">&quot;Que uma loja possui $quant produtos&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw1">public</span> <span class="kw4">void</span> populaLoja<span class="br0">&#40;</span><span class="kw3">Integer</span> quantidade<span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">		loja.<span class="me1">inicializaProdutos</span><span class="br0">&#40;</span>quantidade<span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span>	</pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">	@Given<span class="br0">&#40;</span><span class="st0">&quot;Que $quant estão em promoção&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw1">public</span> <span class="kw4">void</span> informaProdutosPromocao<span class="br0">&#40;</span><span class="kw3">Integer</span> quantidade<span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">		loja.<span class="me1">colocaProdutosPromocao</span><span class="br0">&#40;</span>quantidade<span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">		quantidadeProdutoPromocao <span class="sy0">=</span> quantidade<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span>	</pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">	@When<span class="br0">&#40;</span><span class="st0">&quot;Eu verifico quais estão em promoção&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw1">public</span> <span class="kw4">void</span> verificaProdutosPromocao<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>		</pre></li><li class="li1"><pre class="de1">		listaProdutoPromocao <span class="sy0">=</span> loja.<span class="me1">retornaProdutosPromocao</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">	@Then<span class="br0">&#40;</span><span class="st0">&quot;Preencho minha sacola apenas com produtos em promoção&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw1">public</span> <span class="kw4">void</span> populaSacola<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">		sacola.<span class="me1">populaSacola</span><span class="br0">&#40;</span>listaProdutoPromocao<span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">		<span class="kw1">Assert</span>.<span class="me1">assertEquals</span><span class="br0">&#40;</span>listaProdutoPromocao.<span class="me1">size</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, quantidadeProdutoPromocao<span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">&#125;</span></pre></li></ol></div></div></div></div></div></div></div>


<p><strong>CompraSteps.java</strong></p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="java"><ol><li class="li1"><pre class="de1"><span class="kw1">package</span> <span class="co2">scenario1.steps</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">java.util.ArrayList</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">java.util.List</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">junit.framework.Assert</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.jbehave.scenario.annotations.Given</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.jbehave.scenario.annotations.Then</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.jbehave.scenario.annotations.When</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">scenario1.entity.Produto</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">scenario1.util.PtBRSteps</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">scenario1.vo.Sacola</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">class</span> CompraSteps <span class="kw1">extends</span> PtBRSteps <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">	Sacola sacola 				<span class="sy0">=</span> <span class="kw1">new</span> Sacola<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw4">double</span> somatorioProdutos 	<span class="sy0">=</span> 0d<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">	@Given<span class="br0">&#40;</span><span class="st0">&quot;Que minha sacola de compras está preenchida com $quant produtos em promoção&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw1">public</span> <span class="kw4">void</span> verificaSacola<span class="br0">&#40;</span><span class="kw3">Integer</span> quantidade<span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">		List<span class="sy0">&lt;</span>Produto<span class="sy0">&gt;</span> listaProduto <span class="sy0">=</span> <span class="kw1">new</span> ArrayList<span class="sy0">&lt;</span>Produto<span class="sy0">&gt;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">		<span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">int</span> i<span class="sy0">=</span><span class="nu0">1</span><span class="sy0">;</span> i<span class="sy0">&lt;=</span>quantidade<span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">			Produto produto 	<span class="sy0">=</span> <span class="kw1">new</span> Produto<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">			produto.<span class="me1">preco</span> 		<span class="sy0">=</span> <span class="kw3">Math</span>.<span class="me1">round</span><span class="br0">&#40;</span><span class="kw3">Math</span>.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">*</span><span class="nu0">100</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">			produto.<span class="me1">emPromocao</span> 	<span class="sy0">=</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">			listaProduto.<span class="me1">add</span><span class="br0">&#40;</span>produto<span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">		<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">		sacola.<span class="me1">populaSacola</span><span class="br0">&#40;</span>listaProduto<span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">	@When<span class="br0">&#40;</span><span class="st0">&quot;Eu verifico o somatório de produtos&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw1">public</span> <span class="kw4">void</span> verificaTotalProdutosSacola<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">		<span class="kw1">for</span> <span class="br0">&#40;</span> Produto produto <span class="sy0">:</span> sacola.<span class="me1">retornaProdutos</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">			somatorioProdutos <span class="sy0">=</span> produto.<span class="me1">preco</span> <span class="sy0">+</span> somatorioProdutos<span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">		<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">	@Then<span class="br0">&#40;</span><span class="st0">&quot;Devo ter somente um total de R$ $total reais em produtos&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw1">public</span> <span class="kw4">void</span> validaSacola<span class="br0">&#40;</span><span class="kw4">double</span> totalProduto<span class="br0">&#41;</span> <span class="br0">&#123;</span>		</pre></li><li class="li1"><pre class="de1">		<span class="kw1">if</span> <span class="br0">&#40;</span> somatorioProdutos <span class="sy0">&gt;</span> totalProduto <span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">			<span class="kw1">Assert</span>.<span class="me1">fail</span><span class="br0">&#40;</span><span class="st0">&quot;Total de produtos é acima de R$ 500&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1"><span class="sy0">&lt;/</span>rpe<span class="sy0">&gt;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="sy0">&lt;</span>strong<span class="sy0">&gt;</span>EmailSteps.<span class="me1">java</span><span class="sy0">&lt;/</span>strong<span class="sy0">&gt;</span></pre></li><li class="li1"><pre class="de1"><span class="sy0">&lt;</span>pre lang<span class="sy0">=</span><span class="st0">&quot;java&quot;</span> line<span class="sy0">=</span><span class="st0">&quot;1&quot;</span><span class="sy0">&gt;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">package</span> <span class="co2">scenario1.steps</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">static</span> org.<span class="me1">jbehave</span>.<span class="me1">Ensure</span>.<span class="me1">ensureThat</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.jbehave.scenario.annotations.Given</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.jbehave.scenario.annotations.Then</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">org.jbehave.scenario.annotations.When</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">scenario1.util.PtBRSteps</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">scenario1.vo.Sacola</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">com.guilhermechapiewski.fluentmail.email.EmailMessage</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1"><span class="kw1">import</span> <span class="co2">com.guilhermechapiewski.fluentmail.transport.EmailTransportConfiguration</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1"><span class="kw1">public</span> <span class="kw1">class</span> EmailSteps <span class="kw1">extends</span> PtBRSteps <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">	Sacola sacola 		<span class="sy0">=</span> <span class="kw1">new</span> Sacola<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw3">Boolean</span> statusEnvio <span class="sy0">=</span> <span class="kw2">false</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">	@Given<span class="br0">&#40;</span><span class="st0">&quot;Que minha sacola está preenchida de produtos&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw1">public</span> <span class="kw4">void</span> verificaSacola<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">		<span class="kw3">System</span>.<span class="me1">out</span>.<span class="me1">println</span><span class="br0">&#40;</span><span class="st0">&quot;Lista cheia..&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">	@When<span class="br0">&#40;</span><span class="st0">&quot;Enviar um email de confirmação&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw1">public</span> <span class="kw4">void</span> enviaEmail<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></pre></li><li class="li1"><pre class="de1">		EmailTransportConfiguration.<span class="me1">configure</span><span class="br0">&#40;</span><span class="st0">&quot;localhost&quot;</span>, <span class="kw2">false</span>, <span class="kw2">false</span>, <span class="st0">&quot;&quot;</span>, <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">		<span class="kw1">new</span> EmailMessage<span class="br0">&#40;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	    	.<span class="me1">from</span><span class="br0">&#40;</span><span class="st0">&quot;eusou@marcuscavalcanti.net&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	    	.<span class="me1">to</span><span class="br0">&#40;</span><span class="st0">&quot;eusou@marcuscavalcanti.net&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	    	.<span class="me1">withSubject</span><span class="br0">&#40;</span><span class="st0">&quot;Testando BDD&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	    	.<span class="me1">withBody</span><span class="br0">&#40;</span><span class="st0">&quot;Testando terceiro cenário e o final da estória.&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	    	.<span class="me1">send</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">		statusEnvio <span class="sy0">=</span> <span class="kw2">true</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1">&nbsp;</pre></li><li class="li1"><pre class="de1">	@Then<span class="br0">&#40;</span><span class="st0">&quot;Devo receber o status do envio <span class="es0">\&quot;</span>$retorno<span class="es0">\&quot;</span>&quot;</span><span class="br0">&#41;</span></pre></li><li class="li1"><pre class="de1">	<span class="kw1">public</span> <span class="kw4">void</span> recebeStatusEnvio<span class="br0">&#40;</span><span class="kw3">String</span> retorno<span class="br0">&#41;</span> <span class="br0">&#123;</span>	</pre></li><li class="li1"><pre class="de1">		ensureThat<span class="br0">&#40;</span>statusEnvio.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">equals</span><span class="br0">&#40;</span>retorno<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></li><li class="li1"><pre class="de1">	<span class="br0">&#125;</span></pre></li><li class="li1"><pre class="de1"><span class="br0">&#125;</span></pre></li></ol></div></div></div></div></div></div></div>


<p>Nos exemplos acima, que representam os passos de um cenário, é importante notar que os métodos seguem a ordem definida no arquivo texto, assim como todos são anotados com as palavras chaves correspondentes, no caso <em>Given</em>, <em>When</em>, <em>And</em>, <em>Then</em>. As anotações recebem como parâmetro as frases descritas no arquivo texto, excluindo apenas as palavras chaves no começo da frase, que estão devidamente representadas pelas anotações.</p>
<p>Os parâmetros são identificados com o formato <em>$variavel</em>, e uma vez que usamos esses parâmetros, devemos também colocá-los na assinatura dos métodos. Esses parâmetros são automaticamente capturados pelo JBehave através do uso de <a href="http://guia-er.sourceforge.net/" target="_blank" style="text-decoration: underline">expressões regulares</a>. </p>
<h3>Executando o exemplo</h3>
<p>Para executar o exemplo deve-se executar a classe que extende a classe <em>Scenario</em> do JBehave, nesse caso seria a classe <em>PrecoPromocaoTeste.java</em>, e para acompanhar os resultados, eu utilizo a integração do <a href="http://www.eclipse.org/" target="_blank" style="text-decoration: underline">Eclipse</a> com o <a href="http://www.junit.org/" target="_blank" style="text-decoration: underline">JUnit</a>, através de uma <em><a href="http://www.eclipse.org/articles/viewArticle/ViewArticle2.html" target="_blank" style="text-decoration: underline">view</a></em> própria da <a href="http://pt.wikipedia.org/wiki/IDE" target="_blank" style="text-decoration: underline">IDE</a>.</p>
<p>No exemplo, usei ainda algumas classes auxiliares criadas especificamente para o exemplo, mas que não irei mostrar aqui os seus códigos para não tornar o tópico extenso demais. De qualquer forma, ao final desse tópico botarei um <em>link</em> para <em>download</em> do projeto no Eclipse que contém todos os códigos.</p>
<h3>Observações finais</h3>
<p>Um dos problemas que eu notei no JBehave é em relação a parametrização de alguns valores no arquivo texto para o código Java, em alguns casos isso pode se tornar um trabalho sacal e pouco produtivo, mas acredito que com a evolução do <em>framework</em> esse problema será resolvido.</p>
<p>Algumas pessoas utilizam alternativas variadas para resolver esse problema, como  por exemplo criar o valor dos parâmetros diretamente como atributos nas classes que representam os passos. Eu particularmente não gosto dessa abordagem, pois acredito que isso faz com que os arquivos que descrevem os cenários percam seu valor e esses arquivos são essencial para utilização e sentido do BDD.</p>
<p>No exemplo citado, usei ainda algumas bibliotecas como <a href="http://code.google.com/p/fluentmailapi/" target="_blank" style="text-decoration: underline">FluentMailApi</a>, Mail e Activation da <a href="http://java.sun.com/products/javamail/" target="_blank" style="text-decoration: underline">JavaMail</a> e <a href="http://code.google.com/p/hamcrest/" target="_blank" style="text-decoration: underline">Hamcrest</a>. Essas bibliotecas servem basicamente para o envio de email e uso mais aperfeiçoado de expressões regulares por parte do JBehave.</p>
<p>Para finalizar, é importante citar que as classes do meu negócio (Sacola, Usuario, Loja, etc) foram construídas baseadas no meu requesito, no meu cenário, que foi a primeira etapa a ser elaborada na construção do exemplo.</p>
<h3>Download</h3>
<p>Para <em>download</em> do projeto completo no Eclipse, basta <a href="http://www.marcuscavalcanti.net/blog/wp-content/uploads/JBehave/JBehaveLab.rar" style="text-decoration: underline" target="_blank">clicar aqui</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuscavalcanti.net/blog/2010/01/08/bdd-com-jbehave/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Algumas observações sobre BDD</title>
		<link>http://www.marcuscavalcanti.net/blog/2010/01/07/algumas-observacoes-sobre-bdd/</link>
		<comments>http://www.marcuscavalcanti.net/blog/2010/01/07/algumas-observacoes-sobre-bdd/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 22:35:13 +0000</pubDate>
		<dc:creator>Marcus Cavalcanti</dc:creator>
				<category><![CDATA[Tecnologia, Software & Desenvolvimento]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Testes]]></category>

		<guid isPermaLink="false">http://www.marcuscavalcanti.net/blog/?p=1271</guid>
		<description><![CDATA[Ultimamente estive pesquisando sobre o assunto BDD (Behaviour-Driven Development) e também praticado com alguns exemplos reais, através disso devo dizer que consegui tirar algumas conclusões bem interessantes sobre o assunto, nas quais gostaria de expor aqui. Vamos a elas: BDD ajuda você, BDD ajuda seu cliente Um ponto que pude observar, é que usando BDD [...]]]></description>
			<content:encoded><![CDATA[<p>Ultimamente estive pesquisando sobre o assunto BDD (<a href="http://dannorth.net/introducing-bdd" target="_blank" style="text-decoration: underline">Behaviour-Driven Development</a>) e também praticado com alguns exemplos reais, através disso devo dizer que consegui tirar algumas conclusões bem interessantes sobre o assunto, nas quais gostaria de expor aqui. Vamos a elas:</p>
<h3>BDD ajuda você, BDD ajuda seu cliente</h3>
<p>Um ponto que pude observar, é que usando BDD a possibilidade de um cliente participar de um projeto é imensa, mesmo que você não use alguma metodologia ágil (falarei sobre isso a seguir). E por que ele pode participar? É simples, pois é ele quem pode escrever os testes. Se ainda assim não for o seu cliente o responsável por escrever os testes, será ele quem irá validá-los, ou seja, você pode escrever os testes e pedir para que ele aprove ou não. Isso é muito importante, pois nesse caso os testes em BDD seriam o contrato entre você o seu cliente, entre o que você está entregando e o que ele está esperando.</p>
<h3>BDD favorece o sucesso do uso de metodologias ágeis</h3>
<p>Sem dúvida nenhuma um dos pontos fortes do uso de BDD é que suas características se encaixam muito bem em equipes que fazem o uso de <a href="http://en.wikipedia.org/wiki/Agile_software_development"  target="_blank" style="text-decoration: underline">metodologia ágil</a>. E são vários pontos que favorecem.</p>
<p>Uma delas é a já citada participação do cliente, pois um dos requisitos para o sucesso do uso de metodologias ágeis é a participação e contribuição efetiva do cliente e no caso do uso de BDD ele pode participar diretamente, uma vez que é ele quem é o responsável (<a href="http://improveit.com.br/scrum/product_owner" target="_blank" style="text-decoration: underline">PO</a>) por criar as estórias (ítens do <a href="http://improveit.com.br/scrum/product_backlog"  target="_blank" style="text-decoration: underline">backlog</a>) e criar os <a href="http://en.wikipedia.org/wiki/Acceptance_testing" target="_blank" style="text-decoration: underline">testes de aceitação</a> para as mesmas, onde tudo isso é usado no BDD.</p>
<p>Os artefatos que constituem BDD são muito, mais muito semelhantes aos artefatos presentes em ágil.</p>
<p> Em BDD se usa estórias e testes de aceitação, além de BDD favorecer a construção de aplicativos de forma evolutiva (<a href="http://scrummethodology.com/scrum-sprint/" target="_blank" style="text-decoration: underline"><em>sprints</em></a>) e tudo isso casa perfeitamente com os requisitos das metodologias ágeis.</p>
<h3>Favorece a escrita de testes antes da implementação</h3>
<p>Uma boa prática na criação de testes, independente se você usa BDD ou TDD, é que os <a href="http://stackoverflow.com/questions/319513/when-not-to-write-tests-before-implementation" target="_blank" style="text-decoration: underline">testes sejam criados antes de tudo</a>. Ok, eu concordo, mas devo dizer que com TDD isso não é muito nítido, pois na maioria dos casos, principalmente no começo, as pessoas tendem a implementar os códigos e depois escreverem os testes para validá-los. Já com BDD, a primeira coisa que você precisa ter em mãos antes de implementar os testes são as estórias e os cenários, não tem como fugir disso, o que torna muito mais nítido que em primeiro lugar vem os testes  e depois as implementações.</p>
<h3>Torna mais nítido o que sua aplicação deve fazer</h3>
<p>Com BDD é muito mais fácil isolar as funcionalidade da sua aplicação, já que o que é testado é exatamente isso, dessa forma fica fácil identificar os componentes que envolvem determinada funcionalidade, torna mais nítido qual é o papel daquela funcionalidade, além do que consegue dar um sentido melhor para a sua aplicação de maneira geral.</p>
<p>Com BDD, você consegue ainda uma visão de <em><a href="http://en.wikipedia.org/wiki/Workflow" target="_blank" style="text-decoration: underline">workflow</a></em> da sua aplicação, ou seja, uma visão macro, o que favorece dar manutenção a mesma. Percebo também, que BDD favorece um bom design de código, evitando assim problemas de desenvolvimento como códigos com <a href="http://jcspl.net/2007/12/17/acoplamento-e-coesao/" target="_blank" style="text-decoration: underline">alto-acoplamento</a>.</p>
<h3>Torna os testes mais humanos</h3>
<p>A essência do BDD são os cenários e não parte isoladas da aplicação e essa maneira de lidar com testes favorece o entendimento por parte de nós, humanos.</p>
<p>Testes de interface com o <a href="http://seleniumhq.org/" target="_blank" style="text-decoration: underline">Selenium</a>,  tornam-se mais compreensíveis num contexto que envolva BDD, como em um teste de login, por exemplo.</p>
<h3>Conclusão</h3>
<p>Na minha opinião, está mais do que clara a vantagem no uso de BDD, entretanto ele não substitui o uso de TDD, pois a abordagem de ambas são diferentes e complementares.</p>
<p>No próximo tópico, irei mostrar um cenário de testes com o <em>framework</em> <a href="http://jbehave.org/reference/latest/index.html" target="_blank" style="text-decoration: underline">JBehave</a>, um <em>framework</em> BDD para Java.</p>
<h3>Mais sobre o assunto</h3>
<p><a href="http://blog.objectmentor.com/articles/2008/11/27/the-truth-about-bdd" target="_blank" style="text-decoration: underline">The truth about DDD</a></p>
<p><a href="http://inter-sections.net/2007/10/03/the-difference-between-tdd-and-bdd" target="_blank" style="text-decoration: underline">The difference between TDD and BDD</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuscavalcanti.net/blog/2010/01/07/algumas-observacoes-sobre-bdd/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Ponto para o Rails!</title>
		<link>http://www.marcuscavalcanti.net/blog/2009/03/17/ponto-para-o-rails/</link>
		<comments>http://www.marcuscavalcanti.net/blog/2009/03/17/ponto-para-o-rails/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 03:34:08 +0000</pubDate>
		<dc:creator>Marcus Cavalcanti</dc:creator>
				<category><![CDATA[Tecnologia, Software & Desenvolvimento]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[RoR]]></category>

		<guid isPermaLink="false">http://www.marcuscavalcanti.net/blog/?p=671</guid>
		<description><![CDATA[É muito curioso ver todo o frenesi e o burburinho que o Rails (RoR) vem causando entre os desenvolvedores mundo a fora, pelo menos aos que estão próximos a mim isso é nítido, as pessoas ficam maravilhadas, quase em êxtase! Acho isso fantástico, pois de certa forma o RoR tem feito com que uma série [...]]]></description>
			<content:encoded><![CDATA[<p>É muito curioso ver todo o frenesi e o burburinho que o <a href="http://rubyonrails.org/" target="_blank" style="text-decoration: underline">Rails (RoR)</a> vem causando entre os desenvolvedores mundo a fora, pelo menos aos que estão próximos a mim isso é nítido, as pessoas ficam maravilhadas, quase em êxtase! Acho isso fantástico, pois de certa forma o RoR tem feito com que uma série de preconceitos sejam quebrados e esquecidos. E qual o principal motivo para tudo isso? A simplicidade e a praticidade.</p>
<p>Linguagens de programação tendem a ser parecidas com religião ou com times de futebol, a pessoa simplesmente escolhe uma e defende aquilo com todas as forças, geralmente de forma cega. Eu particularmente acredito que, para defender ou criticar algo, se faz por necessário conhecer profundamente aquilo que você defende ou critica, pois só assim você terá argumentos para apontar falhas ou reconhecer méritos. Sou, ainda, a favor da filosofia &#8220;cabeça aberta&#8221;, que em poucas palavras quer dizer: não tenha medo, muito menos preconceito, de conhecer algo novo, conheça para a partir disso você ter uma opinião formada se aquilo te agrada, ou não.</p>
<p>É comum acontecer em fóruns e em listas de discussão debates sobre <a href="http://www.google.com.br/search?hl=pt-BR&#038;client=firefox-a&#038;rls=com.ubuntu%3Aen-US%3Aunofficial&#038;hs=dBQ&#038;q=qual+linguagem+de+programa%C3%A7%C3%A3o+%C3%A9+melhor&#038;btnG=Pesquisar&#038;meta=" target="_blank" style="text-decoration: underline">&#8220;qual linguagem é melhor&#8221;</a>, na maioria das vezes as pessoas atacam uma linguagem, ou defendem outra, simplesmente baseadas em sua opinião pessoal, ou melhor, baseados na falta de conhecimento. As pessoas não conseguem enxergar que todas têm seus prós e contras, como tudo na vida, e que a partir de uma situação real que é possível avaliar a melhor opção.</p>
<p>Eu comecei a programar através do PHP e hoje em dia trabalho basicamente só com Java. Programadores Java tendem a achar PHP um lixo, na maioria das vezes com embasamentos e teorias totalmente furadas, que demonstram tremenda falta de conhecimento. Eu concordo que o PHP tem uma má fama devido a linguagem ter demorado a amadurecer, como também concordo que o nível dos programadores em PHP no geral é baixo, é duro admitir, mas no geral é assim, provavelmente pela facilidade que a linguagem proporciona e também por sua curva de aprendizado ser bem mais baixa que a do Java, por exemplo. Mas isso quer dizer que o PHP é ruim? Eu poderia enumerar uma série de vantagens que o PHP tem em relação ao Java, da mesma forma que o Java tem uma série de outras vantagens em relação ao PHP, mas esse não é o foco do tópico, o foco é justamente o contrário.</p>
<h3>Uma &#8220;nova&#8221; era</h3>
<p>E para acabar, ou pelo menos ajudar bastante, surge o famoso <em>framework</em> Ruby on Rails, o <em>hype</em> do momento tratando-se de linguagem de programação! Ruby on Rails é um <em>framework</em> de desenvolvimento web que prega o conceito de que algo deve ser simples, prático e prazeroso de fazer, dessa forma inúmeros benefícios são alcançados, como: códigos com mais qualidade, tempo de desenvolvimento mais curto e comunidade participativa. Ruby on Rails não é uma <a href="http://pt.wikipedia.org/wiki/Linguagem_de_programa%C3%A7%C3%A3o"  target="_blank" style="text-decoration: underline">linguagem de programação</a>, é um <a href="http://pt.wikipedia.org/wiki/Framework" target="_blank" style="text-decoration: underline"><em>framework</em></a>, que foi desenvolvido em cima da linguagem <a href="http://www.ruby-lang.org/pt/"  target="_blank" style="text-decoration: underline">Ruby</a>, que é uma linguagem de programação criada por um <a href="http://pt.wikipedia.org/wiki/Yukihiro_Matsumoto" target="_blank" style="text-decoration: underline">japonês</a> em 1995 baseada nos pontos fortes de várias linguagens da época. Reparou no trecho <strong>&#8220;&#8230;que havia de melhor em outras linguagens&#8230;&#8221;?</strong> Ou seja, o próprio criador da linguagem era (ou é) totalmente desprovido de preconceitos, e com isso conseguiu identificar os pontos fortes e fracos de várias linguagens com o intuito de criar uma, que no seu modo de ver, seria mais eficiente.</p>
<h3>Complexidade não é sinal de qualidade</h3>
<p>Uma linguagem de programação, um <em>framework</em> ou uma <a href="http://pt.wikipedia.org/wiki/API"  target="_blank" style="text-decoration: underline">API</a>, tem como principal objetivo (pelo menos deveria) fornecer uma maior praticidade aos desenvolvedores em solucionar problemas. Essa deveria ser a premissa básica para que uma determinada linguagem ou plataforma fosse adotada em um projeto, entretanto nada impede que N linguagens ou plataformas trabalhem de forma conjunta, desde que proporcionem alternativas para descomplicar o problema.</p>
<p>Só para esclarecer: simplicidade, praticidade, produtividade e facilidade nesse caso são sinônimos!</p>
<p>Outro ponto a ser observado é que a <a href="http://pt.wikipedia.org/wiki/Engenharia_de_software"  target="_blank" style="text-decoration: underline">engenharia de software</a> é um assunto relativamente novo, principalmente se formos comparar as outras engenharias, como a civil, e por isso é tão comum observarmos novas metodologias, padrões e linguagens surgindo a todo momento. Mas o que elas tem em comum é que todas tem como objetivo resolver os problemas da maneira &#8220;menos complexa&#8221; que for possível, é claro que outros fatores são levados em consideração, entretanto se paramos para pensar a simplicidade é sempre a prioridade.</p>
<p>E é por isso que o RoR está na crista da onda, pois talvez nenhum <em>framework</em> descomplique tanto as coisas como ele, e o melhor é que isso é contagioso, pois a todo momento surgem mais e mais <em>frameworks</em> &#8220;<a href="http://mail-archives.apache.org/mod_mbox/struts-dev/200509.mbox/%3C43186873.7080309@twdata.org%3E"   target="_blank" style="text-decoration: underline">RoR <em>like</em></a>&#8220;, em PHP existe uma penca deles, como: Akelos, Code Igniter, Cake, Kohana. Até o sempre conservador Java se rendeu ao RoR e lançou o <a href="http://groovy.codehaus.org/"   target="_blank" style="text-decoration: underline">Groovy</a> (<a href="http://jcp.org/en/jsr/detail?id=241"   target="_blank" style="text-decoration: underline">JSR 241</a>) e consequentemente o <a href="http://www.grails.org/""   target="_blank" style="text-decoration: underline">Grails</a>, que é um <em>framework</em> web baseado em quem? No Rails!</p>
<h3>Maçãs são maçãs e bananas são bananas!</h3>
<p>O título acima parece estranho, mas ele serve para deixar claro o seguinte: comparar linguagens não é algo inteligente, ao invés disso, procure conhecê-las e tirar proveito do melhor de cada uma. PHP é PHP, Java é Java, Python é Python! Assim como maçãs são maçãs e bananas são bananas, portanto não cabem comparações. Parece óbvio, e na verdade é, mas mesmo assim existem pessoas que ainda insistem em levar essa discussão adiante, onde dificilmente é tirado algum proveito.</p>
<p>Só para deixar claro, eu nunca desenvolvi uma aplicação sequer usando o RoR, já usei alguns <em>frameworks</em> &#8220;RoR <em>like</em>&#8221; e tive ótimas experiências, entretanto não acho que o RoR substitui o Java, o PHP, ou até mesmo o .NET, como eu já disse, cada um tem o seu propósito e por isso deve haver um equilíbrio na tomada de decisões sobre &#8220;o que escolher?&#8221;, fatores como: experiência com determinada linguagem, documentação, maturidade, infra-estrutura, segurança não podem ser esquecidos de forma alguma, pois no final é a sinergia entre vários fatores que determina as opções a serem escolhidas.</p>
<p>É normal, e de certa forma até compreensível, nos deixarmos levar pela emoção de conhecer um novo mundo e com isso embarcamos no erro de que a partir daquele momento tudo será feito &#8220;daquela forma&#8221;, com &#8220;aquela nova linguagem&#8221;, e isso é um erro, dos graves! Nesse ponto, a experiência, o conhecimento e o equilíbrio fazem toda a diferença na tomada de decisão mais acertada.</p>
<p>Só para finalizar, gostaria de ressaltar que nada impede que existam linguagens e <em>frameworks</em> ruins, é claro que eles existem, mas mais uma vez, para termos essa certeza é preciso conhecer. Da mesma forma que, não é só porque devemos abrir a nossa cabeça e olharmos para os lados, ao invés de olharmos só para frente, que devemos deixar de considerar nossas preferências e aquilo com que temos mais facilidade. Preferência e preconceito não são sinônimos.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuscavalcanti.net/blog/2009/03/17/ponto-para-o-rails/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>O paradoxo de(a) TI</title>
		<link>http://www.marcuscavalcanti.net/blog/2009/02/25/o-paradoxo-de-ti/</link>
		<comments>http://www.marcuscavalcanti.net/blog/2009/02/25/o-paradoxo-de-ti/#comments</comments>
		<pubDate>Wed, 25 Feb 2009 18:30:35 +0000</pubDate>
		<dc:creator>Marcus Cavalcanti</dc:creator>
				<category><![CDATA[Tecnologia, Software & Desenvolvimento]]></category>
		<category><![CDATA[BPM]]></category>
		<category><![CDATA[mercado ti]]></category>
		<category><![CDATA[Ondas de TI]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[TI]]></category>

		<guid isPermaLink="false">http://www.marcuscavalcanti.net/blog/?p=399</guid>
		<description><![CDATA[Semana passada rolou uma apresentação sobre TDD muito interessante na empresa que eu trabalho, onde foram apresentados desde os conceitos básicos de TDD, até os tipos de testes existentes e finalizando com uma aplicação exemplo. No final rolou uma rodada de perguntas, onde foram questionados assuntos como BDD, programação defensiva, contract by domain, dentre outras [...]]]></description>
			<content:encoded><![CDATA[<p>Semana passada rolou uma apresentação sobre <a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank" style="text-decoration: underline">TDD</a> muito interessante na empresa que eu trabalho, onde foram apresentados desde os conceitos básicos de TDD, até os tipos de testes existentes e finalizando com uma aplicação exemplo.</p>
<p>No final rolou uma rodada de perguntas, onde foram questionados assuntos como <a href="http://behaviour-driven.org/" target="_blank" style="text-decoration: underline">BDD</a>, <a href="http://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_defensiva" target="_blank" style="text-decoration: underline">programação defensiva</a>, contract by domain, dentre outras metodologias e padrões. Nesse ponto da apresentação, a maioria das pessoas que estavam presentes ficaram meio perdidas com as milhares de <a href="http://en.wikipedia.org/wiki/Buzzword"  target="_blank" style="text-decoration: underline"><em>buzzwords</em></a> associadas com as perguntas que foram feitas. O pessoal mais antigo ficou mais perdido ainda e até brincaram sobre a questão do &#8220;estamos ficando velho&#8221;.</p>
<p>Paralelamente a isso, começei a ler essa semana um livro do <a href="http://www.trcr.com.br" target="_blank" style="text-decoration: underline">Tadeu Cruz</a> sobre <a href="http://www.trcr.com.br/index.php/biblioteca/" target="_blank" style="text-decoration: underline">BPM e BPMS</a>, onde no primeiro capítulo ele fala sobre a questão da desorganização informacional, muitas vezes causadas pelo excesso de informação e as novas ondas de TI que surgem a todo momento. Outra coisa que o autor do livro cita e crítica é que existem muitos casos de determinadas organizações, que forçam o uso de determinado software sem obter o real benenfício que esse software deveria oferecer, na maioria dos casos, por questões comerciais ou de interesse próprio dessas organizações. Questões como: para que determinada tecnologia foi criada, como deveria ser corretamente usada, como efetivamente está sendo usada, quais deveriam ser os resultados esperados do seu uso e quais são os resultados que estão sendo obtidos com sua utilização, orientariam de forma efetiva o profissional ou a organização com o intuito de medir se a adoção de determinada tecnologia está realmente sendo benéfica. Esse tipo de situação tem ocorrido muito com BPM, que é o novo <a href="http://en.wikipedia.org/wiki/Hype_cycle" target="_blank" style="text-decoration: underline"><em>hype</em></a> do momento tratando-se de TI.</p>
<p>O que as duas histórias tem em comum e onde estou querendo chegar?</p>
<p>O que eu quero dizer é o seguinte: até onde vale apena conhecer N conceitos diferentes e até onde não vale a pena? Nos casos citados acima tem um pouco das duas coisas, bem como suas respostas. No caso específico do TDD, deveríamos considerar que o melhor a ser feito seria debater sobre as <em>buzzwords</em> que o assunto levantou, ou o melhor seria não conhecer muitos desses novos padrões e metodologias? Eu fico com a primeira opção, mas a segunda opção pode contradizer a primeira. Explico logo abaixo.</p>
<p>Vale a pena usar TDD e BDD em um projeto sem conhecer seus benefícios, o resultado a ser esperado e os possíveis obstáculos a serem vencidos? Não. Pois nesse caso tudo de positivo que TDD traria sendo usada da forma correta, traria inversamente em dobro no caso do seu mal uso, pois nesse caso o projeto acabaria tendo novos percalços (além dos já conhecidos), como: prazos atrasados, código mal estruturado, equipe perdida e etc. E isso acontece em larga escala em TI, não apenas no caso específico do TDD, já que o mais se vê são empresas gastando milhões em &#8220;soluções&#8221; de TI (CRM, ERP, BI, etc) &#8211; muitas vezes empurradas pelos ótimos vendedores dos grandes players do mercado &#8211; sem obter benefício algum sobre aquilo (ou até mesmo desconhecendo o porquê do seu uso). Na verdade muito pelo contrário, pois como muito desses processos são feitos sem estruturação alguma e demoram meses, anos&#8230; no final das contas a dor de cabeça e o custo envolvido não atingem nem de perto o <a href="http://www.artigonal.com/gestao-artigos/a-famosa-relacao-custo-x-beneficio-602803.html" target="_blank" style="text-decoration: underline">custo x benefício</a> esperado sobre aquele investimento.</p>
<p>Outro fênomeno interessante a ser observado e que de certa maneira ligam as duas histórias é a infobia. Infobia é uma palavra que o Tadeu Cruz usa para definir o medo por informação, ou seja, em determinado momento, com a enxurrada de tantas <em>buzzwords</em>, as pessoas acabam ficando reativas em absorver novas tecnologias e entender o seu significado,  com isso de certa forma ficam estagnadas, pois deixam de absorver novos conhecimentos. Mas em compensação não adianta em nada conhecer várias palavrinhas mágicas superficialmente só para dizer que &#8220;domina&#8221; aquela tecnologia do momento. Por isso, acredito que dependendo do contexto, é válido ou não conhecer uma nova tecnologia. Esta aí mais um caso do <strong>paradoxo de TI</strong>. De certa forma, mas sem generalizar, a infobia consegue explicar a frase &#8220;estamos ficando velho&#8221;.</p>
<p>Devemos considerar que TI não irá salvar o mundo, TI pode ajudar de forma efetiva qualquer negócio de qualquer natureza, desde que seja aplicada da forma correta, e aplicar de forma correta envolve antes de mais nada: estruturação, disciplina, educação, mudança e planejamento. Ao mesmo tempo que sabemos de diversos casos onde TI trouxe um real benefício as organizações, sabemos de tantos outros onde TI acabou com negócios, projetos e sonhos. A <a href="http://www1.folha.uol.com.br/folha/informatica/ult124u19223.shtml" target="_blank" style="text-decoration: underline">bolha da internet</a> talvez seja o melhor exemplo que ilustra essa situação das ondas de TI.</p>
<p>Muitas vezes as ondas de TI trazem a tona novas tecnologias que surgem apenas com o objetivo de remediar uma tecnologia já existente. O que as vezes é considerado como inovação, nada mais é que uma evolução de algo que tenha tido insucesso no passado, dessa forma uma tecnologia X surge apenas com o intuito de servir como &#8220;curativo&#8221; da tecnologia Y, que prometeu maravilhas e na verdade devido ao seu mal uso (ou não) só trouxe dores de cabeça.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcuscavalcanti.net/blog/2009/02/25/o-paradoxo-de-ti/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

