Gennady Bystritsky
2010-Dec-10 20:25 UTC
[rspec-users] 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.
Matt Wynne
2010-Dec-11 13:14 UTC
[rspec-users] RSpec2: How to avoid an example run when previous failed
On 10 Dec 2010, at 20:25, Gennady Bystritsky wrote:> 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.I don''t consider that noise, I consider it useful clues as to what''s wrong. cheers, Matt matt at mattwynne.net 07974 430184
Gennady Bystritsky
2010-Dec-13 02:58 UTC
[rspec-users] RSpec2: How to avoid an example run when previous failed
On Dec 11, 2010, at 5:14 AM, Matt Wynne wrote:> > On 10 Dec 2010, at 20:25, Gennady Bystritsky wrote: > >> 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. > > I don''t consider that noise, I consider it useful clues as to what''s wrong. > > cheers, > MattMatt, 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 ;-) 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.> > matt at mattwynne.net > 07974 430184 > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users