How to Learn Tdd with Ruby

How to learn TDD with Ruby?

The best way to learn TDD is by just doing it. I suggest you build a new project using TDD. This means don't write any non-testing code unless you have a failing test.

It will make you think about writing tests: I want to write this code, how do I write a test for it so I can write it.

It will show you the layered nature of testing. Instead of want a name that is required and can't contain numbers. you'll first test setting and reading a name, test requiring the name, test it shouldn't contain numbers, than think if it has more constraints and test those.

Remember:

  • Write a test before you write the code
  • Make sure the test fails! It's important to know you're testing logic is correct
  • Before writing the next test make sure all tests succeed
  • You can always clean up your code, if the tests keep working you didn't change the design

How to get started on TDD with Ruby on Rails?

What Ruby on Rails TDD 101 article should I read?

I will start with a guide to testing rails applications.

Also Railscast has some excellent screencasts about how to use different testing tools.

What do I need to test?

I will start with models, since they are easy to test. The simple rule is that you need to cover every if statement in your test.

You should test the purpose of the method (to make sure it is functioning as expected) as well as all edge cases.

Also make sure you don't end up over testing.

What gem/plugin should I use? Should I use rspec? Something else?

When you start, just use Test Unit. You can use rspec or cucumber after you get familiar with the basics.

Autotest is a nice tool to have if you want to be truly test driven. But it is a 'nice have' not required.

Once I've got all my testing classes how do I go and deploy them?

Not sure about the question. You don't usually deploy the tests. Once you have all your testing classes simple type 'rake test' to run all your tests.

How time consuming TDD really is?

It saves time really. If you like labyrinth puzzle, you know it is almost always easier to solve it if you go from finish to start. Same with TDD. Without Test Driven you are consistently thinking 'what should i do next'. With Test Driven, the test will tell you what to do next (it breaks if the logic is not there so you just need to fix the broken part). Also you have less bugs which will save you a lot of time in the long run.

Do I need to read a book about this or
can I get everything just by playing
around with it and reading online
tutorials? If I need to read a book,
what book?

You do not need a book. The most efficient way of learning anything is: just do it. Go back to the book or online resources once you encounter a question or problem. This is agile too.

In your example, the things that need testing are: A contact can be linked to 1 company, A company can have multiple contacts, create ways to create contacts, and link contacts to companies.

class CompanyTest <Test::Unit
def test_relationship # test associations/relationships
c = companies(:some_company)
assert_equal [a list of contacts], c.contacts # make sure a company can have multiple contacts
end
end

class ContactTest<Test::Unit
def test_relationships
c = contact(:some_contact)
assert_equal some_company, c.company # make sure the contact link to 1 company
end

def test_create/add
# test create contacts, here you need to make sure the contact is created correctly, and linked to company correctly
end
end

Book/Tutorial for TDD/BDD in ruby?

With the books mentioned above peepcode screencast on cucumber and rspec is also good.

Links
cucumber and rspec

Where to start with test driven development?

I don't think there's one hard and fast answer on where to start.

I personally like to start with my UI first because I want to understand the full user experience before I worry about what happens behind the scenes. However, I know developers who want to start with their models first and build the UI to match them.

So to answer your question, start where ever you feel most comfortable, build your tests then build whatever you need to make them pass.

ruby tdd best practice in dealing with obsolete tests

Since the tests are specifications for the software you intend to write, the question is why you wrote a specification for something you didn't want (since the task of the challenge was not write a function that squares its arguments)?

You should have written a specification for "a method that returns the sum of an array of squares" in the first place. This test starts out being red.

Then you may decide that you need a function that squares its arguments (or the elements of a given array) as an intermediate step. Write a test for this function. Make it green by implementing such a function.

Eventually put all the things together and make your initial test green (your main function could use the helper function and sum-up its return values).

No you can refactor. If during refactoring you decide that you no longer need the helper function: delete the function and delete its tests.

Also when your specifications are changing, you need to rewrite your tests, write new ones or even delete some of them.

But the general rule is: The tests are always a specification for the current state of your software. They should specify exactly what your software is intended to to. Nothing more, nothing less.

Passing Index Loop Vars To Objects in Ruby with TDD

Essentially all of the fancy testing methods like describe, context, it are just ways of defining testing methods. Rspec then calls these testing methods when it actually runs its tests. So it doesn't really make sense to be calling them inside a loop like that, because you're dynamically defining tests (when it definitely isn't needed in your case). Instead you should get rid of the loop, and define all of your expectations within those test cases. For example:

describe(Game) do
subject { Game.new(5) }
describe '#guess' do
context 'when guessing a number that is lower than the secret number ' do
it 'returns the symbol :lower' do
(1..4).each { |val| expect(subject.guess(val)).to eq(:lower) }
end
end

context 'when guessing a number that is the SAME as the secret number ' do
it 'returns the symbol :found_secret_number' do
expect(subject.guess(5)).to eq(:found_secret_number)
end
end

context 'when guessing a number that is higher than the secret number ' do
it 'returns the symbol :greater' do
(6..10).each { |val| expect(subject.guess(val)).to eq(:greater) }
end
end
end
end

Then when I run that file with rspec, I get

...

Finished in 0.02421 seconds (files took 0.26321 seconds to load)
3 examples, 0 failures

Ruby TDD and Rspec

Use RSpec matchers to check that what your method outputs actually matches what you expect it to do.
https://relishapp.com/rspec/rspec-expectations/docs/built-in-matchers

describe "acro method" do
it "returns acronym of words" do
test_sentence = "this is a test acronym"
expected_acronym = "tiata"

expect(acronym(test_sentence)).to eq(expected_acronym)
end
end

Real example on how to do TDD/BDD with Rspec and Cucumber

I highly recommend you the Rspec book which is exactly what you are looking for :

It explains how to use Rspec and Cucumber together with a simple 2 loops process : The outer big loop is a Test - Code - Refactor process you do with cucumber and each step is made of multiple iteration of a Test - Code - Refactor process you do with Rspec.

That books explains at the same time how and when to use each of the two tools.

If you want a broader vision of TDD-BDD, I also suggest you the GOOS book which is more language/tool agnostic and more process oriented.



Related Topics



Leave a reply



Submit