awesomeprogrammer.com

Sharing ideas

Solving problems

Gathering solutions

Exchanging thoughts

Ruby On Rails

PHP

Postgres

Debian & Ubuntu
jQuery & CSS

How Fast Your Tests Are? - Working With Rspec Outside Rails

Rails is a great framework, isn’t it? It’s ships with all those great tools witch are supposed to help you automatically test your application. So you write specs, you practice TDD, BDD or maybe DDD, but over time you may notice something – it’s getting painfully slow. You app grows, your test suite grows and suddenly testing isn’t anymore so much fun as it supposed to be. You feel like it’s slowing you down.

So you you start using spork, you setup all the guards – but that are just a bandages for a bigger problem. And the problem is – Rails is just slow. I mean not like it’s a slow in production – when you just need to boot up your app once and that’s it – it’s not such a big deal – but you do it constantly in development, and more gems you add (because gems are cool, right?) it takes more and more time. Sooner or later you will start skipping on your tests and you may end up in very bad place.

What I started to do lately with my legacy app I was talking before is – I started testing outside rails. Rails is slow, so let’s take everything you can outside rails and work with pure ruby and rspec. What I mean is you should try and extract some logic into separate classes/modules and test them without database and without framework. And you just need a place to start, let me give you a very simple example where I started.

I have heavily customized two redcarpet render engines – basically I was interested in two helper methods in my ApplicationHelper module. But god how I was frustrated with loading times – I have there some very annoying tests, because I’m asserting html output of markdown input – as I needed absolute certainty everything worked as it supposed to the last tag.

So here’s what my spec look like, I added some comments for clarity.

spec/modules/redcarpet/markdown_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# obviously we will need that
require 'redcarpet'

# I'm using cattr_accessor in one of my classes
require 'active_support/all'

# I'm also using strip_tags methods from action view helpers
require 'action_view/helpers/sanitize_helper'

# so I'm just including here all the methods of sanitize helper
include ActionView::Helpers::SanitizeHelper

# I want my app/ directory
app_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'app'))

# I want my application helper (even tho I'm interested in two methods here)
require "#{app_dir}/helpers/application_helper.rb"

# here I also included my custom redcarpet classes,
# but I will omit that in this example
# ...

# I will a class that I will test
# and include all helper methods
class MarkdownTest
  extend ApplicationHelper
end

# and later or it's just a 'regular' rspec as you know it
describe "Sugar Markdown" do
  subject { MarkdownTest.markdown(text) }

  context "handles flags" do
    let(:text){ "Titta :se: pa mig!" }
    it { should =~ /Titta <img src='\/img\/flags\/se.gif' title='Szwecja' \/> pa mig!/ }
  end

  # ...
end

And how fast is it? Pretty damn fast.

1
2
3
4
5
6
7
$ time rspec spec/modules/redcarpet/
Finished in 0.02648 seconds
16 examples, 0 failures

real  0m0.424s
user  0m0.388s
sys 0m0.032s

Now you don’t have to wait for rails to load just to test this one part of you app and you can do true TDD – your tests won’t slow you down anymore – they will drive you and your design. Of course you will still need to test models, controllers, do integrational tests, but I hope you see the point of testing without rails, and if you don’t – even so I encourage you to try it for yourself.

Comments