RSpec 3 not including support files in spec/support

So today I started a new project (this time I’m trying out Rails Composer) but after an error half way through running the template generator I started about configuring my test suite (RSpec, Capybara and Guard).

Unfortunately for some reason my spec/support directory wasn’t being included in my load path. This was strange as there was indeed the line:

Dir[Rails.root.join(“spec/support/**/*.rb”)].each { |f| require f }

in my rails_helper.rb file.

Anyway after sinking nearly an hour of frantic trouble shooting I figured that the for some reason you now have to use the --require option in ~/.rspec to include the rails_helper.rb file.

My ~/.rspec now looks something like this:

–color
–format documentation
#–warnings
#These need to be included now aparently
–require rails_helper
–require spec_helper

Shave time off you’re tests with a conditional “Watch” using guard-rspec

OK so I didn’t get chance to finish the last post due to exams and by the time I came back to finish it I couldn’t remember all the steps I took clearly enough to guarantee success. I promise the next time I integrate a payment method, I’ll detail the process completely. That said it should be a lot easier from this point on as now has arrived in the UK.

Just for a bit of context on this much shorter post. I started my current project in Rails 3 but whilst doing (yet more) exams rails 4 was released. I had been meaning to get in to TDD for my rails project and transferring the project over to rails 4 seemed like the perfect time to do so.

So far everything is going well and I’d heartily recommend anybody interested in rails to find some testing tools that suit you and learn them as soon as possible. the learning curve associated with them is far outweighed by the security of knowing that your app is working and that whenever you make any changes to your code you can make sure you haven’t broken anything. on top of that using TDD works like having a check-list and documentation on your side.

Anyway, I digress.

I just wanted to share a bit of a snippet I have just implemented which allows me to break up tests conditionally. The project that I was in the middle of making was very large and some of the spec files were quite big. though you can use your own testing strategy (some people like to keep all of there tests in one file, I prefer to split them up for efficiency), I prefer to use rspeccapybaraguard and spork.

Rather than testing models views and controllers, I test models with low level interactions and assert facts about state. Once I am happy that they are in order, I test controllers and views with capybara feature specs. I have guard in the background watching for file changes and triggering tests when needed, I have a spork server running so that my application doesn’t need to load every time I make a change. this was great to start with as there were not many specs but over time certain parts of my testing strategy were really taking ages and so if I changed one line of code I was waiting for around 3 minutes for all of the feature specs to run. here is the solution I came up with.

Conditional watch statements in guardfile.rb

these are the suggested lines for capybara feature specs:


watch(%r{^app/views/(.+)/.*\.(erb|haml)$})          { |m| "spec/features/" }
watch(%r{^app/controllers/(.+)_(controller)\.rb$})  { |m| "spec/features/" }

What I needed to do was to conditionally split these up so that only relevant specs were triggered when editing a view or controller. If you are using spork and respec, you should have a block that looks something like:


guard :rspec, :cli => "--drb" do

at the top of this block, I defined a method called capybara_specs like so:


def capybara_specs
    watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) do |params|
      case params[1]
      when "manage_content"
        "spec/features/admin_features/manage_content"
      else
        "spec/features/"
      end
    end
  end

As you can probably guess, this basically watches all the view files and then based on the calling controller runs a subset of my feature specs (it does require that you restructure your feature specs which may also mean you need to make some slight changes throughout, but that’s out of the scope of this post).

But that’s only watching views! I hear you cry, well a simple bit of refactoring the code and I’m sure you can figure out how to change the method to include views and controllers, yeah it may put slightly more overhead on the test suite but when you get a big test suite running, that over head may be an extra second, but it could shave literally minutes off your tests.

The best part is, that if you have a feature test that runs over multiple controllers, it’ll still get picked up and fall back to the original behaviour.

You’re welcome