RSpec2: How to avoid an example run when previous failed

Is there a way not to execute an example when another one fails? I want
to minimize failure noises in cases when, say, one spec checks that an
array has an expected number of elements while the others drill down on
a specific element. However, when there’s a wrong number of elements in
the first place, other failures are just noise.

Consider the following spec:

1 class Sample
2 attr_reader :items
3 def initialize(number)
4 @items = (1 … number).map { |_item|
5 Struct.new(:name).new(“ITEM:#{_item}”)
6 }
7 end
8 end
9
10 describe Sample, “when creating 2 named items” do
11 let(:items) { Sample.new(2).items }
12 subject { items }
13
14 it { should have(2).entries }
15
16 context “first item” do
17 subject { items.first }
18 its(:name) { should == “ITEM:1” }
19 end
20
21 context “last item” do
22 subject { items.last }
23 its(:name) { should == “ITEM:2” }
24 end
25 end

When run, it produces the following:

$ rspec -fd sample_spec.rb

Sample when creating 2 named items
should have 2 entries
first item
name
should == “ITEM:1”
last item
name
should == “ITEM:2”

Finished in 0.00158 seconds
3 examples, 0 failures

Everything is great until I have an “innocent” bug in the range in line
4, like “(1 … number)” instead of “(1 … number)”. In which case the
above command will produce this:

$ rspec -fd sample_spec.rb

Sample when creating 2 named items
should have 2 entries (FAILED - 1)
first item
name
should == “ITEM:1”
last item
name
should == “ITEM:2” (FAILED - 2)

Failures:

  1. Sample when creating 2 named items
    Failure/Error: it { should have(2).entries }
    expected 2 entries, got 1

    ./sample_spec.rb:14

  2. Sample when creating 2 named items last item name
    Failure/Error: its(:name) { should == “ITEM:2” }
    expected: “ITEM:2”,
    got: “ITEM:1” (using ==)

    ./sample_spec.rb:23

Finished in 0.00167 seconds
3 examples, 2 failures

In the above, failure 2) is a direct result of failure 1) and would be
great to avoided if possible. Especially if I want to spec much more
stuff there with much more noise being displayed.

Thank you for your help,
Gennady.

On 10 Dec 2010, at 20:25, Gennady B. wrote:

7 end
18 its(:name) { should == “ITEM:1” }
$ rspec -fd sample_spec.rb
Finished in 0.00158 seconds
should == “ITEM:1”

Thank you for your help,
Gennady.

I don’t consider that noise, I consider it useful clues as to what’s
wrong.

cheers,
Matt

[email protected]
07974 430184

On Dec 11, 2010, at 5:14 AM, Matt W. wrote:

4 @items = (1 … number).map { |_item|
15

name
should have 2 entries (FAILED - 1)
Failure/Error: it { should have(2).entries }
3 examples, 2 failures

In the above, failure 2) is a direct result of failure 1) and would be great to
avoided if possible. Especially if I want to spec much more stuff there with much
more noise being displayed.

Thank you for your help,
Gennady.

I don’t consider that noise, I consider it useful clues as to what’s wrong.

cheers,
Matt

Matt, thanks a lot for your opinion. Yet I feel I haven’t properly
expressed myself. I agree with you that normally one wants as much
independent failure reports as a tool can generate. However, sometimes
when you write specs you know for sure that if a test for the number
of array elements fails, the subsequent tests of individual elements
are destined to fail with “weird” messages, like:

NoMethodError: undefined method `do_something’ for nil:NilClass

And they repeat again and again for all elements you test, scrolling
the most relevant first failure off the screen (say, in autotest
output). Not cool.

Anyways, I discovered recently introduced RSpec ability to fast fail
– controllable by config parameter “fail_fast”, or command line
option “–fail-fast”. Apparently I am not the only one who was bitten
by this :wink:

It helps with my issues at hand, however I would prefer more granular
ability to, say, put a number of specs into fail_fast{} kind of block
thus selectively indicating such cases.

Gennady.