Webrat with RSpec, no Cucumber
For the impatient: install webrat as from installation instructions and then add this section to your spec_helper.rb that lets you create webrat specs in spec/integration folder:
defined_description.instance_eval do
self
end
end
super(defined_description)
end
Spec::Example::ExampleGroupFactory.register(:integration, self)
end
end
There is plenty of examples of usage of Webrat alone inside test/integration but very few using RSpec. “No big deal” I thought, it must be just as simple as from test/integration. Why I should skip Cucumber? I hope to use Cucumber in the next projects, but I don’t have a real customer for the internal app I’m writing right now and it doesn’t make a lot sense to be so english-like for requirements. So after installing RSpec[Rails] 1.2.4 on Rails 2.3.2 and scaffolded some examples with “./script/generate rspec_scaffold post title:string body:text published:boolean” I created the following webrat-enabled view spec in spec/views/verify_posts_webrat_spec.rb:
visit posts_url
assert_contain "Listing posts"
end
end
and with the following spec_helper setup:
1 ||= 'test' 2 3 "/../config/environment" unless defined?(RAILS_ROOT) 4 5 6 7 Webrat.configure do |config| 8 config.mode = :rails 9 end 10 11 Spec::Runner.configure do |config| 12 config.use_transactional_fixtures = true 13 config.use_instantiated_fixtures = false 14 config.fixture_path = RAILS_ROOT + '/spec/fixtures/' 15 include Webrat::Methods 16 end 17
which gives a sad “undefined method `https!’ for #Spec::Rails::Example::ViewExampleGroup::Subclass_1:0x237e5f4”. Notice line 7-9 and 15 of the spec_helper, those are the correct settings I think. I couldn’t find any reason why this shouldn’t work and I try to move the spec into the controllers or models folders just to be sure. But nothing. I gave up but the following day I thought that if I had to make a choice about the position of webrat based specs that would be in the spec/integration folder. So I decided to create a new RSpec example group so that whatever happens to be in the integration folder is associated with a specfic class that I can control. So I added the following to spec_helper:
1 ||= 'test' 2 3 "/../config/environment" unless defined?(RAILS_ROOT) 4 5 6 7 Webrat.configure do |config| 8 config.mode = :rails 9 end 10 11 Spec::Runner.configure do |config| 12 config.use_transactional_fixtures = true 13 config.use_instantiated_fixtures = false 14 config.fixture_path = RAILS_ROOT + '/spec/fixtures/' 15 end 16 17 18 19 20 21 defined_description.instance_eval do 22 23 self 24 end 25 end 26 27 super(defined_description) 28 end 29 30 Spec::Example::ExampleGroupFactory.register(:integration, self) 31 end 32 end
and moved verify_posts_webrat_spec.rb to spec/integration et voila’, green bars. A few things to notice:
- Line 17: inheriting from ActionController::IntegrationTest brings in all the Rails testing integration goodness
- Line 20-28: this constructor definition is the trick necessary to intercept the instance of ExampleProxy and inject a “to_s” that returns the object itself. The trick is necessary because in ActionController::IntegrationTest the initializer is calling to_s on the incoming parameter expecting always a symbol (but we are passing an ExampleProxy instead)
If you try this solution, I’m pretty sure it won’t work for your combination of Rails/RSpec/Webrat/Environment version. Add a comment below so I can fix and update this post. Happy coding.
20090603 UPDATE: fixed for rspec 1.2.6. 7 months ago