Freelancing Gods 2014

God
02 Sep 2011

Combustion - Better Rails Engine Testing

I spent a good part of last month writing my first Rails engine – although it’s not yet released and for a client, so I won’t talk about that too much here.

Very quickly in the development process, I was looking around on how to test Rails engines. It seemed that, beyond some basic unit tests, having a full Rails application within your test or spec directory was the accepted approach for integration testing.

That felt kludgy and bloated to me, so I decided to try something a little different.

The end goal was full stack testing in a clear and manageable fashion – writing specs within my spec directory, not a bundled Rails app’s spec directory. Capybara’s DSL would be nice as well.

This, of course, meant having a Rails application to test through – but it turns out you can get away without the vast majority of files that Rails generates for you. Indeed, the one file a Rails app expects is config/database.yml – and that’s only if you have ActiveRecord in play.

Enter Combustion – my minimal Rails app-as-a-gem for testing engines, with smart defaults for your standard Rails settings.

Setting It Up

A basic setup is as follows:

  • Add the gem to your gemspec or Gemfile.
  • Run the generator in your engine’s directory to get a small Rails app stub created: combust (or bundle exec combust if you’re referencing the git repository instead).
  • Add Combustion.initialize! to your spec/spec_helper.rb (currently only RSpec is supported, but shouldn’t be hard to patch for TestUnit et al).

Here’s a sample spec_helper, mixing in Capybara as well:

require 'rubygems'
require 'bundler'

Bundler.require :default, :development

require 'capybara/rspec'

Combustion.initialize!

require 'rspec/rails'
require 'capybara/rails'

RSpec.configure do |config|
  config.use_transactional_fixtures = true
end

Putting It To Work

Firstly, you’ll want to make sure you’re using your engine within the test Rails application. The generator has likely added the hooks we need for this. If you’re adding routes, then edit spec/internal/config/routes.rb. If you’re dealing with models, make sure you add the tables to spec/internal/db/schema.rb. The README covers this a bit more detail.

And then, get stuck into your specs. Here’s a really simple example:

# spec/controllers/users_controller_spec.rb
require 'spec_helper'

describe UsersController do
  describe '#new' do
    it "runs successfully" do
      get :new

      response.should be_success
    end
  end
end

Or, using Capybara for integration:

# spec/acceptance/visitors_can_sign_up_spec.rb
require 'spec_helper'

describe 'authentication process' do
  it 'allows a visitor to sign up' do
    visit '/'

    click_link 'Sign Up'
    fill_in 'Name',     :with => 'Pat Allan'
    fill_in 'Email',    :with => 'pat@no-spam-please.com'
    fill_in 'Password', :with => 'chunkybacon'
    click_button 'Sign Up'

    page.should have_content('Sign Out')
  end
end

And that’s really the core of it. Write the specs you need to test your engine within the context of a full Rails application. If you need models, controllers or views in the internal application to fully test out your engine, then add them to the appropriate location within spec/internal – but only add what’s necessary.

Rack It Up

Oh, and one of my favourite little helpers is this: Combustion’s generator adds a config.ru file to your engine, which means you can fire up your test application in the browser – just run rackup and visit http://localhost:9292.

Caveats

As already mentioned, Combustion is built with RSpec in mind – but I will happily accept patches for TestUnit as well. Same for Cucumber – should work in theory, but I’m yet to try it.

It’s also written for Rails 3.1 – it may work with Rails 3.0 with some patches, but I very much doubt it’ll play nicely with anything before that. Still, feel free to investigate.

And it’s possible that this could be useful for integration testing for libraries that aren’t engines. If you want to try that, I’d love to hear how it goes.

Final Notes

So, where do we stand?

  • You can test your engine within a full Rails stack, without a full Rails app.
  • You only add what you need to your Rails app stub (that lives in spec/internal).
  • Your testing code is DRYer and easier to maintain.
  • You can use standard RSpec and Capybara helpers for integration testing.
  • You can view your test application via Rack.

I’m not the first to come up with this idea – after I had finished Combustion, it was pointed out to me that Kaminari’s test suite does a similar thing (just not extracted out into a separate library). It wouldn’t surprise me if others have done the same – but in my searching, I kept coming across well-known libraries with full Rails apps in their test or spec directories.

If you think Combustion could suit your engine, please give it a spin – I’d love to have others kick the tires and ensure it works in a wider set of situations. Patches and feedback are most definitely welcome.

Comments

24 responses to this article

29 Jul 2014
comptoir quartz ville de Quebec said:

I believe this is among the most vital information for me.
And i am happy reading your article. But should commentary on some general things, The site style is ideal, the articles is really great :
D. Just right job, cheers

06 Jun 2014
youtube british voiceover animals funny said:

My brother recommended I might like this website. He was totally right.
This post actually mace my day. You cann’t imagine simply how much time I had spent for
this information! Thanks!

06 Jun 2014
mini desserts recipes said:

And it is an art that is not part of the main stream of brewing.
To be able to starve the yeast, you need to eliminate sugars as much as you can. A
food recipe that always been part for being a Filipino.

03 Jul 2014
findyourflirt.net said:

With havin so much written content do you ever run into any issues of plagorism or copyright violation? My blog
has a lot of exclusive content I’ve either written myself or outsourced but it looks
like a lot of it is popping it up all over the web
without my authorization. Do you know any ways to help protect
against content from being stolen? I’d definitely appreciate it.

05 Jul 2014
black magic spells that work said:

Excellent items from you, man. I’ve be mindful your stuff prior to and
you are simply extremely wonderful. I really like what you’ve bought right here, really like what you
are stating and the way wherein you say it.
You are making it enjoyable and you still take care of to keep it wise.
I can’t wait to learn far more from you. That is really a terrific
website.

03 Aug 2014
comptoir en quartz said:

Hi to all, the contents existing at this web page are in fact remarkable
for people knowledge, well, keep up the nice work fellows.

15 Aug 2014
stanley steemer carpet cleaner Vancouver said:

I’m not that much of a online reader to be honest but your blogs really nice, keep it up!
I’ll go ahead and bookmark your website to come back later on. Cheers

07 Sep 2011
José Valim said:

Hey Pat!

I am likely the main responsible for the practice of bundling Rails apps inside gems. It started with “Crafting Rails Applications” and the target was to make very clear what is happening when you boot your application and when config/application.rb and config/environment.rb are loaded (it is explained with a dummy app right in the first chapter!).

That said, I think combustion provides a nice alternative to the problem for those who want completely hide away the Rails initialization process.

Just one note: I disagree that bundling a Rails app is brittle, it does exactly the same as combution, except that it does it explicitly. However, I agree that bundling the whole Rails app can be considered “bloat” but you really don’t need all those files. You can get away by keeping only config/{boot,application,environment}.rb (plus the database.yml if you are using AR), which is basically what combustion defines.

07 Sep 2011
pat said:

Hi José

I realise there’s not a huge difference in the two approaches (and I had someone point out you’d made the full-app suggestion in your book halfway through developing Combustion – I should probably get myself a copy to read!).

I didn’t actually intend for Combustion to end up being a full Rails app, I just wanted full-stack testing with as little code as possible – and just added things bit by bit until it worked.

And yeah, brittle isn’t quite the right description – I got a little carried away.

08 Sep 2011
Dan Croak said:

Very cool, Pat. Take a look at http://github.com/thoughtbot/diesel and http://github.com/thoughtbot/appraisal for some other ideas about testing engines and testing different versions of Rails, respectively.

08 Sep 2011
pat said:

Very cool, thanks for sharing those Dan – I’m surprised I never found diesel in my searching. Appraisal reminds me of a gem I wrote some time ago for the same purpose – Ginger – https://github.com/freelancing-god/ginger – but that was before Bundler, and Appraisal seems a much cleaner approach now.

19 Sep 2011
Millisami said:

Nice setup to test the engine.
But there is built in engine generator in Rails 3.1 with the following command.

rails plugin new my_engine —mountable

This command also generates a dummy rails app to test against. Its described in Ryan Bigg’s Rails3InAction book. Though it generates the test setup for TestUnit, but its easy to tweak for RSpec too.

Did you build Combustion just to ease the setup or find anything with the built-in plugin generator?

19 Sep 2011
pat said:

I’ve not used the built-in engine/plugin generator in a long, long time (before engines existed) – Combustion was just built to make testing of engines simpler and DRYer.

It’s no surprise that the generator adds a dummy app, since that is the established approach for testing engines.

29 Jan 2013
Brad said:

New link to README: https://github.com/pat/combustion

29 Jan 2013
pat said:

Thanks Brad, just updated the post with the newer link.

09 Jul 2014
compagnie de déménagement said:

Hi! This is my first visit to your blog! We are a collection of volunteers and starting a new project
in a community in the same niche. Your blog provided us valuable information to work on. You have done a outstanding job!

09 Jul 2014
Jade said:

Most lucid dreaming techniques train the mind to:

Increase your dream intensity and dream recall
Become more self-aware in your daily life through meditation
Advance your visualization skills to enter dreams purposely
Habitually plan your dream content
Having regular lucid dreams will become a lifestyle. You will be
more successful in your efforts if you include these
techniques into your everyday habits. In the end, your
dreams reveal your thoughts, experiences and emotions from waking
reality.

That’s why just thinking about the best way to have lucid dreams could possibly produce your first lucid
dream tonight! The best way to Have Lucid Dreams with Head Power

Now, there is no guaranteed method of having a lucid dream tonight.
But there are many tried-and-tested techniques which may raise
your odds, even more so.

How to Have Lucid Dreams with Head Power: 5 Ways
Here are five basic techniques to kick start your lucid dream training:

14 Jun 2014
best itunes duplicate remover said:

So good to discover somebody with some special suggestions on this subject. realy thank you for beginning this up. this web site is something that is needed on the net, somebody with somewhat originality. valuable job for bringing something new towards the internet!

25 Jul 2014
comptoir quartz ou granit ville de Quebec said:

Remarkable issues here. I am very satisfied to see your
article. Thank you so much and I’m taking a look forward to touch you.
Will you kindly drop me a e-mail?

26 Jul 2014
blackbarry said:

I’m not that much of a online reader to be honest but your blogs really nice,
keep it up! I’ll try and save your website to come
back in the future. All the best

27 Jun 2014
electrical engineering jobs in san antonio texas said:

You could get your certificate in general electronic studies and
then apprentice for a refrigeration contractor for
a while before learning enough on the job to be re-certified as an expert in that specific field or you could spend some time in Refrigeration School of Electronics and upon graduation, you.
As you begin to learn about the dangers and prevention pertaining
to Fire, Water and Mold damage in your home or business, you will better understand what steps to take to
protect your family, employees, pets, personal belongings, business
records, equipment, building structure, landscaping and surrounding areas.
Also, in case of an electrical fire, you may not be able to claim from your
insurance company if you cannot produce proof that the expert you hired is indeed
certified and knowledgeable on the proper safety procedures.

28 Jun 2014
Jeannu Greene said:

Anisotropic selection anisotopische filtering is a process to hang in there. Textures clean and exquisite about an object ( 3 D wireframe ) It enhances the appearance of the feels as they may be simply at a terrific distance or if they lie on an inclined airplane in accordance with the ’ perspective ’ . Anisotropic selection is the video controller is an incredibly tough job Whatsapp . It will produce the sport more wonderful in look , but nonetheless, it is going to have damaging sway about the pace .

17 Aug 2014
comptoir quartz ou granit ville de Quebec said:

Hello! Do you know if they make any plugins to protect
against hackers? I’m kinda paranoid about losing everything I’ve worked hard on. Any tips?

21 Aug 2014
compagnie déménagement said:

This is really interesting, You are a very skilled blogger.

I’ve joined your rss feed and look forward to seeking
more of your magnificent post. Also, I’ve shared your website in my social networks!

Leave a Comment

Comments are formatted using Textile. Please be respectful of others when posting comments. Be nice.

RssSubscribe to the RSS feed

Related Links

Related Posts

About Freelancing Gods

Freelancing Gods is written by , who works on the web as a web developer in Melbourne, Australia, specialising in Ruby on Rails.

In case you're wondering what the likely content here will be about (besides code), keep in mind that Pat is passionate about the internet, music, politics, comedy, bringing people together, and making a difference. And pancakes.

His ego isn't as bad as you may think. Honest.

Here's more than you ever wanted to know.

Ruby on Rails Projects

Other Sites

Creative Commons Logo All original content on this site is available through a Creative Commons by-nc-sa licence.