Use o describe para agrupar os seus testes de modo lógico. Use o it para escrever
um teste em si. E por fim, use os RSpec::Matchers para verificar o comporta-
mento
esperado dentro do teste.
Agora vamos dar uma olhada nos matchers que vem por padrão com o RSpec.
3.2
Porquê existem tantos matchers no RSpec
Antes de começarmos a ver os diversos matchers que o RSpec nos oferece por padrão,
vale a pena entendermos uma das vantagens em ter tantos matchers assim. Para isso,
vamos criar um pequeno projeto e fazer um teste para ele.
Vamos desenvolver um objeto que sirva como um saco de palavras, onde você
pode colocar palavras dentro dele e depois verificar quantas palavras tem den-
tro do saco. Comece criando um diretório para o nosso projeto, chamado de
bag_of_words:
$ mkdir bag_of_words
26
Casa do Código
Capítulo 3. Introdução ao básico do RSpec
$ cd bag_of_words
Crie um Gemfile usando o bundler:
$ bundle init
Coloque o RSpec no Gemfile:
source "https://rubygems.org"
gem "rspec"
E finalmente instale o RSpec usando o bundler:
$ bundle install
Sobre o Bundler
Caso você ainda não conheça o Bundler, ele é um projeto muito fa-
moso na comunidade Ruby feito para gerenciar as dependências do seu
projeto.
Para fazer isso, você deve cria um arquivo chamado Gemfile e listar
nele as gems com suas versões das quais o seu projeto depende. Baseado
nesse arquivo Gemfile, o Bundler instala as gems necessárias, resol-
vendo as versões delas de acordo com o que você configurou.
Visto que o Bundler é distribuído como uma gem, instalá-lo é bem
fácil, basta você utilizar o RubyGems, fazendo o seguinte comando no
console:
$ gem install bundler
Com o RSpec instalado, vamos criar a estrutura de diretórios do nosso projeto,
começando pelo lib:
$ mkdir lib
E agora crie a estrutura de diretório e arquivos padrão do RSpec usando o se-
guinte comando:
27
3.2. Porquê existem tantos matchers no RSpec
Casa do Código
$ rspec --init
create
spec/spec_helper.rb
create
.rspec
Perceba que ao rodar o comando rspec --init, ele criou dois arquivos e
um diretório. O diretório spec é onde devemos colocar nossos testes. O arquivo
spec/spec_helper.rb é onde são colocadas as configurações comuns entre to-
dos nossos testes. E finalmente no arquivo .rspec é onde podemos deixar salvas as
flags que serão passadas para o comando rspec quando formos rodar nossos testes.
Com a estrutura de diretórios pronta, vamos começar a desenvolver nosso pequeno
projeto.
Comece
criando
um
arquivo
de
teste
chamado
spec/bag_of_words_spec.rb:
$ touch spec/bag_of_words_spec.rb
Vamos fazer um teste para especificar que é possível colocar pala-
vras no nosso saco de palavras.
Escreva o seguinte teste no arquivo
spec/bag_of_words_spec.rb:
require "spec_helper"
require "bag_of_words"
describe BagOfWords do
it "is possible to put words on it" do
bag = BagOfWords.new
bag.put("hello", "world")
expect(bag.words.size).to eq(2)
end
end
Vamos entender o que fizemos nesse teste. Primeiro demos require do
spec_helper, aquele arquivo gerado automaticamente pelo comando rspec
--init. Nesse arquivo ficam as configurações gerais da nossa suíte de testes, en-
tão fizemos require dele para garantir que essas configurações sejam aplicadas ao
nosso teste.
28
Casa do Código
Capítulo 3. Introdução ao básico do RSpec
Depois fizemos require do arquivo bag_of_words, que ainda nem existe,
mas é onde colocaremos o código da nossa classe.
Por fim, no teste em si, nós simplesmente criamos um objeto bag, coloca-
mos duas palavras dentro dele e testamos se o tamanho da lista retornada por
bag.words.size é igual a 2.
Rode o teste e verifique que ele está quebrando:
$ bundle exec rspec --format documentation
(...)
cannot load such file -- bag_of_words (LoadError)
O teste quebra com uma mensagem que nos fala que o problema é que não foi
possível dar require do arquivo bag_of_words. Claro, ainda não o criamos.
Vamos dar o primeiro passo na tentativa de fazer o teste passar, criando esse arquivo com uma classe BagOfWords e com o método BagOfWords#put. Para isso, crie
o
arquivo lib/bag_of_words.rb e escreva o seguinte código nele:
class BagOfWords
attr_reader :words
def initialize
@words = []
end
def put(*words)
# TODO
end
end
Com a implementação acima feita, com basicamente um initialize e um
método put que ainda vamos implementar, podemos rodar os testes novamente e
ver o feedback para o próximo passo:
$ bundle exec rspec --format documentation
BagOfWords
is possible to put words on it (FAILED - 1)
Failures:
29
3.2. Porquê existem tantos matchers no RSpec
Casa do Código
1) BagOfWords is possible to put words on it
Failure/Error: expect(bag.words.size).to eq(2)
expected: 2
got: 0
(compared using ==)
Nosso teste quebrou com a seguinte mensagem:
Failure/Error: expect(bag.words.size).to eq(2)
expected: 2
got: 0
Pela mensagem podemos ver que o esperado era que o size do array words
fosse 2, mas veio 0. A mensagem está correta e está de acordo com nosso objetivo