No meu primeiro artigo, vou mostrar como testar aplicações Rails de forma simples utilizando Shoulda e factory_girl. Esta é apenas uma introdução, um “por onde começar…”.
Se você não gosta de fixtures, acha o Test:Unit muito básico ou nunca fez testes com aplicações em Rails: Este artigo foi feito sob medida pra você!
Shoulda é um plugin/gem que adiciona alguns recursos poderosos ao conhecido Test::Unit. Com ele, faremos mais testes com menos linhas de código.
factory_girl é uma gem que facilita a criação de dados para testes. Aos invés de usarmos as antigas fixtures, usaremos algo, digamos, mais “sexy”, como a comunidade gosta de chamar.
Vamos direto a prática. O meu ambiente está configurado com Rails 2.1.1.
Crie uma aplicação Rails. Aqui estou usando MySQL:
$ rails my_cash -d mysql
$ cd my_cash/
Agora instale o plugin do Shoulda. Você também pode optar por usar a gem. No meu caso, prefiro adicioná-lo ao projeto:
$ script/plugin install git://github.com/thoughtbot/shoulda.git
Neste exemplo, vou criar uma aplicação bem simples para controlar gastos pessoais. Nela, poderei cadastrar minhas despesas e receitas (que chamarei de operações).
Gere um scaffold para o model operação:
$ ./script/generate scaffold Operation description:string category:string value:float
Edite o arquivo config/database.yml e configure o seu banco de dados.
Após isso, crie todos os databases:
$ rake db:create:all
Agora execute um db:migrate para criar as tabelas no database development:
$ rake db:migrate
Se tudo correu bem até aqui, você pode iniciar sua aplicação e conferir se tudo está funcionando corretamente:
$ ./script/server
Acesse http://localhost:3000/operations e adicione algumas operações. Vamos considerar que uma operação de valor positivo é uma receita, e valor negativo é despesa.
Você terá algo, mais ou menos, assim:

Exemplo de operações
Vamos os testes!
Edite o arquivo test/unit/operation_test.rb.
Uma operação deve ter, pelo menos, descrição e valor preenchidos. Para fazermos este teste utilizaremos uma macro adicionada pelo Shoulda chamada should_require_attributes:
Você pode rodar os testes:
$ rake test:units
Eles vão falhar e você receberá uma mensagem, mais ou menos, assim:
1) Failure:
test: Operation should require description to be set. (OperationTest)
...
Operation allowed nil as a value for description.
...
2) Failure:
test: Operation should require value to be set. (OperationTest)
...
Operation allowed nil as a value for description.
...
2 tests, 2 assertions, 2 failures, 0 errors
Os testes falharam porque ainda não colocamos no nosso model as validações necessárias. Mas veja que interessante. Temos mensagens bastante descritivas sobre os nossos testes:
“Operation should require description to be set. Operation allowed nil as a value for description”.
Está aí um dos grandes pontos fortes do Shoulda. Conseguimos fazer nossos testes ficarem bem próximos de uma especificação. Veremos mais sobre isso adiante.
Vamos editar o arquivo do app/models/operation.rb e adicionar as validações necessárias para evitar que o teste falhe:
Rode os testes novamente (rake test:units) e veja nosso novo resultado:
...
2 tests, 6 assertions, 0 failures, 0 errors
Repare que “por baixo dos panos” o Shoulda criou 2 testes e 6 asserções para garantir que o os nosso model valida a presença dos atributos description e value. Tudo isso com apenas uma linha de código!
Shoulda tem várias macros como a que usamos em nossos testes. Elas tornam nossas classes de teste muito mais enxutas. Para conhecê-las acesse o site do Shoulda.
Antes de prosseguirmos com nossos testes com o Shoulda, vamos configurar o factory_girl. A partir de agora, precisaremos de alguns objetos Operation.
Instale a gem do factory_girl (como estou no Ubuntu, vou utilizar o sudo pra isso):
$ sudo gem install thoughtbot-factory_girl --source http://gems.github.com
Agora precisamos informar ao Rails que nossa aplicação depende da gem factory_girl.
Para isso, adicione a seguinte linha ao arquivo config/enviroment.rb, dentro do bloco Rails::Initializer.run:
Edite o arquivo test/test_helper.rb e comente a linha abaixo para desabilitar o uso de fixtures:
Caso você tenha um projeto que utiliza fixtures e você não quer migrá-lo completamente para factory_girl, não comente a linha acima. Acredito que fixtures e factories podem trabalhar juntas sem problemas.
Crie o arquivo test/factories.rb e adicione o seguinte conteúdo:
Neste arquivo, nós definimos nossos objetos que poderemos usar nos nossos testes.
Agora sim. Com o factory_girl configurado e alguns objetos Operation já definidos, podemos prosseguir.
Edite o arquivo test/unit/operation_test.rb e insira os seguintes métodos:
Nos dois primeiros métodos, estou apenas testando o retorno do valor da primeira operação, e a categoria da segunda operação. Nos dois últimos, estou testando se a operação é uma receita ou uma despesa.
Veja que em cada método estou recuperando um objeto da nossa Factory e fazendo um assert. Como eu disse no início, o Shoulda apenas adiciona funcionalidades ao Test:Unit. Mesmo assim, você ainda pode usar os recursos padrões.
Para que os testes funcionem, adicione os seguintes métodos no model Operation (app/models/operation.rb):
Rode os testes (rake test:units) e terá o seguinte resultado:
6 tests, 10 assertions, 0 failures, 0 errors
Contextos
Contexto é um recurso muito interessante do Shoulda. Com ele podemos especificar situações e tornar os testes mais legíveis. Continue lendo, você já vai entender e gostar muito.
Vou fazer um pequeno refactoring nos nossos testes. Leia o código abaixo com calma:
Repare como eu especifiquei situações (contextos) que fazem meus testes serem lidos de uma forma bastante lógica.
Se você simular um erro você receberá uma mensagem parecida com essa:
1) Failure:
test: A valid operation with value less than zero should be expense. (OperationTest)
...
Viu como tudo fica claro? Ficará melhor ainda.
Um dos recursos que mais gosto no Shoulda é a tarefa shoulda:list que ele adiciona ao rake. Execute:
$ rake shoulda:list
Você terá um retorno assim:
Operation
A valid operation should require description to be set.
A valid operation should require value to be set.
A valid operation should return its category.
A valid operation should return its value.
A valid operation with value greater than zero should be income.
A valid operation with value less than zero should be expense.
OperationsController
test_should_create_operation
test_should_destroy_operation
test_should_get_edit
test_should_get_index
test_should_get_new
test_should_show_operation
test_should_update_operation
Nos testes do model Operation estamos usando Shoulda. Olhe como as mensagens estão muito legíveis!
Nos testes do OperationController estão testes padrões, gerados pelo scaffold, utilizando apenas Test:Unit. Notam a diferença?
Você também pode testar seus controllers utilizando o Shoulda. Leia mais aqui.
Testes com a Shoulda você pode imprimir e conferir junto ao seu cliente. Fica tudo muito claro.
Com o conteúdo apresentado aqui, você já pode testar grande parte das aplicações.
Mas esta foi apenas uma introdução do que é possível fazer com Shoulda e factory_girl.
Encontre mais informações nos seguintes links:
Fiquem à vontade para enviar dúvidas, críticas e sugestões.