12
votes

I'm writing RSpec tests and I have come to a point where I am not reading the same opinions on different websites. The directory structure for RSpec is clear when we are dealing with spec/controllers and spec/models directories, but the conflicting information I am getting deals with testing views.

I would like to just put these tests in a spec/integration/ directory, but I have read that it's supposed to be under spec/integration, but another book says spec/requests. Does this matter?

To further complicate the situation, I have read conflicting information on naming the actual file names of the tests! For example, if I had a controller/model/view directory called 'people' (I i use haml), I should name the files like this:

spec/integration/people.html.haml_spec.rb

However, another book suggests this:

spec/requests/people_spec.rb

I would like a little explanation of naming conventions within RSpec and WHY I should name the view tests specific names, as well as whether or not it matters to put them under spec/integration or spec/requests. I feel like I'm going with the wind here.

Any help is greatly appreciated.

2

2 Answers

12
votes

Check the dates of the books and the versions of RSpec for which they were written. The naming structure has changed slightly over time.

According to the docs for rspec-rails, request specs can go in spec/requests, spec/api, or spec/integration. I prefer to put request specs in spec/requests.

To make things more interesting, if you are using Capybara with rspec-rails, it will work with spec/requests for Capybara 1.x, and spec/features for Capybara 2.

As to individual spec file names, when there is a specific class under test, like a Rails model, you should use an analogous spec file name:

app/models/user.rb -> spec/models/user_spec.rb

View specs should use the template name:

app/views/users/index.html.erb -> spec/views/users/index.html.erb_spec.rb

Namespaced models should include the namespace in the spec file path:

app/models/admin/user.rb -> spec/models/admin/user_spec.rb

The RSpec scaffold generator is a good guide for showing where these specs belong.

When there is no specific class under test, as is the case with request specs, IMHO you should feel free to use a name that describes the thing being tested. E.g. spec/requests/place_an_order_spec.rb.

1
votes

The files read by the rspec gem are simply those that end in _spec.rb and that are anywhere in the hierarchy below the spec folder as long as the top of the hierarchy is an alpha-numeric word (that is, files under a folder named spec/##/ would not be considered in generating specs.) This is the relevant line of code that implements this, in /gems/rspec-rails-2.14.1/lib/rspec/rails/tasks/rspec.rake:

namespace :spec do
  types = begin
    dirs = Dir['./spec/**/*_spec.rb'].
           map { |f| g=f.sub(/^\.\/(spec\/\w+)\/.*/, '\\1') ; puts ">>> Found #{g}."; g }.
           uniq.
           select { |f| File.directory?(f) }
    Hash[dirs.map { |d| [d.split('/').last, d] }]
  end

So all the text in the filename previous to _spec.rb is a convention - it doesn't change how Rails processes the files.

I'd have to read through the code a lot more to figure out what the significance of each folder name, under spec, is - it gets passed through to the Rake spec task that's created, so it's being used for something but I don't know what.