MouseOver Studio

MouseOver Studio header image 2

É um assert por teste um “falso ídolo”?

novembro 13th, 2008 por Diego Carrion · 7 comentários

No meu último post argumentei tentando demostrar que seguir o padrão de um assert por testes melhora nossos testes porque nos obriga a criar especificações.

Num dos comentários foi indicado este post do blog dos caras da thoughtbot onde entre outras práticas, criticam a que acabei de mencionar no paragrafo anterior.

Uma boa crítica vem sempre com argumentos e nesse casso achei os argumentos fracos, vamos ver por que.

6 registros criados

O autor do post mostra um código feito em Shoulda onde antes de cada teste cria um registro na base de dados é menciona que o padrão é ruim porque para seguir ele teve que criar seis registros na base. Quem mandou criar um registro antes de cada teste? Se analisam meu post anterior, vão poder apreciar que no exemplo dado eu escrevi:

antes :todos do
  envio_mail = EnvioEmail.new("morena@opensource.com")
end

e não:

antes :cada_um do
  envio_mail = EnvioEmail.new("morena@opensource.com")
end

Shoulda não tem como definir um bloco que vai ser executado antes de tudo? Caso seja assim, problema do Shoulda, não é problema do padrão. Independente de escolher o padrão o não, os testes tem que ser inteligentes.

TDD deve ter ritmo

O autor, no mesmo código, mostra uns testes que são realizados numa linha (macros) e outros que são realizados em trés linhas e argumenta que o padrão é ruim porque o código não tem ritmo é TDD deve ter ritmo. Alguém acha que isto tem algum sentido? O padrão não exige que você tenha testes de uma linha e outros de três. Isso não tem nada a ver com o padrão, eu poderia ter o mesmo comportamento sem seguir o padrão, por exemplo:

should_respond_with_xml_for 'user'
  
should 'include the user id and user name' do
  assert_select 'id', @user.id.to_s
  assert_select 'name', @user.name
end

E agora, vai dizer que o Shoulda é ruim porque criei um código que considero que não tem ritmo? São então os macros ruins porque eles tiram o ritmo do código?

Os nomes dos testes ficam ruins

Não sei se entendi direito esse argumento mas me parece que o autor esta reclamando de que com mas testes ele é obrigado a criar nomes muito específicos. Supondo que estou certo no meu entendimento, a intenção do padrão é justamente essa, criar testes que especifiquem o que estão testando e o que o código deve fazer. Quando executamos os testes acho melhor receber:

a GET to /users/:id.xml should respond with success
a GET to /users/:id.xml should render template show
a GET to /users/:id.xml should find the correct User
a GET to /users/:id.xml should respond with xml for user
a GET to /users/:id.xml should include the user id
a GET to /users/:id.xml should include the user name

que

user show xml

Utilizei “user show xml” porque o segundo código que o autor mostra é um único teste com nome “test_user_show_xml”. “user show xml” não nos diz nada sobre o sistema. Se eu leio esse teste eu vou entender que o usuário deve mostrar um xml. O primeiro caso nos diz bastante sobre o sistema, é uma especificação executável.

WTF

Também não se se entendi direito essa de aqui mas me parece que o argumento diz que se queremos realizar testes curtos por que não utilizamos então o Test::Unit e não RSpec e Shoulda com seus describe, it, should e context que nos obrigam a utilizar trés linhas no mínimo. Que tem a ver isso com o padrão, ele em nenhum momento fala de deixar o código menor. Alias, acho que esse argumento é ate à favor do padrão. Tem gente que diz que não segue o padrão porque gosta de escrever menos código. Beleza, vamos utilizar Test:Unit então. :)

Finalmente o autor do post mostra um código realizado encima do Test::Unit com todos os assert dentro de um teste, utilizando o nome mencionado anteriormente. Eu acho esse teste ruim porque não especifica nada e para entender o que ele testa é necessário ler o código.

Para terminar, no post é mencionado que o padrão um assert por teste é uma solução a um problema que não existe, mas o problema existe sim, e ele é o seguinte:

Escrever documentação não executável de um código é muito custoso porque a cada mudança no código deve ser mudada também a documentação e isso gera trabalho em dobro. Além do trabalho em dobro, a documentação não executável não garante que o código faz o que esta escrito no papel. A solução a isto é criar documentação executável e documentação executável quer dizer testes que especificam e para criar testes que especificam a solução mais fácil é criar um assert por teste.

Tags: bdd · tdd

7 respostas ate agora ↓

  • 1 Samuel Flores // nov 13, 2008 at 8:24 pm

    Concordo em gênero, número e grau. Também havia achado os argumentos sem pé nem cabeça. Ótimo post.

  • 2 Marcio Trindade // nov 13, 2008 at 8:42 pm

    Eu sou contra os posts que de certa forma acabam denegrindo o que uma outra pessoa acredita.
    Acredito que as pessoas tem que se unir sobre o assunto e cada um dar sua opnião, mas sem afetar aos outros.

    Fora isso ótimo post pelo fato das comparações.

  • 3 Diego Carrion // nov 14, 2008 at 11:45 am

    Obrigado Samuel e Marcio, espero poder continuar criando posts assim :)

  • 4 Carlos Brando // nov 20, 2008 at 1:44 pm

    Você devia traduzir este artigo para inglês. Ia gerar uma polêmica interessante.

  • 5 Diego Carrion // nov 20, 2008 at 6:31 pm

    Achei muito boa a idea Carlos, vou aproveitar que estou com um tempinho para traduzir 😛

    Valeu!

  • 6 Tapajós // jan 20, 2009 at 7:01 pm

    O que eu mais gostei foi o e-mail usado no teste! :-)

    Parabéns por estar discutindo e levando reflexão ao mundo dos testes.

  • 7 Diego Carrion // jan 20, 2009 at 10:40 pm

    Hahaha, que saudades da morena!

    Valeu Tapajos (:

Deixar um comentário