Oxente Rails 2010: o evento mais esperado do ano!
Publicado por Vinicius Manhães Teles há 3 meses.
O Oxente Rails 2010 será em Natal nos dias 6 e 7 de agosto de 2010. Segue abaixo o meu convite para a sua participação. Quero te ver lá!

Publicado por Vinicius Manhães Teles há 3 meses.
O Oxente Rails 2010 será em Natal nos dias 6 e 7 de agosto de 2010. Segue abaixo o meu convite para a sua participação. Quero te ver lá!
Tags conferência, oxente rails, rails | 4 comentários
Publicado por Marcos Tapajós há 11 meses.
Algumas semanas atrás Fernando Luizão migrou o Brazilian Rails para funcionar no Ruby 1.9 mantendo a compatibilidade com o Ruby 1.8.X. Estou para divulgar isso tem alguns dias porém eu não tive muito tempo.
Ele explicou em detalhes no blog dele tudo que foi necessário fazer.
Deixo aqui registrado meu muito obrigado ao Fernando.
Tags brazilianrails, rails, ruby, ruby 1.9 | nenhum comentário
Publicado por Vinicius Manhães Teles há 12 meses.
No último sábado participei do Rails for Kids, um excelente evento organizado pela eGenial. Minha apresentação foi sobre como utilizar Ruby on Rails com CouchDB, com a ajuda da gem Couchrest. Para facilitar a apresentação e passar o máximo de informação nos trinta minutos disponíveis, optei por fazer um screencast, que mostra o básico dessa integração do Rails com o CouchDB.
Você pode ver o screencast abaixo.
Ruby on Rails com CouchDB usando Couchrest from Improve It on Vimeo.
O vídeo termina de forma um tanto abrupta, porque tentei me manter o máximo possível dentro do limite de tempo, deixando ainda alguns minutos livres para responder a perguntas. Seja como for, é possível fazer muita coisa com o CouchDB usando os conceitos básicos mostrados no vídeo.
Como gostei da experiência de preparar este, é possível que eu faça outros futuramente, inclusive dando sequência ao que está aí. Espero que seja útil.
Tags couch, couchdb, couchrest, rails, rest, rubyonrails, screencast | 8 comentários
Publicado por Marcos Tapajós há aproximadamente 1 ano.
Conforme anunciado anteriormente adicionei ao Brazilian Rails o suporte ao i18n.
As instruções para uso estão no Readme do projeto ou na página do plugin em:
http://improveit.com.br/software_livre/brazilian_rails
Tags brazilianrails, i18n, rails | 4 comentários
Publicado por Marcos Tapajós há aproximadamente 1 ano.
Já faz algum tempo que o Brazilian Rails vem evoluindo muito mais pela colaboração da comunidade do que por mérito meu. Gostaria de agradecer a todos que já ajudaram no projeto porém hoje quero agradecer a uma pessoa em especial, o Cássio Marques.
O Cássio vem colaborando muito com o projeto sempre fazendo códigos de qualidade e muito bem testados, por isso acabei de tomar a decisão de adiciona-lo como "commiter" do projeto. Com isso ele não precisa mais ficar me pedindo autorização para melhorar o código.
Cássio, seja bem vindo!
Tags brazilianrails, gem, plugin, rails | 2 comentários
Publicado por Marcos Tapajós há aproximadamente 1 ano.
Desde o lançamento do Rails 2.2 várias pessoas me escreveram reportando problemas com o uso das traduções do Brazilian Rails e a nova versão do Rails só que inexplicavelmente nas ultimas duas semanas isso ficou ainda mais intenso (25 emails) e resolvi mexer no projeto e escrever esse post.
A gem brtraducao era um monkey patch que modificava alguns métodos do Rails para injetar as mensagens em português. Com a adição do suporte i18n no Rails o código mudou e por isso a gem parou de funcionar. Esse é o problema desse tipo de patch!
Essa gem foi super útil porém ela se tornou completamente obsoleta e desnecessária pois o i18n já resolve. Claro que ela ainda é útil para quem utiliza as versões anteriores a 2.2 do Rails.
Considerando essa nova realidade eu resolvi remover a gem do projeto e criar um projeto exclusivo para acomodar esse código que ainda é útil para várias pessoas. A gem permanecerá publicad1 no rubyforge (no mesmo lugar). O projeto está no github em:
http://github.com/tapajos/brtraducao
Provavelmente esse código não irá mais evoluir!
Provavelmente nos próximos dias irei adicionar ao projeto um arquivo de configuração do i18n que eu estou preparando baseado nas traduções do Akita e algumas outras novidades.

Para quem quiser aprender como usar o suporte i18n do Rails eu recomendo a leitura desse post do Patrick Espake
Tags brazilianrails, gem, i18n, plugin, rails | 2 comentários
Publicado por Marcos Tapajós há aproximadamente 1 ano.
Tem algum tempo que o Cássio trabalhou em umas melhorias na gem de cpf e cnpj e só agora pude olhar e aceita-las.
Ele escreveu um post explicando tudo que mudou:
http://cassiomarques.wordpress.com/2009/01/21/nova-versao-da-gem-brcpfcnpj
Cássio, obrigado!
Tags brazilianrails, rails | nenhum comentário
Publicado por Marcos Tapajós há aproximadamente 1 ano.
Tem gente "chutando" Demeter.
Minha idéia era escrever um post dessa série por semana, mas infelizmente uma tendinite tem me atacado e está meio complicado ficar escrevendo muito. Por isso mesmo esse segundo artigo será bem compacto. Todos os códigos citados nesse post fazem parte de um projeto How Test que está disponível em: http://github.com/tapajos/how-test
Nesse post a minha idéia é mostrar de forma bem simples como funciona um mock object no Rspec e no Test::Unit(usando o mocha).
Para exemplificar eu vou fazer uma crítica a uma construção que eu tenho visto muito em diversos projetos e que viola a Lei de Demeter(Principle of Least Knowledge). Ou como dizia, o meu amigo, Bernardo, "Tem gente chutando Demeter!".
Supondo que você tenha um modelo Account que se relaciona ao modelo User.
class Account < ActiveRecord::Base
belongs_to :user
end
Freqüentemente eu vejo construções do tipo:
@account.user.name
@account.user.mail
@account.user.rg.number
@account.user.rg.state
@account.user.rg.city
O grande problema é que nesse tipo de construção você está "conhecendo" coisas demais e certamente vai pagar por isso num futuro breve, quando você precisar fazer um refactoring e tiver que mudar em vários lugares. Imagina se o User deixa de ter um "name" e passa a ter um "full_name".
Para resolver esse tipo de problema basta você concentrar esse "conhecimento" no seu modelo Account da seguinte forma:
class Account < ActiveRecord::Base
belongs_to :user
def user_name
user.name
end
end
OBS: Vou me concentrar apenas no problema com o nome e não vou me preocupar em validar se o relacionamento foi estabelecido.
Bem, finalizada a crítica a uma falha de design OO vamos ao objetivo desse post, mostrar como *EU* testaria esse problema.
Como eu falei no post anterior, não gosto muito de usar fixtures para testes unitários e por isso mesmo vou apelar aos mock objects. Se você não está muito familiarizado com mocks sugiro que pare por aqui e leia um pouco mais sobre isso. Uma referência rápida pode ser o wikipedia mas realmente sugiro que vá mais adiante.
Testando usando RSpec(usando o framework de mock padrão):
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ós")
@account.user_name.should == "Tapajós"
end
end
Testando usando Test::Unit com mocha:
setup :create_model
def test_user_name
@user_mock.expects(:name).returns("Tapajós")
assert_equal "Tapajós", @account.user_name
end
private
def create_model
@account = Account.new
@user_mock = mock("User")
@account.stubs(:user).returns(@user_mock)
end
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 é feito pelas linhas:
RSpec:
@account.stub!(:user).and_return(@user_mock)
Test::Unit:
@account.stubs(:user).returns(@user_mock)
Após o setup ou o before, temos um modelo @account onde o @account.user retorna um mock.
Feito isso eu preciso configurar o meu mock, isto é, informar que ele receberá uma mensagem name (chamada do método .name) e essa retornará o meu nome(sim, sou egocêntrico). Isso é feito pelos métodos "should_receive" e "expects" conforme as linhas abaixo:
RSpec:
@user_mock.should_receive(:name).and_return("Tapajós")
Test::Unit:
@user_mock.expects(:name).returns("Tapajós")
Depois que nossos mocks foram devidamente configurados podemos, finalmente, fazer nossa verificação do retorno, isto é, simplesmente chamar nossos métodos conferir o retorno. Pronto teste feito com sucesso, sem precisar recorrer a banco de dados nem configurar fixtures.
Nesse momento deve ter surgido uma dúvida: "Porque uma hora você usa stub! e outra um should_receive?"
A resposta é bem simples, o stub! não faz um verify no final enquanto a outra chamada sim. Na pratica isso significa:
Quando eu uso stub!(ou um Stubs) eu estou configurando o meu modelo account para responder pelo método user retornando o @mock_user porém não me interessa quebrar esse teste caso você não chame esse método.
Quando eu uso should_receive(ou um expects) eu estou configurando o meu mock user para responder pelo método name porém caso esse método não seja chamado eu devo quebrar meu teste, pois isso seria um comportamento indesejável.
Ao contrário do que muita gente pensa o uso de mocks não é um bicho de 7 cabeças, é bem simples. Na verdade testar é algo simples, desde que você tenha domínio do ferramental e os mocks são realmente úteis em diversos casos.
Imagina que o seu sistema precise fazer consultas a uma api publica do Yahoo e para isso você tenha criado uma classe de consultas. Você não vai querer(nem o Yahoo vai gostar) ir lá no servidor toda vez que você rodar os seus testes. Isso tornaria os seus testes lentos e impossível roda-los offline. Nesse caso você resolve seu problema "mockando" essa classe.
Tags rails, rspec, rspec_on_rails, ruby, test, Testes, unit | 8 comentários
Publicado por Marcos Tapajós há aproximadamente 1 ano.
Quando comecei a estudar Extreme Programming descobri que não é possível fazer nenhum software de qualidade sem uma excelente base de testes. Desde então tenho me dedicado muito ao estudo das mais diversas ferramentas e técnicas para elaborar bons de testes.
O assunto testes é bastante polêmico e não pretendo (nesse post) tentar convencer ninguém da importância deles. Se você não faz testes e/ou discorda de qualquer uma das minhas afirmações deixo algumas perguntas para você refletir.
1 - Quantos bugs fixes você fez esse ano?
2 - Quantos tickets abertos existem no seu bug tracker?
3 - Quantas vezes você fez um deploy de uma nova versão em uma sexta feira de tarde e saiu mais cedo do trabalho?
4 - Quantas vezes você "virou a noite" esse ano?
Acabei me tornando um evangelizador de testes porém nunca fiz nada muito prático para passar o conhecimento que eu adquiri para a comunidade. Só que agora vou me redimir dessa falha iniciando uma série de posts onde vou expor um problema e como EU testaria usando Test::Unit e Rspec. Não vou falar de Shoulda pois não gosto dele. :-)
A idéia de escrever essa série de posts sobre testes surgiu logo após a gravação do terceiro episódio do RailsBox e gostaria de agradecer ao Ozeias e ao Davis Cabral por terem me motivado.
"Back to the cold cow..."
O ActiveRecord simplifica muito nossos modelos porém tenho observado que em vários projetos os desenvolvedores deixam de testar corretamente os seus modelos usando a alegação que não vão testar alguma coisa que o Rails já testou. Esse é um argumento valido em alguns casos pois você está apenas delegando responsabilidades mas você sempre deve testar se a responsabilidade foi realmente delegada.
Um exemplo clássico são as validações. Teoricamente você não precisaria testar como elas são implementadas mas deve testar se elas realmente existem pois se alguém remove-las seus testes vão continuar passando mas sua aplicação estará quebrada e/ou permitindo inconsistências de banco de dados.
Nesse post vou mostrar como testar alguns comportamento do ActiveRecord usando como base o modelo User. Todos os códigos citados nesse post fazem parte de um projeto How Test que está disponível em: http://github.com/tapajos/how-test
class User < ActiveRecord::Base
validates_presence_of :name
validates_format_of :mail,
:with => /([-.\w^@]+@(?:[-\w]+.)+[A-Za-z]{2,4})+/i,
:on => :create,
:allow_nil => true
has_many :accounts
named_scope :actives, :conditions => ["active = ?", true]
end
Uma boa estratégia para orientar o desenvolvimento dos teste é elaborar algumas perguntas que darão origem aos seus cenários de testes.
def test_if_check_presence_of_name
assert !@user.valid?, "Should be invalid"
assert_equal "can't be blank", @user.errors[:name]
end
Na primeira linha desse teste o assert recebe um segundo parâmetro que por ser opcional não é muito comentado mas merece uma atenção especial. Esse argumento nada mais é do que a mensagem que será exibida quando o teste quebrar. Quando você omite esse parâmetro o teste quebra exibindo a mensagem 'false is not true' que não ajuda muito a entender o que está acontecendo.
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
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ós"
assert @user.valid?, "Should be valid"
end
def test_if_not_check_format_of_mail_on_update
@user.name = "Tapajó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ós"
@user.mail = mail
assert @user.valid?, "Should be valid when mail is #{mail}"
end
end
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ós"
@user.should be_valid
end
it "should not check mail format on update" do
@user.name = "Tapajós"
@user.save.should be_true
@user.mail = "an invalid mail"
@user.should be_valid
end
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
it "should has many accounts" do
association = User.reflect_on_association(:accounts)
association.should_not be_nil
association.macro.should == :has_many
end
def test_if_actives_use_the_correct_conditions
assert_equal({:conditions=>["active = ?", true]}, User.actives.proxy_options)
end
it "should find for all users that status of active is true" do
User.actives.proxy_options.should == {:conditions=>["active = ?", true]}
end
Para esse post ficar mais simples e curto não me preocupei em validar se o tamanho máximo dos campos está coerente com o tamanho máximo permitido pelo tipo no banco de dados. Essa é uma validação EXTREMAMENTE importante que não deve ser esquecida!
No próximo post dessa série falarei um pouco sobre a Lei de Demeter, como respeita-la e testar alguns métodos usando Mock Objects.
O que você achou desse artigo? O que você gostaria de saber sobre testes de ActiveRecord que eu não falei aqui?
Aguardo o feedback de vocês.
Tags rails, rspec, rspec_on_rails, ruby, test, Testes, unit | 46 comentários
Publicado por Marcos Tapajós há aproximadamente 1 ano.
O Brazilian Rails acabou de ganhar uma gem para lidar com CPF e CNPJ desenvolvida pelo Cássio Marques. Ele fez um post no seu blog explicando como utilizar.
http://tinyurl.com/cpfcnpj
Além dessa nova gem a versão 2.0.8 do Brazilian Rails recebeu algumas pequenas correções feitas pelo Akita e pelo Sergio Brant.
Gostaria de agradecer aos três pelas colaborações.
Tags brazilianrails, cnpj, cpf, gem, rails, ruby | nenhum comentário
Alguns clientes do Be on the Net:
agile beonthenet brazilianrails conferência empreendedorismo extreme programming fotos java plugin podcast produto rails ruby scrum teste treinamento vídeo workshop xp xprio

