<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Desenvolvimento &#193;gil - Blog da Improve It: Tag Testes</title>
    <link>http://blog.improveit.com.br/articles/tag/testes</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Como Testar parte 2 - Mocks</title>
      <description>&lt;blockquote class="excerpt"&gt;
  &lt;p&gt;Tem gente "chutando" Demeter.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Minha id&#233;ia era escrever um post dessa s&#233;rie por semana, mas infelizmente uma tendinite tem me atacado e est&#225; meio complicado ficar escrevendo muito. Por isso mesmo esse segundo artigo ser&#225; bem compacto. Todos os c&#243;digos citados nesse post fazem parte de um projeto How Test que est&#225; dispon&#237;vel em: http://github.com/tapajos/how-test&lt;/p&gt;

&lt;p&gt;Nesse post a minha id&#233;ia &#233; mostrar de forma bem simples como funciona um &lt;a href="http://en.wikipedia.org/wiki/Mock_Object"&gt;mock object&lt;/a&gt; no Rspec e no Test::Unit(usando o mocha). &lt;/p&gt;

&lt;p&gt;Para exemplificar eu vou fazer uma cr&#237;tica a uma constru&#231;&#227;o que eu tenho visto muito em diversos projetos e que viola a &lt;a href="http://en.wikipedia.org/wiki/Law_of_Demeter"&gt;Lei de Demeter&lt;/a&gt;(Principle of Least Knowledge). Ou como dizia, o meu amigo, Bernardo, "Tem gente chutando Demeter!". &lt;/p&gt;

&lt;h3&gt;Vamos a um exemplo dessa viola&#231;&#227;o:&lt;/h3&gt;

&lt;p&gt;Supondo que voc&#234; tenha um modelo Account que se relaciona ao modelo User.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Account &amp;lt; ActiveRecord::Base
  belongs_to :user
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Freq&#252;entemente eu vejo constru&#231;&#245;es do tipo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@account.user.name
@account.user.mail
@account.user.rg.number
@account.user.rg.state
@account.user.rg.city
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;O grande problema &#233; que nesse tipo de constru&#231;&#227;o voc&#234; est&#225; "conhecendo" coisas demais e certamente vai pagar por isso num futuro breve, quando voc&#234; precisar fazer um refactoring e tiver que mudar em v&#225;rios lugares. Imagina se o User deixa de ter um "name" e passa a ter um "full_name".&lt;/p&gt;

&lt;p&gt;Para resolver esse tipo de problema basta voc&#234; concentrar esse "conhecimento" no seu modelo Account da seguinte forma:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Account &amp;lt; ActiveRecord::Base
  belongs_to :user
  def user_name
    user.name
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;OBS: Vou me concentrar apenas no problema com o nome e n&#227;o vou me preocupar em validar se o relacionamento foi estabelecido.&lt;/p&gt;

&lt;p&gt;Bem, finalizada a cr&#237;tica a uma falha de design OO vamos ao objetivo desse post, mostrar como *EU* testaria esse problema.&lt;/p&gt;

&lt;p&gt;Como eu falei no post anterior, n&#227;o gosto muito de usar fixtures para testes unit&#225;rios e por isso mesmo vou apelar aos &lt;a href="http://en.wikipedia.org/wiki/Mock_Object"&gt;mock objects&lt;/a&gt;. Se voc&#234; n&#227;o est&#225; muito familiarizado com mocks sugiro que pare por aqui e leia um pouco mais sobre isso. Uma refer&#234;ncia r&#225;pida pode ser o &lt;a href="http://en.wikipedia.org/wiki/Mock_Object"&gt;wikipedia&lt;/a&gt; mas realmente sugiro que v&#225; mais adiante.&lt;/p&gt;

&lt;p&gt;Testando usando RSpec(usando o framework de mock padr&#227;o):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;before(:each) do
  @account = Account.new    
  @user_mock = mock_model(User)
  @account.stub!(:user).and_return(@user_mock)
end

describe ".user_name" do

  it "should delegate to user.name" do
    @user_mock.should_receive(:name).and_return("Tapaj&#243;s")
    @account.user_name.should == "Tapaj&#243;s"
  end

end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Testando usando Test::Unit com mocha:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;setup :create_model

def test_user_name
  @user_mock.expects(:name).returns("Tapaj&#243;s")
  assert_equal "Tapaj&#243;s", @account.user_name
end

private

  def create_model
    @account = Account.new
    @user_mock = mock("User")
    @account.stubs(:user).returns(@user_mock)
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Explicando...&lt;/h3&gt;

&lt;p&gt;Em ambos os casos eu preciso que a minha account simule o relacionamento com User e para isso eu vou retornar um mock object. Isso &#233; feito pelas linhas:&lt;/p&gt;

&lt;p&gt;RSpec:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@account.stub!(:user).and_return(@user_mock)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Test::Unit:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@account.stubs(:user).returns(@user_mock)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ap&#243;s o setup ou o before, temos um modelo @account onde o @account.user retorna um mock.&lt;/p&gt;

&lt;p&gt;Feito isso eu preciso configurar o meu mock, isto &#233;, informar que ele receber&#225; uma mensagem name (chamada do m&#233;todo .name) e essa retornar&#225; o meu nome(sim, sou egoc&#234;ntrico). Isso &#233; feito pelos m&#233;todos "should_receive" e "expects" conforme as linhas abaixo:&lt;/p&gt;

&lt;p&gt;RSpec:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@user_mock.should_receive(:name).and_return("Tapaj&#243;s")
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Test::Unit:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@user_mock.expects(:name).returns("Tapaj&#243;s")
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Depois que nossos mocks foram devidamente configurados podemos, finalmente, fazer nossa verifica&#231;&#227;o do retorno, isto &#233;, simplesmente chamar nossos m&#233;todos conferir o retorno. Pronto teste feito com sucesso, sem precisar recorrer a banco de dados nem configurar fixtures.&lt;/p&gt;

&lt;p&gt;Nesse momento deve ter surgido uma d&#250;vida: "Porque uma hora voc&#234; usa stub! e outra um should_receive?"&lt;/p&gt;

&lt;p&gt;A resposta &#233; bem simples, o stub! n&#227;o faz um verify no final enquanto a outra chamada sim. Na pratica isso significa:&lt;/p&gt;

&lt;h3&gt;Stub! ou stubs&lt;/h3&gt;

&lt;p&gt;Quando eu uso stub!(ou um Stubs) eu estou configurando o meu modelo account para responder pelo m&#233;todo user retornando o @mock_user por&#233;m n&#227;o me interessa quebrar esse teste caso voc&#234; n&#227;o chame esse m&#233;todo.&lt;/p&gt;

&lt;h3&gt;Should_receive ou expects&lt;/h3&gt;

&lt;p&gt;Quando eu uso should_receive(ou um expects) eu estou configurando o meu mock user para responder pelo m&#233;todo name por&#233;m caso esse m&#233;todo n&#227;o seja chamado eu devo quebrar meu teste, pois isso seria um comportamento indesej&#225;vel.&lt;/p&gt;

&lt;h2&gt;Porque usar mocks?&lt;/h2&gt;

&lt;p&gt;Ao contr&#225;rio do que muita gente pensa o uso de mocks n&#227;o &#233; um bicho de 7 cabe&#231;as, &#233; bem simples. Na verdade testar &#233; algo simples, desde que voc&#234; tenha dom&#237;nio do ferramental e os mocks s&#227;o realmente &#250;teis em diversos casos.&lt;/p&gt;

&lt;p&gt;Imagina que o seu sistema precise fazer consultas a uma api publica do Yahoo e para isso voc&#234; tenha criado uma classe de consultas. Voc&#234; n&#227;o vai querer(nem o Yahoo vai gostar) ir l&#225; no servidor toda vez que voc&#234; rodar os seus testes. Isso tornaria os seus testes lentos e imposs&#237;vel roda-los offline. Nesse caso voc&#234; resolve seu problema "mockando" essa classe.&lt;/p&gt;</description>
      <pubDate>Sun, 16 Nov 2008 18:22:13 -0200</pubDate>
      <guid isPermaLink="false">urn:uuid:bf5b906d-9cec-4301-8cd1-f6480e1d406b</guid>
      <author>Marcos Tapaj&#243;s</author>
      <link>http://blog.improveit.com.br/articles/2008/11/16/como-testar-parte-2-mocks</link>
      <category>rails</category>
      <category>rspec</category>
      <category>rspec_on_rails</category>
      <category>ruby</category>
      <category>test</category>
      <category>Testes</category>
      <category>unit</category>
    </item>
    <item>
      <title>Como Testar parte 1 - Models</title>
      <description>&lt;p&gt;Quando comecei a estudar &lt;a href="http://www.improveit.com.br/xp"&gt;Extreme Programming&lt;/a&gt; descobri que n&#227;o &#233; poss&#237;vel fazer nenhum software de qualidade sem uma excelente base de testes. Desde ent&#227;o tenho me dedicado muito ao estudo das mais diversas ferramentas e t&#233;cnicas para elaborar bons de testes.&lt;/p&gt;

&lt;p&gt;O assunto testes &#233; bastante pol&#234;mico e n&#227;o pretendo (nesse post) tentar convencer ningu&#233;m da import&#226;ncia deles. Se voc&#234; n&#227;o faz testes e/ou discorda de qualquer uma das minhas afirma&#231;&#245;es deixo algumas perguntas para voc&#234; refletir.&lt;/p&gt;

&lt;p&gt;1 - Quantos bugs fixes voc&#234; fez esse ano?&lt;/p&gt;

&lt;p&gt;2 - Quantos tickets abertos existem no seu bug tracker?&lt;/p&gt;

&lt;p&gt;3 - Quantas vezes voc&#234; fez um deploy de uma nova vers&#227;o em uma sexta feira de tarde e saiu mais cedo do trabalho?&lt;/p&gt;

&lt;p&gt;4 - Quantas vezes voc&#234; "virou a noite" esse ano?&lt;/p&gt;

&lt;p&gt;Acabei me tornando um evangelizador de testes por&#233;m nunca fiz nada muito pr&#225;tico para passar o conhecimento que eu adquiri para a comunidade. S&#243; que agora vou me redimir dessa falha iniciando uma s&#233;rie de posts onde vou expor um problema e como EU testaria usando Test::Unit e Rspec. N&#227;o vou falar de Shoulda pois n&#227;o gosto dele. :-)&lt;/p&gt;

&lt;p&gt;A id&#233;ia de escrever essa s&#233;rie de posts sobre testes surgiu logo ap&#243;s a grava&#231;&#227;o do terceiro epis&#243;dio do &lt;a href="http://railsbox.org/2008/9/9/railsbox-podcast-3"&gt;RailsBox&lt;/a&gt; e gostaria de agradecer ao Ozeias e ao Davis Cabral por terem me motivado.&lt;/p&gt;

&lt;p&gt;"Back to the cold cow..."&lt;/p&gt;

&lt;p&gt;O ActiveRecord simplifica muito nossos modelos por&#233;m tenho observado que em v&#225;rios projetos os desenvolvedores deixam de testar corretamente os seus modelos usando a  alega&#231;&#227;o que n&#227;o v&#227;o testar alguma coisa que o Rails j&#225; testou. Esse &#233; um argumento valido em alguns casos pois voc&#234; est&#225; apenas delegando responsabilidades mas voc&#234; sempre deve testar se a responsabilidade foi realmente delegada.&lt;/p&gt;

&lt;p&gt;Um exemplo cl&#225;ssico s&#227;o as valida&#231;&#245;es. Teoricamente voc&#234; n&#227;o precisaria testar como elas s&#227;o implementadas mas deve testar se elas realmente existem pois se algu&#233;m remove-las seus testes v&#227;o continuar passando mas sua aplica&#231;&#227;o estar&#225; quebrada e/ou permitindo inconsist&#234;ncias de banco de dados.&lt;/p&gt;

&lt;p&gt;Nesse post vou mostrar como testar alguns comportamento do ActiveRecord usando como base o modelo User. Todos os c&#243;digos citados nesse post fazem parte de um projeto How Test que est&#225; dispon&#237;vel em: http://github.com/tapajos/how-test&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class User &amp;lt; ActiveRecord::Base
  validates_presence_of :name
  validates_format_of :mail, 
                      :with =&amp;gt; /([-.\w^@]+@(?:[-\w]+.)+[A-Za-z]{2,4})+/i,
                      :on =&amp;gt; :create,
                      :allow_nil =&amp;gt; true
  has_many :accounts
  named_scope :actives, :conditions =&amp;gt; ["active = ?", true]
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Uma boa estrat&#233;gia para orientar o desenvolvimento dos teste &#233; elaborar algumas perguntas que dar&#227;o origem aos seus cen&#225;rios de testes.&lt;/p&gt;

&lt;h3&gt;Valida&#231;&#227;o do nome&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Posso cadastrar um usu&#225;rio sem nome? N&#227;o&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;Testando usando Test:Unit:&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;def test_if_check_presence_of_name
  assert !@user.valid?, "Should be invalid"
  assert_equal "can't be blank", @user.errors[:name]
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Na primeira linha desse teste o assert recebe um segundo par&#226;metro que por ser opcional n&#227;o &#233; muito comentado mas merece uma aten&#231;&#227;o especial. Esse argumento nada mais &#233; do que a mensagem que ser&#225; exibida quando o teste quebrar. Quando voc&#234; omite esse par&#226;metro o teste quebra exibindo a mensagem 'false is not true' que n&#227;o ajuda muito a entender o que est&#225; acontecendo.&lt;/p&gt;

&lt;h4&gt;Testando usando RSpec:&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;it "should reject if name is not given" do
  @user.should have(1).error_on(:name)
  @user.errors[:name].should == "can't be blank"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Valida&#231;&#227;o do e-mail.&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Posso criar um registro com um e-mail inv&#225;lido? N&#227;o&lt;/li&gt;
&lt;li&gt;Posso atualizar um regitro com um e-mail inv&#225;lido? Sim&lt;/li&gt;
&lt;li&gt;Posso criar um registro com um e-mail em branco? Sim&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;Testando usando Test:Unit:&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;VALIDS_MAIL = %w(foo@bar.com foo@bar.com.br foo@globo.com foo@i_hate_the_microsoft.com foo@i_love_my_mac.com)
INVALIDS_MAIL = %w(foobar.com foo@bar i_hate_the_microsoft.com i_love_my_mac.com)

def test_if_reject_invalid_format_os_mail_on_create
  INVALIDS_MAIL.each do |mail|
    @user.mail = mail
    assert !@user.valid?, "Should be invalid when mail is #{mail}"
    assert_equal "is invalid", @user.errors[:mail]
  end
end

def test_if_not_reject_when_mail_is_nil
  @user.name = "Tapaj&#243;s"
  assert @user.valid?, "Should be valid"
end

def test_if_not_check_format_of_mail_on_update
  @user.name = "Tapaj&#243;s"
  assert @user.save, "Should save"
  @user.mail = "an invalid mail"
  assert @user.valid?, "Should be valid"
end

def test_if_accept_a_valid_mail
  VALIDS_MAIL.each do |mail|
    @user.name = "Tapaj&#243;s"
    @user.mail = mail
    assert @user.valid?, "Should be valid when mail is #{mail}"
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Testando usando RSpec:&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;INVALIDS_MAIL.each do |mail|
  it "should reject because #{mail} is an invalid mail" do
    @user.mail = mail
    @user.should have(1).error_on(:mail)
    @user.errors[:mail].should == "is invalid"
  end
end

VALIDS_MAIL.each do |mail|
  it "should be valid when mail is #{mail}" do
    @user.mail = mail
    @user.should_not have(1).error_on(:mail)
  end
end

it "should not reject if mail is not given" do
  @user.name = "Tapaj&#243;s"
  @user.should be_valid
end

it "should not check mail format on update" do
    @user.name = "Tapaj&#243;s"
    @user.save.should be_true
    @user.mail = "an invalid mail"
    @user.should be_valid
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Testando o relacionamento com Account.&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Um usu&#225;rio pode ter mais de uma conta? Sim&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;Testando usando Test::Unit:&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;def test_has_many_accounts
  association = User.reflect_on_association(:accounts)
  assert association, "Association with account is not found"
  assert_equal :has_many, association.macro
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Testando usando RSpec:&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;it "should has many accounts" do
  association = User.reflect_on_association(:accounts)
  association.should_not be_nil
  association.macro.should == :has_many
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Testando o User.actives&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Posso listar usu&#225;rios inativos? N&#227;o&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;Testando usando Test::Unit:&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;def test_if_actives_use_the_correct_conditions
  assert_equal({:conditions=&amp;gt;["active = ?", true]}, User.actives.proxy_options)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Testando usando RSpec:&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;it "should find for all users that status of active is true" do
  User.actives.proxy_options.should == {:conditions=&amp;gt;["active = ?", true]}
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Para esse post ficar mais simples e curto n&#227;o me preocupei em validar se o tamanho m&#225;ximo dos campos est&#225; coerente com o tamanho m&#225;ximo permitido pelo tipo no banco de dados. Essa &#233; uma valida&#231;&#227;o EXTREMAMENTE importante que n&#227;o deve ser esquecida!&lt;/p&gt;

&lt;p&gt;No pr&#243;ximo post dessa s&#233;rie falarei um pouco sobre a &lt;a href="http://en.wikipedia.org/wiki/Law_of_Demeter"&gt;Lei de Demeter&lt;/a&gt;, como respeita-la e testar alguns m&#233;todos usando &lt;a href="http://en.wikipedia.org/wiki/Mock_Object"&gt;Mock Objects&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;O que voc&#234; achou desse artigo? O que voc&#234; gostaria de saber sobre testes de ActiveRecord que eu n&#227;o falei aqui?&lt;/p&gt;

&lt;p&gt;Aguardo o feedback de voc&#234;s.&lt;/p&gt;</description>
      <pubDate>Sun, 26 Oct 2008 02:51:35 -0200</pubDate>
      <guid isPermaLink="false">urn:uuid:aa3262eb-fd9b-4304-9bb1-f6ef0d945ee2</guid>
      <author>Marcos Tapaj&#243;s</author>
      <link>http://blog.improveit.com.br/articles/2008/10/26/como-testar-parte-1-models</link>
      <category>rspec</category>
      <category>test</category>
      <category>unit</category>
      <category>Testes</category>
      <category>ruby</category>
      <category>rails</category>
      <category>rspec_on_rails</category>
    </item>
    <item>
      <title>Plugin Brazilian Rails atualizado.</title>
      <description>&lt;p&gt;O &lt;a href="http://tudoquequerosaber.com/"&gt;Eduardo Fiorezi&lt;/a&gt; e o Bruno Iecker identificaram um &lt;a href="http://rubyforge.org/tracker/index.php?func=detail&amp;amp;aid=16897&amp;amp;group_id=4003&amp;amp;atid=15412"&gt;bug&lt;/a&gt; no &lt;a href="http://brazilianrails.improveit.com.br"&gt;Brazilian Rails&lt;/a&gt; e me enviaram um patch s&#243; que devido a minha falta de tempo ainda n&#227;o tinha verificado. Acabei de aplicar o patch e como os outros que eles enviaram est&#225; tudo muito bem feito e testado.&lt;/p&gt;

&lt;p&gt;Gostaria de pedir desculpas pela demora e agradecer novamente aos dois pela ajuda.&lt;/p&gt;</description>
      <pubDate>Wed, 23 Jan 2008 16:52:00 -0200</pubDate>
      <guid isPermaLink="false">urn:uuid:29cce0e7-9e29-4495-bd04-d768ec815002</guid>
      <author>Marcos Tapaj&#243;s</author>
      <link>http://blog.improveit.com.br/articles/2008/01/23/plugin-brazilian-rails-atualizado</link>
      <category>brazilianrails</category>
      <category>rails</category>
      <category>plugin</category>
      <category>Testes</category>
    </item>
    <item>
      <title>Plugin Selenium on Rails no Rails 2.0</title>
      <description>&lt;p&gt;Hoje fui migrar um sistema para o Rails 2.0.1 e tudo estava funcionando mas quando fui rodar os testes do Selenium alguns quebraram pois as fixtures n&#227;o eram carregadas no banco de testes.&lt;/p&gt;

&lt;p&gt;Descobri que estava relacionado a um cache de fixtures   e consegui resolver o problema. Acabei de enviar um email para o autor do plugin sugerindo um patch. Como n&#227;o sei quanto tempo vai demorar para sair a corre&#231;&#227;o ent&#227;o resolvi publicar a minha solu&#231;&#227;o aqui para ajudar quem esbarrar nesse problema.&lt;/p&gt;

&lt;p&gt;Para resolver o problema basta editar o arquivo fixture_loader.rb e modificar o trecho:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if fixtures.any?
    Fixtures.create_fixtures fixtures_path, fixtures
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Para: &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if fixtures.any?
    Fixtures.reset_cache
    Fixtures.create_fixtures fixtures_path, fixtures
end
&lt;/code&gt;&lt;/pre&gt;</description>
      <pubDate>Sat, 15 Dec 2007 19:40:00 -0200</pubDate>
      <guid isPermaLink="false">urn:uuid:7e727d0c-45a3-493b-97f8-becbdf731aee</guid>
      <author>Marcos Tapaj&#243;s</author>
      <link>http://blog.improveit.com.br/articles/2007/12/15/plugin-selenium-on-rails-no-rails-2-0</link>
      <category>rails</category>
      <category>selenium</category>
      <category>selenium_on_rails</category>
      <category>Testes</category>
    </item>
    <item>
      <title>Podcast &amp;quot;Tudo que quero saber&amp;quot;</title>
      <description>&lt;p&gt;&lt;a href="http://tudoquequerosaber.com"&gt;Eduardo Fiorezi&lt;/a&gt; publicou mais um &lt;a href="http://podcasts.tudoquequerosaber.com/podcast/Pod10-Disciplina_em_XP_com_Danilo_Sato_e_Marcos_Tapajos.mp3"&gt;podcast&lt;/a&gt; da s&#233;rie &lt;a href="http://tudoquequerosaber.com/?p=40"&gt;"Tudo que quero saber!"&lt;/a&gt;. Dessa vez foi sobre disciplina em projetos com &lt;a href="http://www.improveit.com.br/xp"&gt;eXtreme Programming&lt;/a&gt; e &lt;a href="http://www.improveit.com.br/tapajos"&gt;eu&lt;/a&gt; fui entrevistado junto com o &lt;a href="http://www.dtsato.com/"&gt;Danilo Sato&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Fiquei muito feliz com o convite do &lt;a href="http://tudoquequerosaber.com"&gt;Eduardo&lt;/a&gt; e em conhecer o Danilo, com quem j&#225; troquei algumas figurinhas sobre o &lt;a href="http://groups.google.com/group/dojo_sp"&gt;Dojo-SP&lt;/a&gt;. Obrigado &lt;a href="http://tudoquequerosaber.com"&gt;Eduardo&lt;/a&gt; !&lt;/p&gt;

&lt;p&gt;Mais informa&#231;&#245;es sobre o &lt;a href="http://podcasts.tudoquequerosaber.com/podcast/Pod10-Disciplina_em_XP_com_Danilo_Sato_e_Marcos_Tapajos.mp3"&gt;podcast&lt;/a&gt; &lt;a href="http://tudoquequerosaber.com/?p=40"&gt;aqui&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Mon, 27 Aug 2007 18:03:00 -0300</pubDate>
      <guid isPermaLink="false">urn:uuid:035ce8fe-09ef-49be-b0fb-ea7e77ea5f6f</guid>
      <author>Marcos Tapaj&#243;s</author>
      <link>http://blog.improveit.com.br/articles/2007/08/27/podcast-tudo-que-quero-saber</link>
      <category>xp</category>
      <category>extreme</category>
      <category>programming</category>
      <category>Testes</category>
      <category>TDD</category>
      <category>dojo</category>
      <category>passos de bebe</category>
      <category>baby steps</category>
      <category>podcast</category>
      <category>Marcos</category>
      <category>Tapaj&#243;s</category>
      <category>Danilo Sato</category>
    </item>
    <item>
      <title>Plugin Brazilian Rails</title>
      <description>&lt;p&gt;Acabei de publicar no &lt;a href="http://www.rubyforge.org"&gt;RubyForge&lt;/a&gt; a primeira vers&#227;o do plugin &lt;a href="http://rubyforge.org/projects/brazilian-rails/"&gt;Brazilian Rails&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Desde que eu comecei a programar em &lt;a href="http://www.ruby-lang.org"&gt;Ruby&lt;/a&gt;, usando o &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;, sempre adorei o sistema de plugins, onde facilmente podemos incorporar novas funcionalidades que atendem a v&#225;rios projetos. &lt;/p&gt;

&lt;p&gt;Sempre tive vontade de colocar nossos c&#243;digos dispon&#237;veis como plugins mas nunca tive tempo para fazer isso. Inevitavelmente continuo sem tempo mas agora estou contando com um time de amigos que resolveram me ajudar. S&#227;o eles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Andr&#233; Luiz Kupkovski (&lt;a href="http://www.ancar.com.br"&gt;Ancar&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Celestino Ferreira Gomes (&lt;a href="http://www.ancar.com.br"&gt;Ancar&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Rafael Fraga Walter (&lt;a href="http://www.ancar.com.br"&gt;Ancar&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Fernando Jo&#227;o Manfroi (&lt;a href="http://www.ancar.com.br"&gt;Ancar&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Luciene Souza Luna (&lt;a href="http://www.ancar.com.br"&gt;Ancar&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esse plugin surgiu da necessidade de usar o m&#233;todo error&lt;em&gt;_&lt;/em&gt;messages_for para sinalizar na camada de vista os erros encontrados nas valida&#231;&#245;es do nosso modelo. Essas mensagens eram em ingl&#234;s, o que fazia com que os desenvolvedores tivessem que implementar algo semelhante no RHTML.&lt;/p&gt;

&lt;p&gt;Acabamos notando que v&#225;rias outras coisas poderiam ficar mais simples aos brasileiros usando-as como estamos acostumados. Por exemplo, nosso formato padr&#227;o de data &#233; DD/MM/AAAA mas &lt;a href="http://www.ruby-lang.org"&gt;Ruby&lt;/a&gt; n&#227;o trabalha da mesma forma. Para solucionar esse problema fizemos uma implementa&#231;&#227;o que modifica o m&#233;todo to_date do modulo String para lidar com esse nosso formato.&lt;/p&gt;

&lt;p&gt;Esse nosso primeiro release n&#227;o abrange todas as nossas implementa&#231;&#245;es mas resolvemos publicar o quanto antes para poder contar com o &lt;a href="http://www.improveit.com.br/xp/valores/feedback"&gt;feedback&lt;/a&gt; dos nossos usu&#225;rios e melhorar continuamente. &lt;/p&gt;

&lt;p&gt;Trata-se de um projeto Open Source, onde gostar&#237;amos de contar com a colabora&#231;&#227;o da comunidade Brasileira com sugest&#245;es e quem sabe com novos desenvolvedores. Minha &#250;nica exig&#234;ncia com rela&#231;&#227;o aos patches &#233; que eles venham acompanhados de &lt;a href="http://www.improveit.com.br/xp/praticas/tdd"&gt;testes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Quem quiser experimentar nosso plugin basta executar uma &#250;nica linha e reiniciar sua aplica&#231;&#227;o &lt;a href="http://www.rubyonrails.org/"&gt;Rails&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;script/plugin install -x \
svn://rubyforge.org/var/svn/brazilian-rails
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Como temos v&#225;rios tipos de c&#243;digos diferentes devemos fazer outros plugins em breve !&lt;/p&gt;</description>
      <pubDate>Fri, 06 Jul 2007 21:30:00 -0300</pubDate>
      <guid isPermaLink="false">urn:uuid:8ceaaf97-3329-4baa-81b8-75731631f831</guid>
      <author>Marcos Tapaj&#243;s</author>
      <link>http://blog.improveit.com.br/articles/2007/07/06/plugin-brazilian-rails</link>
      <category>ruby</category>
      <category>rails</category>
      <category>Plugins</category>
      <category>Testes</category>
      <category>TDD</category>
      <category>Active</category>
      <category>Record</category>
      <category>Action</category>
      <category>View</category>
      <category>brazilianrails</category>
    </item>
  </channel>
</rss>
