<?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>Rafael Dohms &#187; tdd</title>
	<atom:link href="http://www.rafaeldohms.com.br/tag/tdd/pt/feed/pt/" rel="self" type="application/rss+xml" />
	<link>http://www.rafaeldohms.com.br</link>
	<description>Web Engineer</description>
	<lastBuildDate>Sat, 06 Feb 2010 20:15:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>pt</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Escrevendo testes com PHPT e contribuindo com o PHP</title>
		<link>http://www.rafaeldohms.com.br/2009/08/19/escrevendo-testes-com-phpt/pt/</link>
		<comments>http://www.rafaeldohms.com.br/2009/08/19/escrevendo-testes-com-phpt/pt/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 14:22:04 +0000</pubDate>
		<dc:creator>Rafael Dohms</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpt]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testfest]]></category>

		<guid isPermaLink="false">http://www.rafaeldohms.com.br/?p=513</guid>
		<description><![CDATA[Este ano esteve em destaque a PHPTestFest09, sendo realizada em vários cantos do mundo e destacando-se a participação do PHPSP que contribuiu com o maior número de testes. Ficou de fora? Então já comece a se preparar para ano que vem.
O PHPT é um framework extremamente simples de testes criado e usado internamente pelos desenvolvedores [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><div id=HOTWordsTxt name=HOTWordsTxt><p>Este ano esteve em destaque a PHPTestFest09, sendo realizada em vários cantos do mundo e destacando-se a <a href="http://phpsp.org.br/2009/07/06/resultado-phptestfest/">participação do PHPSP</a> que contribuiu com o maior número de testes. Ficou de fora? Então já comece a se preparar para ano que vem.</p>
<p>O PHPT é um framework extremamente simples de testes criado e usado internamente pelos desenvolvedores do core. Ele é extremamente atômico e centrado em testes como os que esperamos do PHP, como testar funções e bugs específicos.</p>
<p><strong>O que preciso saber?</strong></p>
<p>A grande vantagem do PHPT é que para poder escrever um teste, tudo que você precisa saber é: como escrever código PHP. Claro que um pouco de conhecimento interno do funcionamento do PHP vai te ajudar a procurar detalhes para testar, mas sabendo escrever PHP você já pode contribuir com uma grande percentagem dos testes que precisamos.</p>
<p>Vamos então atacar por partes:</p>
<ol>
<li>Preparando o ambiente</li>
<li>Escolhendo um teste</li>
<li>Escrevendo um teste</li>
<li>Rodando um teste</li>
<li>Enviando seu teste para o PHP</li>
</ol>
<h2><strong>1. Preparando o Ambiente</strong></h2>
<p>A preparação do ambiente não é nada complicada e exemplos estão disponíveis para referencia. A primeira coisa que você precisa é da versão do PHP que vai precisar para rodar testes. No caso do TestFest focamos no PHP 5.3, no momento recomendo pegar as últimas disponíveis na página do PHP QA (<a href="http://qa.php.net/">qa.php.net</a>) vá lá e baixe o pacote (source ou binary para windows).</p>
<p>Em ambientes Linux/Mac Os X, você irá passar pelo processo de compilar o PHP, passando pelos processos normais de <em>&#8220;./configure&#8221;</em>, <em>&#8220;make&#8221;</em> mas antes de rodar o <em>&#8220;make install&#8221;</em>, você poderá rodar o comando <em>&#8220;make tests&#8221;</em>. Este comando irá rodar todos os testes do PHP (em torno de 900+), pode demorar, mas é um ótimo procedimento, pois ao final você poderá mandar um relatório para a equipe de QA e &#8220;fazer sua parte&#8221;. Rode também o comando <em>make install</em> pois durante a confecção de um teste será interessante você poder testar ele com a versão correta do PHP.</p>
<p>Mais pra frente vamos ver como usar o <em>make tests</em> para rodar os seus novos testes.</p>
<h2><strong>2. Escolhendo um teste</strong></h2>
<p>Antes de escrever um teste é necessário escolher o objeto de nosso teste. Para tal é preciso identificar um ponto do PHP que necessita de um teste, isto pode vir de duas fontes, um bug ou uma linha de código não &#8220;coberta&#8221; (code coverage). Para descobrir bugs com/sem testes a melhor forma é olhando a pasta de testes da extensão do bug (GD -&gt; /ext/gd/tests) ou conversando com o pessoal na lista do QA.</p>
<p>Para testes específicos de linhas de código sua melhor aposta é o site <a href="http://gcov.php.net">http://gcov.php.net</a> onde você deve navegar até a versão correta que esta testando e então escolher uma área sem cobertura. No caso da testfest deste ano, o PHPSP focou na GD pois sua cobertura estava bem baixa então navegamos até o gcov do gd.c para ver onde poderiamos atuar. Para fazer esta parte do processo um conhecimento básico de C e de como o PHP funciona por baixo dos panos é muito bom, mas após alguns testes você aprende a identificar os pontos e durante o testfest o Guilherme Blanco e o Erick nos ajudaram a entender o código.</p>
<p>Para exemplificar melhor vamos ver como identificar estas linhas e o que elas fazem. Veja por exemplo a linha abaixo:</p>
<p><a href="http://www.rafaeldohms.com.br/wp-content/uploads/Picture-1.png"><img class="aligncenter size-full wp-image-568" title="PHPT-Gcov" src="http://www.rafaeldohms.com.br/wp-content/uploads/Picture-1.png" alt="PHPT-Gcov" width="948" height="218" /></a></p>
<p>O que queremos é que todas as linhas fiquem azuis (executadas) ou brancas (código não executável), as linhas não testadas estão marcadas de vermelho. Identificando a linha 1856 como não executada devemos interpretar que como há um if logo antes, a condição &#8220;== FAILURE&#8221; nunca é atingida, ou seja, esta linha nunca é executada pois a função <em>zend_parse_parameters</em> não retorna falso em nenhuma das chamadas a função <em>imagecolorallocatealpha</em> identificada logo ali encima na linha 1848.</p>
<p>Mas e ae? Ok, a função <em>zend_parse_parameters</em> é responsável por validar os parâmetros da função, ou seja, para testar esta função precisamos escrever alguns testes que passem parâmetros inválidos para a função e verifique se ela alerta o erro corretamente. Agora podemos passar para o passo de escrever este teste.</p>
<h2><strong>3. Escrevendo um teste</strong></h2>
<p>Escrever um teste é incrivelmente simples, e como testes devem ser objetivos e pontuais isso é bem claro. Você deve limitar o escopo de seu teste, procurando testar apenas uma função ou aspecto. Isso irá facilitar a nomeclatura de seu teste.</p>
<h3><strong>3.1 Nomeclatura de arquivos</strong></h3>
<p>A nomeclatura é bem simples:</p>
<ul>
<li>Teste para bug: bug&lt;bugid&gt;.phpt</li>
<li>Funcionamento básico da função: &lt;função&gt;_basic.phpt</li>
<li>Erros da função: &lt;função&gt;_error.phpt</li>
<li>Variação do funcionamento da função: &lt;função&gt;_variation.phpt</li>
<li>Extensões: &lt;extensão&gt;_&lt;#&gt;.phpt</li>
</ul>
<h3><strong>3.2 Estrutura de um .phpt</strong></h3>
<p>Arquivos de teste seguem uma estrutura bem simples:</p>
<blockquote>
<pre>--TEST--
strtr() function - basic test for strstr()
--FILE--
/* Do not change this test it is a README.TESTING example. */
$trans = array("hello"=&gt;"hi", "hi"=&gt;"hello", "a"=&gt;"A", "world"=&gt;"planet");
var_dump(strtr("# hi all, I said hello world! #", $trans));
?&gt;
--EXPECT--
string(32) "# hello All, I sAid hi planet! #"</pre>
</blockquote>
<p>Como vemos, a sessão TEST é um título de uma linha do teste descrito no arquivo. A sessão FILE é usada como o corpo de um arquivo .php que será gerado para o teste, e a sessão EXPECT demonstra o resultado que esperamos da execução da função. Recomenda-se o uso de var_dump para gerar saídas.</p>
<p>Estas são sessões padrões, mas a documentação completa pode ser vista aqui: <a href="http://qa.php.net/phpt_details.php">phpt format</a></p>
<p>Você poderá ver situações onde os blocos acima não são o bastante, mas em geral você estará checando para ver se executando a função X irá retornar a saída esperada. Porem um bloco é interessante ser mencionado aqui, o bloco CREDIT. Caso você não tenha acesso ao CVS, colocando seu nome nesse bloco irá levar seu nome aos créditos do PHP, no caso do TestFest utilizamos este formato:</p>
<blockquote>
<pre>--CREDIT--
Rafael Dohms &lt;myemail@gmail.com&gt; #PHPSPTestFest 2009-04-DD</pre>
</blockquote>
<p>Ok. Vamos tentar escrever um teste agora para ver se entendemos tudo até agora. Usando o exemplo acima onde identificamos uma linha não coberta por testes, vamos escrever um teste para testar o primeiro parâmetro da função. Observe a linha abaixo:</p>
<blockquote>
<pre><span>zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, <strong>"rllll"</strong>, &amp;IM, &amp;red, &amp;green, &amp;blue, &amp;alpha)</span></pre>
</blockquote>
<p>O que devemos entender aqui é o trecho que diz <em>&#8220;rllll&#8221;</em> pois ele identifica o tipo que cada parâmetro deve ter, neste caso o primeiro parâmetro deve ser um &#8220;Resource&#8221; por isso o &#8220;r&#8221;, e os outros devem ser do tipo &#8220;long&#8221;. Pare um momento agora e verifique o manual do PHP para esta função</p>
<blockquote>
<pre>int imagecolorallocatealpha ( resource $image , int $red , int $green , int $blue , int $alpha )</pre>
</blockquote>
<p>Ele confirma exatamente o que vemos no código, mas você poderia também achar uma situação onde o manual esta incorreto, mais um ponto onde você poderia contribuir com o PHP.</p>
<p>Voltando ao nosso exemplo, vamos então escrever um teste para testar a validação do primeiro parâmetro da função. Verificando a pasta <em>/ext/gd/tests</em> vemos que não há testes desta função, mas especificamente não há um teste chamado <em>imagecolorallocatealpha_error1.phpt</em>, então como vamos testar justamente isto, podemos usar esse nome. (podemos usar _error2&#8230; para os outros parametros por exemplo)</p>
<blockquote>
<pre>--TEST--
Testing imagecolorallocatealpha(): Wrong types for parameter 1
--CREDITS--
Rafael Dohms &lt;rdohms [at] gmail [dot] com&gt;</pre>
</blockquote>
<p>Primeiramente vamos definir o título, deixando claro que estamos testando o parâmetro 1 da função e adicionar nosso crédito, que também é importante se houver algum erro no teste ou adaptação e precisarem saber quem foi o autor original do mesmo.</p>
<blockquote>
<pre>--SKIPIF--
&lt;?php
if (!extension_loaded("gd")) die("skip GD not present");
?&gt;</pre>
</blockquote>
<p>O bloco &#8211;SKIPIF&#8211; é muito importante neste caso. Como estamos testando uma função da GD, que é uma extensão do PHP, ela não estará sempre ativada, portanto só devemos executar os testes caso a extensão esteja ativa. O bloco SKIPIF é exatamente para isso, faça as verificações necessárias, caso não deva rodar, execute um die. O processo que executa os testes interpreta isso como SKIP e não FAIL. Isto vale para outras condições também, como arquivos necessários e qualquer outro fator que possa determinar se um teste deve ou não ser &#8220;pulado&#8221;.</p>
<blockquote>
<pre>--FILE--
&lt;?php
$resource = tmpfile();</pre>
<pre>imagecolorallocatealpha($resource, 255, 255, 255, 50);
imagecolorallocatealpha('string', 255, 255, 255, 50);
imagecolorallocatealpha(array(), 255, 255, 255, 50);
imagecolorallocatealpha(null, 255, 255, 255, 50);
?&gt;</pre>
</blockquote>
<p>Este é o corpo do teste, a parte mais importante. Basicamente estamos executando a chamada à função com diversos parâmetros inválidos, como strings, arrays e um resource que não é uma imagem. Passando um resource que não é imagem estamos na verdade testando a linha 1859, mas é uma condição importante de se testar também. O restante dos parâmetros recebem valores válidos.</p>
<blockquote>
<pre>--EXPECTF--
Warning: imagecolorallocatealpha(): supplied resource is not a valid Image resource in %s on line %d</pre>
<pre>Warning: imagecolorallocatealpha() expects parameter 1 to be resource, %s given in %s on line %d</pre>
<pre>Warning: imagecolorallocatealpha() expects parameter 1 to be resource, array given in %s on line %d</pre>
<pre>Warning: imagecolorallocatealpha() expects parameter 1 to be resource, null given in %s on line %d</pre>
</blockquote>
<p>Finalmente vamos testar o resultado. Aqui no caso utilizamos o EXPECTF que funciona como um printf, poderíamos ter usado outros disponíveis com expressões regulares por exemplo, mas o funcionamento deste é bem mais simples. Aqui basicamente estamos conferindo se o texto de erro bate com o que esperamos e como usamos um formato de printf $s e %d substituem textos que são dinâmicos, como o nome do arquivo que varia em cada máquina.</p>
<p><em><strong>Dica: </strong>Para obter as mensagens de erro, rode o arquivos usando o PHP, ex: php imagecolorallocatealpha_error1.phpt. O arquivo será executado, todo conteudo dele será echoado na tela, mas dentro do bloco &#8211;FILE&#8211; o conteudo que aparecer é o resultado da execução.</em></p>
<p><em><br />
</em></p>
<h2><strong>4. Rodando um teste e fazendo faxina</strong></h2>
<p>Agora você tem um arquivo phpt pronto e precisamos ver se este teste esta mesmo passando. Para isso precisamos chamar o executor de testes e passar o nosso teste, caso contrário ele irá executar todos os 900+ testes. Para fazer isso o processo é simples, execute o comando <em>make test</em> da mesma forma de antes, mas definindo o parâmetro <em>TESTS</em>, assim:</p>
<blockquote>
<pre>make test TESTS=ext/gd/tests/imagecolorallocatealpha_*.phpt</pre>
</blockquote>
<p>Você pode dar o caminho completo para o arquivo, ou usar um <em>wildcard</em> como assim, isso é útil se você acabou de escrever os testes para todos parâmetros e quer rodar todos testes daquela função.</p>
<p>Veja o resultado:</p>
<p><a href="http://www.rafaeldohms.com.br/wp-content/uploads/Picture-2.png"><img class="aligncenter size-full wp-image-570" title="Test Results" src="http://www.rafaeldohms.com.br/wp-content/uploads/Picture-2.png" alt="Test Results" width="896" height="426" /></a></p>
<p>Note que o teste passou, como indica o <em>PASS</em> logo em frente ao que escrevemos no bloco &#8211;TEST&#8211;.  É interessante também comentar o que acontece quando um teste falha, além de ser marcado com um <em>FAIL</em> o sistema gera um numero de arquivos com o mesmo nome e diferentes extensões:</p>
<ul>
<li>.out &#8211; output do arquivo php criado po teste</li>
<li>.php &#8211; o código gerado para o teste (bloco &#8211;FILE&#8211;)</li>
<li>.diff &#8211; uma comparacao do que foi o output e do que se esperava</li>
<li>.exp &#8211; o texto em &#8211;EXPECTEDF&#8211; isaolado</li>
<li>.log &#8211; um resumo do processo</li>
</ul>
<p>Estes arquivos são muito uteis para que se analise o resultado e poque da falha.</p>
<h2><strong>5. Enviado seu teste para o PHP</strong></h2>
<p>Você possui algumas formas de fazer seu teste chegar no PHP. A primeira é participando do PHPTestFest anual, onde todos os testes são enviados para um repositório separado e então integrados ao SVN oficial. A segunda forma é você enviar este teste que escreveu para a lista do QA Team e alguem irá colocar ele no SVN por você. A terceira forma é uma junção de ambas, muitas pessoas apos a testfest são presenteadas com contas do SVN e karma para poderem comitar seus próprios testes, como ocorreu comigo (viu, não é mentira!)</p>
<h2><strong>Conclusão</strong></h2>
<p>Pronto, agora você tem todas as ferramentas para começar a escreve testes para o PHP. O PHPT é excelente para sua função em testes do PHP, mas testes não param por ai, procure incluir os testes em seus sistemas e bibliotecas, mas para isso procure o PHPUnit e aprende sobre Test Driven Development (TDD). Em breve falarei destes por aqui também.</p>
</div><div id="st_tags"><a href="http://www.rafaeldohms.com.br/tag/php/pt/" rel="tag">PHP</a>, <a href="http://www.rafaeldohms.com.br/tag/phpt/pt/" rel="tag">phpt</a>, <a href="http://www.rafaeldohms.com.br/tag/tdd/pt/" rel="tag">tdd</a>, <a href="http://www.rafaeldohms.com.br/tag/testfest/pt/" rel="tag">testfest</a><br /></div><!-- google_ad_section_end -->	<p></p>
	<hr noshade style="margin:0;height:1px" />
	<p>&copy; Rafael Dohms for <a href="http://www.rafaeldohms.com.br">Rafael Dohms</a>, 2009. |
	  <a href="http://www.rafaeldohms.com.br/2009/08/19/escrevendo-testes-com-phpt/pt/">Permalink</a> |
	  <a href="http://www.rafaeldohms.com.br/2009/08/19/escrevendo-testes-com-phpt/pt/#comments">6 comments</a><br>
	  Want more on these topics ? Browse the archive of posts filed under <a href="http://www.rafaeldohms.com.br/category/php/pt/" title="View all posts in PHP" rel="category tag">PHP</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.rafaeldohms.com.br/2009/08/19/escrevendo-testes-com-phpt/pt/feed/pt/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
