oto brglez - tips for better tests
DESCRIPTION
Practical tips on how to improve your RSpec specs and test suites in general. Slides ware presented on Slovenian Ruby Meetup on March 2014.TRANSCRIPT
Tips for better testsOto Brglez / March 2014
otobrglez.opalab.com
#1 Describing methods?describe 'the authenticate method for User' dodescribe 'if the user is an admin' do
describe '.authenticate' dodescribe '#admin?' do
#2 Missing some context?it 'has 200 status code if logged in' do expect(response).to respond_with 200endit 'has 401 status code if not logged in' do expect(response).to respond_with 401end
context 'when logged in' do it { should respond_with 200 }endcontext 'when logged out' do it { should respond_with 401 }end
#3 Descriptions...it 'has 422 status code if an unexpected params will be added' do
context 'when not valid' do it { should respond_with 422 }end
#4 Who?it { expect(assigns('message')).to match /it was born in Maribor/ }it { expect(assigns('message').creator).to match /Ljubljana/ }
subject { assigns('message') }it { should match /it was born in Ljubljana/ }
#5 Be lazy...describe '#type_id' do before { @resource = FactoryGirl.create :device } before { @type = Type.find @resource.type_id }
it 'sets the type_id field' do expect(@resource.type_id).to equal(@type.id) endend
describe '#type_id' do let(:resource) { FactoryGirl.create :device } let(:type) { Type.find resource.type_id }
it 'sets the type_id field' do expect(resource.type_id).to equal(type.id) endend
#6 See this a lot?user = User.create( first_name: 'Oto', last_name: 'Brglez', country: 'Slovenia', email: '[email protected]' , active: true)
user = FactoryGirl.create :user
#7 Can’t remember...lambda { model.save! }.to raise_error Mongoid::Errors::DocumentNotFound
expect { model.save! }.to raise_error Mongoid::Errors::DocumentNotFound
#8 But it works just like...describe 'GET /devices' do let!(:resource) { FactoryGirl .create :device, created_from : user.id } let(:uri) { '/devices' }
context 'when shows all resources' do let!(:not_owned ) { FactoryGirl .create factory }
it 'shows all owned resources' do page.driver.get uri expect(page.status_code).to be( 200) contains_owned_resource resource does_not_contain_resource not_owned end end
describe '?start=:uri' do it 'shows the next page' do page.driver.get uri, start : resource.uri expect(page.status_code).to be( 200) contains_resource resources.first expect(page).to_not have_content resource.id.to_s end endend
describe 'GET /devices' do
let!(:resource) { FactoryGirl.create :device } let(:uri) { '/devices' }
it_behaves_like 'a listable resource' it_behaves_like 'a paginable resource' it_behaves_like 'a searchable resource' it_behaves_like 'a filterable list'end
#9 Me, you, him? When?it 'should not change timings' do consumption.occur_at.should == valid.occur_atend
it 'does not change timings' do expect(consumption.occur_at).to equal(valid.occur_at)end
#10 I don’t have the time...rspec spec/models/user_spec.rb
1. bundle exec guard # or zeus, spork, spin
2. rspec spec/models/user_spec.rb -l 10
3. rspec --no-drb spec/models/*
#11 External is slow. :/require 'open-uri'file = open('http://otobrglez.opalab.com')contents = file.readputs contents
context "blog" do let(:uri) { 'http://otobrglez.opalab.com' } before { stub_request(:get, uri).to_return(status: 200, body: fixture('home.html')) } it "gets home page" do # magic here... expect(page).to have_content 'Oto Brglez' endend
What else?1. Use formatters
2. Test what you see
3. Test edge-cases
4. Learn how to mock/stub
5. Decuple your code
6. Think about CI
7. Keep your tests fast and readable
8. Learn from OS projects
ThanksInspired by betterspecs.org and nasty test suites.
Read my blog; and be ql.
- Oto