0

I've found a number of specs in our large codebase (some were even mine :) that forgot to include the .should and passed when they weren't testing anything.

e.g.

describe FooController, behavior_type: :controller do
  before do
    post :create, foo: { bar: 100 }
  end

  it "doesn't really test anything"
    response.body == "{\"result\":\"excellent\"}"
  end
end

This spec will pass regardless of the content of response.body because no RSpec matcher is used.

My question is: is there an RSpec option or a gem or something that would detect when a spec has completed without using any RSpec matchers and without calling pending and raise an error or mark the spec failed or some other status to alert the developer to the fact that the spec isn't doing what they probably think it is?

A followup question would be: shouldn't this be the default behaviour of RSpec? Is there a use case where you'd want to be able to write specs that use no matchers and don't call pending?

FWIW: I know RSpec has a --warnings option which may or may not print a warning about a scenario like this. In practice though for our main project it prints thousands of lines of irrelevant warnings, many of them about third party gems etc.

jim
  • 1,025
  • 12
  • 17

1 Answers1

1

There is no RSpec option or gem, but there are techniques described in https://github.com/rspec/rspec-core/issues/759, https://github.com/rspec/rspec-core/issues/404 and https://github.com/rspec/rspec-core/issues/740 for doing this yourself.

As for this being the default behavior, the current and past leaders of the RSpec team have argued against it in the aforementioned issue threads.

See issue 404 for a use case for not wanting a failure.

Peter Alfvin
  • 28,599
  • 8
  • 68
  • 106
  • Thanks, I like http://blog.sorah.jp/2012/12/17/rspec-warn-for-no-expectations though I'd prefer the spec outright failed. – jim Jan 07 '14 at 04:05
  • 1
    Note that although you can't set an expectation in an `after` clause that will cause an example failure, you _can_ raise an error in an after clause to cause an example failure. As such, you can replace the `puts` call in the code you reference with something like `raise "no expectations set"` – Peter Alfvin Jan 07 '14 at 04:19
  • Re default behaviour: the use case raised basically rested on a bug (rspec/rspec-expectations#59) that’s since been resolved. The main hindrance seems to have been concerns over how to implement this without coupling submodules together. I’d still prefer a test framework was safe by default for people new to TDD/RSpec than either of those things. – jim Jan 07 '14 at 04:34
  • 1
    That was my conclusion as well after a brief reading, but I didn't want to "get into it" in my response. Feel free to "join the conversion" on github. The team is great and I think really open to input. – Peter Alfvin Jan 07 '14 at 04:42