06.10
2008

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

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.

01.10
2008

Olá! Para quem não me conhece, eu sou o Lucas Fais.

Demorei bastante para criar meu blog, mas enfim ele está aqui. Pretendo escrever sobre assuntos diversos na área de desenvolvimento de software.

Atualmente estou focando meus estudos em Rails. Nos próximos dias, vou postar meu primeiro artigo: uma breve introdução de como testar aplicações Rails utilizando Shoulda e factory_girl.

Aguardem!