I have often been told and red not to test the database. To avoid useless round trips and that my tests should be testing the code, not the database. That is the key to fast testing. But how fast exactly does this change? I took it upon myself to figure it out. I wanted to know the affects of slow vs fast testing and measure it.
Slow tests often come from round trip to the database. I decided to measure the performance impact using a gem I generally use for testing: FactoryGirl
I used my template to create a new blank rails project (You can find the template I use here) with the necessary gems to test this the way I usually test my applications (RSpec & FactoryGirl).
Once installed, create a model to put under test:
rails generate model Person name
I created a quick test that actually does not do anything except instantiating (and / or) creating the object in the database.
My tests looked like this
# spec/models/person_spec.rb
require 'rails_helper'
require 'benchmark'
describe Person, type: :model do
it 'works' do
n = 50_000
Benchmark.bm do |x|
%i(build build_stubbed create).each do |method|
x.report(method) { n.times { send(method, :person) } }
end
end
end
end
Running this test with
bundle exec rspec spec/models/person_spec.rb
will highlight some of the key differences.
The report on my machine (though your based on the time, the processes running and the machine it’s run on may alter the times) looked as following:
user | system | total | real | |
---|---|---|---|---|
build | 6.970000 | 0.130000 | 7.100000 | ( 7.140500) |
build_stubbed | 11.500000 | 0.220000 | 11.720000 | ( 11.779517) |
create | 55.800000 | 5.580000 | 61.380000 | ( 70.141748) |
This show nearly a tenfold slower.
This highlights the importance of well written tests. There are many of blogposts out there to illustrate how to write your tests in an understandable manner. While this blogpost does not reflect what is right / wrong with running tests against a database it does show with a measurable quantity the impact of writing / reading to the database