Vamos falar de teste, e de RSpec para ser específico, confesso que ainda estou no comecinho com RSpec mas o que eu já vi e entendi da pra ajudar quem ainda não viu nada, e como exemplificar é melhor que falar, vou fazer um exemplo chamado fizzbuzz que vi no dojo-rio a algumas semanas, naquela ocasião foi feito em Python mas como meu foco é Ruby, vou fazer com ele.
O exercício chamado Fizzbuzz é o seguinte, se um número for divisível por 3, escreve fizz, se o número for divisível por 5, escreve buzz, se for pelos 2, escreve fizzbuzz, se não for por nenhum deles, retorna o próprio
número.
Se você é aquela pessoa anciosa que não quer ver o passo a passo do problema e só quer a resposta, e continuar sem entender nada, vai logo pro final deste post.
Abra o terminal e instale a gem do rspec
sudo gem install rspec
Vá para seu diretório de projetos e crie um diretório chamado fizzbuzz e entre nele:
cd project && mkdir fizzbuzz && cd fizzbuzz
// com isso ele fará as 3 requisições uma depois da outra
Crie um arquivo chamado test.rb e salve. Este é o arquivo que vai ser lido quando rodar o spec.
gedit test.rb
Para verificar se o nosso ambiente de teste está funcionando faça:
describe "Teste" do
it "para ver se está funcionando" do
1.should == 1
end
end
E depois rode no terminal:
clear && spec test.rb --color --format nested
# o comando clear limpa a tela, e depois agente executa o camando do RSpec, ele vai adicionar cor e identar
Linha por linha:
describe "Teste" do # describe => declara o grupo de exemplos, é um bloco tem o (do) para abrir e o (end) para fechar esse bloco
it "para ver se está funcionando" do # it => declara o exemplo
1.should == 1 # should => é um método da classe Oject, se a espectativa retornar true ela passa, se retornar false o should mostra uma mensagem de falha
Agora voltando ao problema, a primeira coisa que você tem que pensar é existe 4 regras pra resolver, então
tem que começar pela que é teoricamente mais fácil, que é:
Se é divisível por 3, retorna fizz.
describe "Fizzbuzz" do
context "é divisível" do
it "por 3" do
fizzbuzz(9).should == "fizz"
end
end
end
Se você for no terminal e rodar a spec vai acontecer isso:
Fizzbuzz
é divisível
por 3 (FAILED - 1)
1)
NoMethodError in 'Fizzbuzz é divisível por 3'
undefined method `fizzbuzz' for #<Spec::Example::ExampleGroup::Subclass_1::Subclass_1:0x7f7f950a5250>
./test.rb:4:
Finished in 0.040514 seconds
1 example, 1 failure
Mas é claro, não existe método fizzbuzz, então ta na hora de criar um outro arquivo, chamado "fizzbuzz" mesmo:
gedit fizzbuzz.rb
e chamar este arquivo no nosso arquivo de teste, o test.rb:
require "fizzbuzz"
e no arquivo fizzbuzz.rb
def fizzbuzz(numero)
"fizz"
end
Passou, mas ainda não resolveu nossa primeira regra. Para resolver a primeira regra é bem simples.
def fizzbuzz(numero)
if numero %3 == 0 # Se for divisível por 3, retorna a palavra fizz
"fizz"
end
end
Se você for curioso como eu, vai querer ver se realmente isso ta funcionando como o esperado, troca a palavra fizz por buzz:
Fizzbuzz
é divisível
por 3 (FAILED - 1)
1)
'Fizzbuzz é divisível por 3' FAILED
expected: "fizz",
got: "buzz" (using ==)
./test.rb:5:
Finished in 0.036305 seconds
1 example, 1 failure
Bang !!! ... o teste esperava a palavra fizz, porém o método retornou a palavra buzz, volte com a palavra fizz e seguiremos nossas regras. Agora se é divisível por 5, retornar buzz.
Depois do primeiro bloco it adicione este bloco:
it "por 5 " do
fizzbuzz(10).should == "buzz"
end
Se você rodar o teste vai ver que o primeiro teste passou e o segundo teve o seu retorno nulo, por que ele não é divisível por 3, e como não tem nenhum else ele vai retornar nulo.
Fizzbuzz
é divisível
por 3
por 5 (FAILED - 1)
1)
'Fizzbuzz é divisível por 5 ' FAILED
expected: "buzz",
got: nil (using ==)
./test.rb:10:
Finished in 0.039466 seconds
2 examples, 1 failure
Para resolver isso coloque a condição para ser divisível por 5.
def fizzbuzz(numero)
if numero %3 == 0
"fizz"
elsif numero %5 == 0
"buzz"
end
end
Agora passou, eu sei que parece chato para alguns, mas estou seguindo um esquema de dojo, então explico em detalhes cada passo, para realmente a pessoa entender como faz.
A próxima regra é para ver se é divisível por 3 e 5 ao mesmo tempo, retornar fizzbuzz.
Depois do bloco do it coloque este aqui.
it "por 3 e 5" do
fizzbuzz(15).should == "fizzbuzz"
end
E o método vai ficar diferente, por que primeiro temos que testar se é divisível pelos 2 números, para depois testar as outras condições
def fizzbuzz(numero)
if numero %3 == 0 and numero %5 == 0
"fizzbuzz"
elsif numero %3 == 0
"fizz"
elsif numero %5 == 0
"buzz"
end
end
Agora para a última regra, verificar se não é divisível por nenhum dos 2 números. Abaixo do contexto coloque isto:
require "fizzbuzz"
describe "Fizzbuzz" do
context "é divisível" do
it "por 3" do
fizzbuzz(9).should == "fizz"
end
it "por 5 " do
fizzbuzz(10).should == "buzz"
end
it "por 3 e 5" do
fizzbuzz(15).should == "fizzbuzz"
end
end
context "se não for divisível por 3 ou 5" do
it "retorna o mesmo valor" do
numero = 7
fizzbuzz(numero).should == numero
end
end
end
Fiz assim para ficar mais organizável e legível, agora é só adicionar este último else para finalizar o
processo.
def fizzbuzz(numero)
if numero %3 == 0 and numero %5 == 0
"fizzbuzz"
elsif numero %3 == 0
"fizz"
elsif numero %5 == 0
"buzz"
else
numero
end
end
Essa forma é a que eu vejo ser a mais simples, tem como otimizar mais este código, mas isso fica para outra hora, espero que eu tenha ajudado de alguma forma, até a próxima.
O exercício chamado Fizzbuzz é o seguinte, se um número for divisível por 3, escreve fizz, se o número for divisível por 5, escreve buzz, se for pelos 2, escreve fizzbuzz, se não for por nenhum deles, retorna o próprio
número.
Se você é aquela pessoa anciosa que não quer ver o passo a passo do problema e só quer a resposta, e continuar sem entender nada, vai logo pro final deste post.
Abra o terminal e instale a gem do rspec
sudo gem install rspec
Vá para seu diretório de projetos e crie um diretório chamado fizzbuzz e entre nele:
cd project && mkdir fizzbuzz && cd fizzbuzz
// com isso ele fará as 3 requisições uma depois da outra
Crie um arquivo chamado test.rb e salve. Este é o arquivo que vai ser lido quando rodar o spec.
gedit test.rb
Para verificar se o nosso ambiente de teste está funcionando faça:
describe "Teste" do
it "para ver se está funcionando" do
1.should == 1
end
end
E depois rode no terminal:
clear && spec test.rb --color --format nested
# o comando clear limpa a tela, e depois agente executa o camando do RSpec, ele vai adicionar cor e identar
Linha por linha:
describe "Teste" do # describe => declara o grupo de exemplos, é um bloco tem o (do) para abrir e o (end) para fechar esse bloco
it "para ver se está funcionando" do # it => declara o exemplo
1.should == 1 # should => é um método da classe Oject, se a espectativa retornar true ela passa, se retornar false o should mostra uma mensagem de falha
Agora voltando ao problema, a primeira coisa que você tem que pensar é existe 4 regras pra resolver, então
tem que começar pela que é teoricamente mais fácil, que é:
Se é divisível por 3, retorna fizz.
describe "Fizzbuzz" do
context "é divisível" do
it "por 3" do
fizzbuzz(9).should == "fizz"
end
end
end
Se você for no terminal e rodar a spec vai acontecer isso:
Fizzbuzz
é divisível
por 3 (FAILED - 1)
1)
NoMethodError in 'Fizzbuzz é divisível por 3'
undefined method `fizzbuzz' for #<Spec::Example::ExampleGroup::Subclass_1::Subclass_1:0x7f7f950a5250>
./test.rb:4:
Finished in 0.040514 seconds
1 example, 1 failure
Mas é claro, não existe método fizzbuzz, então ta na hora de criar um outro arquivo, chamado "fizzbuzz" mesmo:
gedit fizzbuzz.rb
e chamar este arquivo no nosso arquivo de teste, o test.rb:
require "fizzbuzz"
e no arquivo fizzbuzz.rb
def fizzbuzz(numero)
"fizz"
end
Passou, mas ainda não resolveu nossa primeira regra. Para resolver a primeira regra é bem simples.
def fizzbuzz(numero)
if numero %3 == 0 # Se for divisível por 3, retorna a palavra fizz
"fizz"
end
end
Se você for curioso como eu, vai querer ver se realmente isso ta funcionando como o esperado, troca a palavra fizz por buzz:
Fizzbuzz
é divisível
por 3 (FAILED - 1)
1)
'Fizzbuzz é divisível por 3' FAILED
expected: "fizz",
got: "buzz" (using ==)
./test.rb:5:
Finished in 0.036305 seconds
1 example, 1 failure
Bang !!! ... o teste esperava a palavra fizz, porém o método retornou a palavra buzz, volte com a palavra fizz e seguiremos nossas regras. Agora se é divisível por 5, retornar buzz.
Depois do primeiro bloco it adicione este bloco:
it "por 5 " do
fizzbuzz(10).should == "buzz"
end
Se você rodar o teste vai ver que o primeiro teste passou e o segundo teve o seu retorno nulo, por que ele não é divisível por 3, e como não tem nenhum else ele vai retornar nulo.
Fizzbuzz
é divisível
por 3
por 5 (FAILED - 1)
1)
'Fizzbuzz é divisível por 5 ' FAILED
expected: "buzz",
got: nil (using ==)
./test.rb:10:
Finished in 0.039466 seconds
2 examples, 1 failure
Para resolver isso coloque a condição para ser divisível por 5.
def fizzbuzz(numero)
if numero %3 == 0
"fizz"
elsif numero %5 == 0
"buzz"
end
end
Agora passou, eu sei que parece chato para alguns, mas estou seguindo um esquema de dojo, então explico em detalhes cada passo, para realmente a pessoa entender como faz.
A próxima regra é para ver se é divisível por 3 e 5 ao mesmo tempo, retornar fizzbuzz.
Depois do bloco do it coloque este aqui.
it "por 3 e 5" do
fizzbuzz(15).should == "fizzbuzz"
end
E o método vai ficar diferente, por que primeiro temos que testar se é divisível pelos 2 números, para depois testar as outras condições
def fizzbuzz(numero)
if numero %3 == 0 and numero %5 == 0
"fizzbuzz"
elsif numero %3 == 0
"fizz"
elsif numero %5 == 0
"buzz"
end
end
Agora para a última regra, verificar se não é divisível por nenhum dos 2 números. Abaixo do contexto coloque isto:
require "fizzbuzz"
describe "Fizzbuzz" do
context "é divisível" do
it "por 3" do
fizzbuzz(9).should == "fizz"
end
it "por 5 " do
fizzbuzz(10).should == "buzz"
end
it "por 3 e 5" do
fizzbuzz(15).should == "fizzbuzz"
end
end
context "se não for divisível por 3 ou 5" do
it "retorna o mesmo valor" do
numero = 7
fizzbuzz(numero).should == numero
end
end
end
Fiz assim para ficar mais organizável e legível, agora é só adicionar este último else para finalizar o
processo.
def fizzbuzz(numero)
if numero %3 == 0 and numero %5 == 0
"fizzbuzz"
elsif numero %3 == 0
"fizz"
elsif numero %5 == 0
"buzz"
else
numero
end
end
Essa forma é a que eu vejo ser a mais simples, tem como otimizar mais este código, mas isso fica para outra hora, espero que eu tenha ajudado de alguma forma, até a próxima.
Nenhum comentário:
Postar um comentário