Aprendendo TDD: Testando a camada Model [parte 2]

Na primeira parte entendemos um pouco sobre como podemos testar validações, relacionamentos e como podemos seguir o ciclo do TDD à risca(red-green-refactor). Para o texto não ficar muito longo eu precisei dividi-lo em duas partes, e cá estamos para finalizar essa etapa.

Objetivo de hoje

Nessa segunda parte começaremos a utilizar as factories que preparamos no post anterior e que você pode saber um pouco mais no resumo que fiz, no primeiro post dessa série. Também veremos o que é happy path e o motivo de não testarmos somente ele. Junto com o happy path vamos ver o que são e para que servem o context,o it e o expect.

Happy Path? Como assim?

Na continuação dos testes da nossa camada model, vamos escrever um teste assumindo que nossas bandas serão criadas com sucesso, tendo todos os seus atributos obrigatórios devidamente preenchidos, mas, e quando uma banda não possuir um algum atributo obrigatório preenchido, o que deverá acontecer? Precisamos testar esses casos também! Então vamos combinar de que, sempre que acharmos necessário, vamos testar esses dois tipos de cenários, ok?

Testando as factories geradas

Nós já temos nossas validações devidamente testadas com o auxilio da gem shoulda-matchers, agora vamos testar o que acontece quando temos uma banda criada com sucesso (happy path) e uma banda não criada devido a algum atributo obrigatório não preenchido. Para demarcar isso, vamos utilizar o context que serve para organizar de uma maneira mais clara os possíveis cenários onde ocorrerão os nossos testes, ficando da seguinte forma:

Temos definidos aqui dois possíveis cenários, onde um será o cenário que existirão factories válidas e um outro cenário onde existirão factories inválidas.

Dentro de cada bloco context vamos escrever , de fato, nossos testes. Para isso vamos usar o it para descrever teste por teste.

A primeira coisa que testaremos é quando teremos uma factory válida. Nosso teste ficará da seguinte maneira:

Temos duas coisas novas nesse teste: o expect e o be_valid. O primeiro, como o nome sugere, tem o papel de informar a saída esperada pro nosso teste. No caso, nosso teste diz que é esperado (expect) que nossa factory :band seja valida (be_valid).

build ou create?

O build mantém nossas instâncias em memória, já o create persiste essas instâncias no banco. Por questões de desempenho, use o create somente quando for realmente necessário persistir dados no banco.

Agora testamos o que acontece quando uma factory não é criada por ser inválida. Vamos verificar o que acontece quando elas não tem seus atributos obrigatórios preenchidos:

Nesse segundo cenário nós escrevemos um pouco mais de código. Ao invés de passar o build(:band) direto no expect, nós atribuimos a um objeto band, indicando que o atributo name será nil , para depois verificarmos se é válido (band.valid?), e ,por fim, informar que é esperado (expect) o retorno de uma mensagem de erro, informando que esse atributo não pode estar em branco (“can’t be blank”).

Esse teste é importante, pois, lá na frente, quando o cadastro de bandas estiver funcionando certinho, poderá acontecer de o usuário esquecer de preencher o campo nome ao usar nosso sistema.

Agora, basta escrevermos os testes verificando os demais atributos que declaramos obrigatórios: musical_genre e site. Ao rodamos o rspec spec, teremos o seguinte.

Band
 should validate that :name cannot be empty/falsy
 should validate that :musical_genre cannot be empty/falsy
 should validate that :site cannot be empty/falsy
 should have many musics
 is valid
 has a valid factory
 is invalid
 without name
 without musical_genre
 without site

Interessante como os testes geram uma documentação bem completa,não? Isso que dizer que quanto mais você testa seu software, mais controle você terá sobre o mesmo.

Para finalizar, tente escrever os testes do model Music.

Ao final, rode mais uma vez o rspec spec e veja o resultado:

Band
 should validate that :name cannot be empty/falsy
 should validate that :musical_genre cannot be empty/falsy
 should validate that :site cannot be empty/falsy
 should have many musics
 is valid
 has a valid factory
 is invalid
 without name
 without musical_genre
 without site
Music
 should validate that :title cannot be empty/falsy
 should validate that :name_author cannot be empty/falsy
 should belong to band
 is valid
 has a valid factory
 is invalid
 without title
 without name_author
Finished in 0.67403 seconds (files took 2.67 seconds to load)
14 examples, 0 failures
Coverage report generated for RSpec to /home/ricardo/open-source/demo_tdd/coverage. 110 / 110 LOC (100.0%) covered.

Já escrevemos 14 testes!!

Se você teve paciência para chegar até aqui , deve ter questionado a necessidade de testar as factories inválidas mesmo após nós já termos testado os validates do model. Realmente não há necessidade. Utilizei esses exemplos para mostrar a importância do expect, it, context e a diferença entre build e create. São duas formas diferentes de testar, que no final, surtem o mesmo efeito. Então escolha a forma que mais te agrada =)

Finalizo aqui a segunda parte da nossa abordagem a respeito de testes sobre a camada model. Claro que existem outros possíveis testes, mas isso vai depender das particularidades de cada projeto.

Dicas, críticas e outras coisas mais, basta comentar aqui embaixo ou entrar em contato comigo pelo facebook :*

Ah, aqui está o link do projeto

Até a proxima!