Mike Vincent

use it or lose it.

xit for rspec

August 12th, 2007

Update: As of revision 2530 they have added the xit feature to rspec's trunk so the next release will find it baked in.

Edit: So no sooner do I make a post, and there's a new rspec release and I realize the way I thought the new 'pending' feature worked was mistaken. So I fixed the post to reflect what actually works.

Adam Keys asked if there was an 'xit' feature in rspec, citing that you could mark specs as pending or incomplete or some such by prefixing an 'x' to them with test/spec. I told him if he commented out the block in his spec rspec would denote it as incomplete. But It was pretty easy to implement for rspec by dropping this in your spec_helper.rb:
1
2
3
4
5
6
7

# Omit passing the specification's block into Example so it will be marked incomplete/pending
module Spec::DSL::BehaviourEval::ModuleMethods
  def xit(description=:__generate_description, opts={})
    examples << Spec::DSL::Example.new(description, opts)
  end
end
Or, even better, using Rspec's new pending feature:
1
2
3
4
5
6
7
8
9
10
11

# Using Rspec > 1.0.6 'pending' feature, which will raise an exception if the specification block does NOT fail
module Spec::DSL::BehaviourEval::ModuleMethods
  def xit(description=:__generate_description, opts={}, &block)
    examples << Spec::DSL::Example.new(description, opts) do
      pending "temporarily disabled" do
        instance_eval(&block)
      end
    end
  end
end
Quick contrived example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# roman_spec.rb
module Spec::DSL::BehaviourEval::ModuleMethods
  def xit(description=:__generate_description, opts={}, &block)
    examples << Spec::DSL::Example.new(description, opts) do
      pending "temporarily disabled" do
        instance_eval(&block)
      end
    end
  end
end

describe "The letter 'I'" do
  it "should be 'i' in lower case" do
    "I".downcase.should eql("i")
  end

  xit "should respond to :to_roman" do
    "I".should respond_to(:to_roman)
  end
end
Produces the following specdoc output
1
2
3
4
5
6
7
8
9
10
11

The letter 'I'
- should be 'i' in lower case
- should respond to :to_roman (PENDING: temporarily disabled)

Finished in 0.005163 seconds

2 examples, 0 failures, 1 pending

Pending:
The letter 'I' should respond to :to_roman (temporarily disabled)
If we later add the to_roman method to string, eg:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# roman_spec.rb
module Spec::DSL::BehaviourEval::ModuleMethods
  def xit(description=:__generate_description, opts={}, &block)
    examples << Spec::DSL::Example.new(description, opts) do
      pending "temporarily disabled" do
        instance_eval(&block)
      end
    end
  end
end

class String
  def to_roman
  end
end

describe "The letter 'I'" do
  it "should be 'i' in lower case" do
    "I".downcase.should eql("i")
  end

  xit "should respond to :to_roman" do
    "I".should respond_to(:to_roman)
  end
end
and rerun the spec, we get..
1
2
3
4
5
6
7
8
9
10
11
12
13

The letter 'I'
- should be 'i' in lower case
- should respond to :to_roman (ERROR - 1)

1)
'The letter 'I' should respond to :to_roman' FIXED
Expected pending 'temporarily disabled' to fail. No Error was raised.
/home/mike/projects/logn/roman_spec.rb:6:in `xit'

Finished in 0.005257 seconds

2 examples, 1 failure

It does have that annoyance that the error response is somewhat ambiguous because it's the xit method that is failing. It would be nice to know the line number, etc for the pending specs.

Sorry, comments are closed for this article.

Mike Vincent uses the Shay theme, and is Powered by Mephisto