If you’ve ever wanted to poke and prod your Rails app through the entire stack without firing up a web browser, Rails 1.1 just made it easy. You can now use the app object from within script/console to get access to the ActionController::Integration::Session instance. And that means you can drive your app just like an integration test.

Let’s take an app for a quick test drive:

Loading development environment.

>> app.class
=> ActionController::Integration::Session

Going to Fred’s home page should redirect him to a login page:

>> app.get "/home"
=> 302

>> app.controller.params
=> {"action"=>"home", "controller"=>"accounts"}

>> app.response.redirect_url
=> "http://www.example.com/login"

Sure enough. Now let’s log ol’ Fred in:

>> app.post "/login", :user => {:login => 'fred', :password => 'flintstone'}
=> 302

>> app.session[:user_id]
=> 1

>> app.cookies
=> {"shopper_id"=>"176f8c0bf450f772f80f85ba22861504"}

Since Fred originally intended to hit his Home page, now that he’s logged in he should have landed up back on his Home page with a cheery greeting:

>> app.response.redirect_url
=> "http://www.example.com/home"

>> app.flash
=> {:notice=>"Welcome Back, fred!"}

Being an avid shopper, Fred can’t help but buy something. In this case, we use an asynchronous (yes, that’s Ajaxy) request:

>> app.xml_http_request "/store/add_to_cart", :id => 1
=> 200

>> app.assigns(:new_item)
=> #<CartItem:0x23d5f24 @product=#<Product:0x23d5efc
@attributes={"name"=>"Lunchbox" ...

This isn’t a regression testing tool, mind you. But it’s quite handy as an experiential interface to your app. And when you’re satisfied with the results, you can (and should!) write an automated integration test. The app instance used above is the same object that’s used during integration testing, but it’s implicit in the integration test. So you could turn around and convert the session above into something like the following:

require "#{File.dirname(__FILE__)}/../test_helper"

class ShoppingTest < ActionController::IntegrationTest

  fixtures :products

  def test_shopping
     get "/home"
     is_redirected_to "login"

     post "/login", 
       :user => {:login => 'fred', :password => 'flintstone'}
     is_redirected_to "home"
     post "/store/add_to_cart", :id => products(:lunchbox).id
     assert_response :success
     assert_not_nil assigns(:new_item)


  def is_redirected_to(template)
    assert_response :redirect
    assert_response :success
    assert_template template


Then you’d run it by simply typing:

rake test:integration