I have already told you that organizing your code in use cases can help you to start your projects using TDD, and also I gave you a tip on how you can organize your app in use cases.
But even if you know what your code should do, is not so obvious how you should structure your tests…
Is not obvious to know…
Where should you test validations?
How granular should yours tests be?
How much should a use case function do?
What level of detail should you have in your tests?
If you have this questions…
I want to share with you a small guide that will help you to give structure to your tests, to help you build new features faster and know where to look when you have to modify existent features.
The first step is to divide your use cases functions in two types…
Actions that will change something, like…
And actions that ask for something, like…
And once that you have your actions in one of this two categories you can use this two templates…
You can start with something like this…
module Things
describe "Create/Change Thing" do
it "has a form" do
# Tests the form fields and default values.
# (Only if you need a form to create/update the thing)
end
it "creates/updates a record" do
# Tests that the record was created/updated with the right values.
end
it "returns success" do
# Tests that when the thing was created successfully it returns a
# success status.
end
describe "with <bad value>" do
# When a bad value is passed
it "does not return success" do
# Tests that it does not returns a success status.
end
it "does not create/update the record" do
# Tests that it does not create/update the record.
end
it "returns an error" do
# Tests that the right error is returned in the right way.
end
end
end
end
Some times you will need to write more test for more complex behaviors, here is what you can do for some common cases…
Complex default values
You can test them switching the it
to describe
and adding more examples
.
describe "has a form" do
example "<case 1>" do
end
example "<case 2>" do
end
#...
end
Complex calculated values when the record is created
Also you can test them switching the it
to describe
and adding more examples
.
describe "creates a record" do
example "<case 1>" do
end
example "<case 2>" do
end
#...
end
Different “Bad values”
To test them you can add more describe
blocks.
describe "with <bad value>" do
end
describe "with <other bad value>" do
end
describe "with <other bad value>" do
end
When you are asking for a single item…
You can test that you are returning just the record attributes that you will need, and the calculated values that you will need in that use case.
module Things
describe "Get Thing" do
it "has some attributes..." do
# Here you can test those properties that come directly
# from the record.
end
describe "<calculated value>" do
example "<case 1>" do
end
example "<case 2>" do
end
# ...
end
describe "<other calculated value>" do
example "<case 1>" do
end
example "<case 2>" do
end
# ...
end
#...
end
end
When you are asking for a list of items…
You can do something very similar but you will need to add a test case to check the you are returning the right items.
module Things
describe "Get Things" do
it "returns all the stored <things>" do
# Here you can check just that the count of the things
# is right
end
describe "each thing..." do
it "has some attributes..." do
# Here you can prepare just one record and select that
# item from the response and test the properties that come directly
# from the record.
end
describe "<calculated value>" do
example "<case 1>" do
end
example "<case 2>" do
end
# ...
end
describe "<other calculated value>" do
example "<case 1>" do
end
example "<case 2>" do
end
# ...
end
#...
end
end
end
This list is not very exhaustive, but I think it can help you to get started with TDD with less frustration!
Now, a little exercise…
Imagine you are building a blog app, and you want to be able to…
Add a blog post with title and content, validating the presence of the title.
List all blog posts sorted by id in a descendent way, with the id and the title.
Try write these two features using TDD and the structure from the templates… And after you have finished you can check how I would do it here.
I send an email each week, trying to share knowledge and fixes to common problems and struggles for ruby on rails developers, like How to fetch the latest-N-of-each record or How to test that an specific mail was sent or a Capybara cheatsheet. You can see more examples on Most recent posts or All post by topic.