TDD + Ruby: Número de Fibonacci
June 15, 2009 at 3:34 am | In Ruby/Rails | Leave a CommentEstou necessitado de escrever posts melhores, eu sei, mas enquanto isso, tava brincando aqui com TDD + Ruby, então resolvi fazer um código para gerar a sequencia de Fibonacci fazendo o uso de TDD.
Para quem ainda não sabe, o numero de fibonacci e uma sequencia de numero, que é gerada começando com 1 e em seguida somando os dois anteriores para se conhecer o próximo, na prática:
Começamos com 1, então o proximo numero será : 0 + 1 = 1, o seguinte será 1 + 1 = 2 … 2 +1 = 3 … e assim vai… essa sequencia é defenida como sendo recursiva, a formula é:

Bom, o problema ta entendido(eu acho) rs.
Como vamos fazer o uso de TDD, vamos começar escrevendo nossos testes
Precisamos ter um método chamdo por exemplo fibo, esse método deve receber como argumento um inteiro, inicialmente se passarmos 0(zero) devemos ter como retorno 0(zero), entõa vamos criar o esqueleto do teste:
require "test/unit" require "fibonacci.rb" class Test < Test::Unit::TestCase def test_case_name end end
Acima está o esquelete de um teste básico, na primeira linha fizemos a inclusão do framework de teste, no segundo require chamamos a nossa classe fibonacci(que ainda nao existe), e logo em seguida temos o primeiro método para teste, vamos mudar o nome dele e acresentar o comportamento que nossa classe fibonacci deve ter quando receber zero.
require "test/unit" require "fibonacci.rb" class TestFibonacci < Test::Unit::TestCase def test_fiboZero assert_equal(0, Fibonacci.seqfibo(0)) end end
Todo teste deve iniciar com o palavra test, logo em seguida vem nosso teste propriamente dito, é justamente o que falamos acima, se receber Zero, retorne Zero, vamos rodar nosso teste para ver o que acontece:
LoadError: no such file to load fibonacci.rb
Ops, certamente teriamos um erro ai mesmo, pois ainda nao criamos nossa classe fibonacci, vamos cria-la,(sem nehum codigo ainda) e rodar novamente:
Ops, denov, so temos um arquivo e mais nada então recebemos o seguinte:
Started
E
Finished in 0.002 seconds.
1) Error:
test_fiboZero(TestFibonacci):
NameError: uninitialized constant TestFibonacci::Fibonacci
C:\Documents and Settings\casa\Desktop\Nova pasta\fibonacciTest:5:in `test_fiboZero’
1 tests, 0 assertions, 0 failures, 1 errors
Vamos criar essa classe, acresente o seguinte em fibonacci.rb:
class Fibonacci def self.seqfibo(num) return 0 if num == 0 end end
Bom, isso provavelmente irá fazer nosso teste passar, rodando recebemos o seguinte:
Started
.
Finished in 0.002 seconds.
1 tests, 1 assertions, 0 failures, 0 errors
Legal, tudo passou, nosso primeiro caso esta feito, agora, podemos pensar em outro comportamento para nossa classe. . . .bom testamos com zero agora vamos tentar passar um(1) para o método e ver o que acontece, incluindo mais método para teste (poderia ser feito no mesmo método, mas vou separar aqui), nosso código de teste agora fica assim:
require "test/unit" require "fibonacci.rb" class TestFibonacci < Test::Unit::TestCase def test_fiboZero assert_equal(0, Fibonacci.seqfibo(0)) end def test_fiboUm assert_equal(1, Fibonacci.seqfibo(1)) end end
a lógica dos teste aqui, nao mudou nada, vamos rodar para ver:
Started
F.
Finished in 0.033 seconds.
1) Failure:
test_fiboUm(TestFibonacci) [C:\Documents and Settings\casa\Desktop\Nova pasta\fibonacciTest:8]:
<1> expected but was
<nil>.
2 tests, 2 assertions, 1 failures, 0 errors
Bom, vimos ali que o teste esperava 1 mas retornou nil, vamos implementar essa lógica na nossa classe, agora temos isso:
class Fibonacci def self.seqfibo(num) return 0 if num == 0 return 1 if num == 1 end end
Exatamente igua ao anterior, agora não seria nada bom ficar acresentando todos essas asserts ai para testar cada um dos numero que esperamos obter, para isso em nosso teste vamos criar um array de arrays contendo vários cassos de testes algo do tipo:
testes = [[0,0][1,1][2,1] . . .]
e logo interar por esse array passando esses valores para nosso teste, logo iremos ter um unico método, nossa classe teste fica + – assim agora:
require "test/unit" require "fibonacci.rb" class TestFibonacci < Test::Unit::TestCase def test_fiboZero teste = [[0,0],[1,1],[2,2],[4,5],[3,2]] teste.each do |t| assert_equal(t[1], Fibonacci.seqfibo(t[0])) end end end
Bom, creie um array de array com alguns cassos, agora so falta implementar na classe fibonacci um funcao recursiva para fazer o calculo, então agora tempo:
class Fibonacci def self.seqfibo(num) return num unless num > 2 seqfibo(num-1) + seqfibo(num-2) end #um metodo pra executar def execute for i in 1..10 puts seqfibo(i) end end end
Agora rodamos o código de teste e recebemos:
Started
.
Finished in 0.002 seconds.
1 tests, 5 assertions, 0 failures, 0 errors
Bom, aqui acabamos nossa implementação, obviamente da para melhorar e fazer muitos outros teste, e melhorar o teste, e tudo mais, se alguem achar erros, ou quizer falar algo, porfavor deixe um comentário.
No Comments Yet »
RSS feed for comments on this post. TrackBack URI
Leave a comment
Blog at WordPress.com. | Theme: Pool by Borja Fernandez.
Entries and comments feeds.