Learncast #1: BDD leve com Shoulda - testando modelos ActiveRecord
Behavior Driven Development parece ganhar tração constantemente nas comunidades de desenvolvedores de teste. Isso não é à toa: essa “nova” mentalidade dá o toque semântico que faltava às técnicas de Test Driven Development.
Na comunidade Rails, os três projetos mais conhecidos na área de BDD são RSpec, Shoulda e test/spec. Minha escolha é o Shoulda, que utilizo desde o lançamento com muito sucesso. Há um bom tempo venho “rascunhando” um screencast introdutório e, finalmente, ele está pronto. Clique aqui para baixá-lo em formato QuickTime.
O objetivo do screencast é apenas mostrar superficialmente o que é Shoulda e como testar funcionalidades de modelos ActiveRecord (como validações e associações). Em breve virão mais alguns cobrindo testes de controllers e mais detalhes sobre o uso do plugin.
Links interessantes:
Shoulda: tutorial | repositório | RDocs | bundle para TextMate
Plugin QuietBacktrace
Comentários, críticas e complementos são muito bem-vindos!
Obs: estou resfriado, mas fiz o possível para deixar o som o mais claro possível. Por favor, avise caso eu não tenha conseguido.
Update: como apontado nos comentários, subi o vídeo sem o som (duh!), mas isso já foi corrigido. Obrigado pelo aviso, pessoal.
Update 2: disponibilizei o script e as imagens que utilizo para o Autotest com o Shoulda em minha máquina, rodando o Leopard. Crie, na pasta home de seu usuário (/Users/<nome_do_seu_usuário>/), uma pasta chamada .autotest_images e copie as duas imagens para lá. Crie, também na home, um arquivo chamado .autotest e preencha-o com o script contido no pacote. Esse script é baseado em um script publicado pelo Carlos Brando.
Rails-footnotes, mais um plugin de Dr Nic
Se você desenvolve em Rails no MacOS X com TextMate, você tem que utilizar o plugin rails-footnotes. Sério. É obrigatório. Mesmo.
Esse plugin coloca um rodapé em todas as páginas de sua aplicação, quando no ambiente de desenvolvimento, mostrando várias informações, como parâmetros da requisição, sessão, cookies, filtros, rotas, queries e log. Além disso, contém também links para abrir arquivos (como o controller ou view atual) no TextMate. Isso permite que você, enquanto navega pela aplicação, possa abrir no TextMate arquivos relacionados a página aberta no navegador, como o controller, a view, o layout ou a folha de estilos.
Extremamente recomendado.
Dica: Migrations com comandos SQL e problemas com testes no Rails
Se você utiliza o método execute em suas migrations para rodar comandos SQL na criação de sua base de dados, cuidado ao rodar os testes de sua aplicação. Na criação da base de testes, o Rails não roda as migrations, ele utiliza o script contido no arquivo schema.rb. O problema é que, ao fazer o dump da base para esse arquivo, o Rails não utiliza os comandos SQL definidos nas migrations e sim os métodos da DSL de manipulação de estrutura e dados (como add_index, create_table, add_column etc).
Devido a isso, se você utilizou alguma particularidade do sistema gerenciador de banco de dados que utiliza ao definir sua base, muito provavelmente ocorrerá um erro no banco de dados ao tentar rodar os testes de sua aplicação.
Exemplo:
Em uma migration:
(...) create_table :tests do |t| t.column :test_column, :text end execute("ALTER TABLE test ADD INDEX test_index(test_column(200));") (...)
No MySQL é necessário definir um comprimento para índices em colunas dos tipos TEXT e BLOB e, como não há essa opção no método add_index, utilizamos um comando SQL. No entanto, no arquivo schema.rb, a criação do índice é feita da seguinte maneira:
add_index "tests", ["test_column"], :name => "test_index"
E isso causa um erro no MySQL. Para corrigí-lo, procure em seu arquivo environment.rb pela seguinte linha:
config.active_record.schema_format = :sql
Por padrão ela vem comentada. Retire o comentário para fazer com que o banco de dados de testes seja criado diretamente com comandos SQL. Caso não a encontre comentada, adicione-a dentro do bloco Rails::Initializer.run.
Novidade pra quem gosta de screencasts
Mike Clark anunciou há pouco em seu blog os Pragmatic Screencasts. O projeto inicia com quatro séries, cada uma sobre um tema (como Erlang e ActiveRecord), cada série com episódios vendidos a cinco dólares cada.
Screencasts são uma excelente forma de aprendizado prático e esta parece ser mais uma boa fonte, ao lado de Peepcode e Railscasts.
Conheça suas gems
Uma boa forma de aprender mais sobre Ruby é “fuçar” no código-fonte de gems. Vagando pelo GitHub e RubyForge esses dias, encontrei um conjunto de pequenos utilitários escritos por Dr Nic (que deve ser um robô ou extraterrestre).
Um desses utilitários chama-se find_gem (não achei um site oficial, apenas esse arquivo de texto explicando como configurar e usar). Ele instala dois comandos em seu sistema:
- find_gem <nome_da_gem>: retorna o caminho completo da gem passada como parâmetro.
- edit_gem <nome_da_gem>: abre os fontes da gem passada como parâmetro no editor configurado com a variável de ambiente EDITOR. Assim você pode vasculhar o código-fonte das gems com mais comodidade.
No MacOS X Leopard funciona muito bem. Outra funcionalidade legal é o auto-complete no comando gem (tanto para os comandos, como install e list, quanto para nomes de gems).
Veja aqui a lista de utilitários do Dr Nic Utilities. Estou utilizando também o git_autocomplete e recomendo.
High Five: five tips on testing with Rails
Testing is a very important aspect of Rails programming. The framework makes testing really easy, eliminating some excuses you could have for not testing your applications. Here’s my five tips for testing with Rails:
- Embrace the TDD cycle: this one isn’t Rails related, but is very important. You can write your code first and test it after and you’ll get some benefits, but Test-Driven Development really leverages the power of this automated testing. By writing your tests first you get low coupling and high cohesion through a better interface (API) design. Moreover, by following the red-green-refactor cycle you’ll always know when you’re done and will avoid scope creep.
- Test your helpers: plain and simple. Rais Recipes has a recipe about it and, with Edge Rails, testing helpers got easier.
- Overmocking results in brittle tests:and brittle tests are a bad thing. Many people just mock and stub everything. By doing this you’re coupling your tests to the inner details of the tested code instead of the result of its execution. You can see an example here (and subscribe to that blog’s feed, it’s very good).
- Watch out on your way to BDD: Behavior-Driven Development is in vogue within the Rails community. Be careful. Just like you can write Fortran in any language, you can use something like RSpec and still not do BDD. BDD is about a shift in the way you think about tests, not about tools by themselves. You can use Test::Unit and do BDD. Tools like RSpec and Shoulda (my personal choice) are facilitators, they don’t guarantee anything.
- One assertion per test: this is one of that tips that seems inoffensive but once you’re doing helps a lot. Why? Jay Fields can explain better than me.
And that’s it. Five quick and simple tips that I hope will help you. Feel free to share your own tips in the comments. This article is my entry to the Railscasts’ 100th episode contest. Take some time to visit the site, it’s really good.
Curso de Rails em Porto Alegre-RS
Pro pessoal de Porto Alegre-RS e região, o Jony dos Santos Kostetzer anunciou uma nova turma do curso Formação Desenvolvedor Web com Ruby on Rails, ministrado por ele.
FISL 9.0 - balanço
O melhor do evento, com certeza, foram as pessoas. Tive a oportunidade de conhecer pessoalmente muita gente que só conhecia no “mundo virtual”: Jony dos Santos, Rodrigo Kochenburger, Júlio Monteiro, Carlos Eduardo Franco, Ronaldo Ferraz, Weldys Santos, Everton Carpes e também rever alguns, como Fábio Akita e Vinícius Teles.

Akita, Tiago, Lucas, Vinícius, Carlos Eduardo, Júlio, Jony e Rodrigo - Rails Brasil em peso no FISL
Vi algumas palestras. Algumas boas, algumas péssimas. Não tem jeito, quando alguém muito técnico é posto para falar, o resultado não é muito bom. Por isso é tão importante sair do “cubículo” e dar atenção a aspectos nâo técnicos para desenvolver outras habilidades.
Conversamos também com um pessoal de um grupo de usuários de Java do Uruguai. Eles estão interessados em aprender Rails e foram até o stand do Rails Brasil para uma conversa. Três pessoas falando espanhol e quatro falando português, imaginem a “salada”.
Outro estrangeiro que apareceu por lá foi o Evan Henshaw-Plath, aka “Rabble”, desenvolvedor Rails da Yahoo! e também um dos criadores do Odeo. A conversa com ele foi muito interessante. Eles nos mostrou um novo produto da Yahoo! desenvolvido em Rails (Fire Eagle) e também nos contou que está escrevendo um livro sobre TDD com Ruby para a O’Reilly.
Outros destaques foram as palestras de Randal Schwartz (que era sobre Seaside mas ficou só no básico de Smalltalk) e Jon Maddog Hall.
O que ficou do evento é que nossa comunidade vem crescendo muito bem e conta com desenvolvedores excelentes, sempre buscando melhorar e objetivando qualidade. Valeu galera, até a próxima oportunidade!
Rails já está no GitHub
http://github.com/rails/rails/tree/master
Contribuindo: plugin reserved_attributes para Rails
(nota: esta é a “tradução” do post anterior)
Esta é minha primeira contribuição para a comunidade Rails: o plugin reserved_attributes.
O plugin é muito simples, apenas adicionando uma task rake ao seu projeto. A task varre todos os seus modelos procurando por attributos que tenham nomes que são palavras reservadas do Ruby/Rails e te avisando disso.
Há algum tempo atrás desperdicei 8 horas de trabalho porque meus testes unitários davam um erro muito estranho (e um trace gigantesco). No fim das contas, eu tinha um atributo chamado “notify”, que é o nome de um método interno, então eu estava sobrescrevendo esse método e bagunçando tudo. Vi muita gente com esse problema, então aqui está uma pequena ajuda. Dê uma olhada na página principal do repositório para ver o README com instruções.
O plugin está hospedado no github e você é livre para fazer um fork e melhorá-lo.