This is a guide to having your TDD enviroment working on your laptop. For this you will need to have certain tool ready to be used.
- RSpec
- FactoryGirl
- Fakker
- DatabaseCleaner
Here at @icalialabs, we use Platter to create rails app with the basic setup.
Platter needs at least ruby 2.0.0 in order to run
Run
% gem install platter
Use
% platter yourNewRailsApp
It will also:
- Setup the testing environment with Rspec, FactoryGirl, DatabaseCleaner.
- Setup an staging environment to deploy to this environment
- Provides the necessary configuration for the PUMA server run with Foreman
- A setup script for new developers
- Adds configuration for ActiveJob and DelayedJob
- In case of an API, it will add Versionist and ActiveModelSerializers, along with a version 1 structure.
- Adds configuration for ActionMailer to run with Sendgrid
- Setup the project with git providing an initial commit
Platter already adds the gem to your Gemfile to be ready to use.
gem 'factory_girl'
Each factory has a name and a set of attributes. The name is used to guess the class of the object by default, but it's possible to explicitly specify it:
# This will guess the User class
FactoryGirl.define do
factory :user do
first_name "John"
last_name "Doe"
admin false
end
# This will use the User class (Admin would have been guessed)
factory :admin, class: User do
first_name "Admin"
last_name "User"
admin true
end
end
factory_girl supports several different build strategies: build, create, attributes_for and build_stubbed:
# Returns a User instance that's not saved
user = build(:user)
# Returns a saved User instance
user = create(:user)
# Returns a hash of attributes that can be used to build a User instance
attrs = attributes_for(:user)
# Returns an object with all defined attributes stubbed out
stub = build_stubbed(:user)
# Passing a block to any of the methods above will yield the return object
create(:user) do |user|
user.posts.create(attributes_for(:post))
end
Refer to Factory Girl for more details on its use.
Platter already adds FFaker gem to the GemFile so it can be used.
require 'ffaker'
FFaker::Name.name #=> "Christophe Bartell"
FFaker::Internet.email #=> "[email protected]"
FFaker solely purpose, is to fill up fields of data saving the developers time doing it so. FFaker reference
Platter adds Database Cleaner gem to the GemFile so it can be used.
require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
# then, whenever you need to clean the DB
DatabaseCleaner.clean
With the :truncation
strategy you can also pass in options, for example:
DatabaseCleaner.strategy = :truncation, {:only => %w[widgets dogs some_other_table]}
DatabaseCleaner.strategy = :truncation, {:except => %w[widgets]}
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
end
There are a few things to keep in mind, but overall if you trust your tests and allow them to guide your development you will not go wrong.
Do's:
- Write your tests first
- Use contexts
- Use shared example groups
- Test your edge cases
Don’ts:
- Test the framework
- Test the implementation
BAD
describe 'the authenticate method for User' do
describe 'if the user is an admin' do
GOOD
describe '.authenticate' do
describe '#admin?' do
Notice the #
symbol is use to describe instance methods, and the .
to describe class methods or scopes.
BAD
it 'has 200 status code if logged in' do
expect(response).to respond_with 200
end
it 'has 401 status code if not logged in' do
expect(response).to respond_with 401
end
GOOD
context 'when logged in' do
it { is_expected.to respond_with 200 }
end
context 'when logged out' do
it { is_expected.to respond_with 401 }
end
BAD
user = User.create(
name: 'Genoveffa',
surname: 'Piccolina',
city: 'Billyville',
birth: '17 Agoust 1982',
active: true
)
GOOD
user = FactoryGirl.create :user
For a specific file
% rspec path/to/spec/file.rb
For all files in path
% rspec path/to/spec/
Also, fell free to take a look at Thoughbot How We Test Rails Applications for more about testing Rails applications.