views:

774

answers:

2

Every time this step

Given /blah.../
    ...
    cart = session[:cart] ||= Cart.new
    ...
end

runs in a scenario, it creates a new cart as opposed to (starting from the second call) picking one up from the session. Anyone knows how to fix that?

I am on rails 2.2.2, cucumber 0.3.98, webrat 0.4.4

P.S. Possibly adding selenium into the circuit might help. But, since a preliminary attempt to get cucumber/selenuim working didn't succeed, I thought a little call for wisdom was in order before standing up against Dark Force of 'things that never just work'

A: 

In the way Webrat simulates a browser for testing your application you don't get any session support. This means that storing information in the session hash works for the current request, but the information doesn't get stored for subsequent requests.

Depending on a session which is created in previous scenario's isn't really a good way of testing. Each scenario you create should be self-containing. In the 'Given' steps you should make sure the prerequisites for the steps are met, if this includes setting up a shopping cart, you should do so.

Another tip: you can concatenate several Given/When/Then blocks in one scenario if you want to test further once you made some assertions:

Scenario: Foobar
Given the cart exists
When I click checkout
Then I should see '$100'
When I click 'Pay'
Then I should see 'Paid'

It seems tempting to concatenate all you scenario's in one, but this makes it harder to debug your application once the scenario fails. I prefer a lot of short scenarios!

Edwin V.
> Depending on a session which is created in previous scenario's isn't really a good way of testing Agreed. That is why it depends (tries to) on a session created in a previous step. > In the 'Given' steps you should make sure the prerequisites for the steps are met, if this includes setting up a shopping cart, you should do so. That was exactly what I was trying to achieve.
artemave
A: 

There is not really a clean way to do this because cucumber is simulating your browser. All your browsers knows of sessions is an opaque cookie that rails politely turns into a hash for each request.

The best solution is to make your application create a cart in the usual fashion, that is logging in, selection a product and adding it to the cart. This can all be done in one step, but I would do it in separate steps because it is reusable and also because it follows more closely what your user is likely to have done.

Scenario: Foobar
  Given I am a logged in user
  And I add a "wizbang" to my cart
  When I click checkout
  Then I should see '$100'
  When I click 'Pay'
  Then I should see 'Paid'

If the problem is maintaining information between steps, you can use IVars that will persist through the whole senario. ie:

@cart ||= Cart.new
John F. Miller
I don't get it. Cucumber certainly retains (emulates? whatever...) session between steps. Otherwise 'wizbang' would disappear from cart by the time of checkout. So why not to make it accessible? Just like in plain old Test::Unit::TestCase
artemave
Problem with going thru links in steps properly is that webrat is quite limited in navigating though page elements. Say, you have a list of two products (bread and butter) with 'add to cart' button in each line. Now try to add 2 breads and 3 butters. Good luck with webrat
artemave
So I plugged in selenium where there they have xpath selectors (very helpful!). Selenium is by all means a way closer to reality. But a way way slower... Everything comes at a price!
artemave
To answer your first comment: Webrat retains cookies between request, just like your browser. Sessions are a fiction of Rails. Every request it looks at the cookie it is sent and uses it to reproduce the original session hash. By default Rails compresses and encrypts a marshal dump of the session hash and stuffs it it the cookie, but it can also pull it out of the database or a file or memcache, and just store the a "key" token in the cookie. All webrat can do is return the same cookie it was given.
John F. Miller
To answer your second comment: Webrat uses nokogiri for all its parsing. nokigiri has both CSS3 and XPath selectors, and is IMHO, the more useful tool for testing. The default cucumber steps don't give you a lot of power when choosing links, but if you use nokogiri to find your button and pass it's selector to Webrat, it can do the right thing as well. If you are having trouble getting this to work ask another question and I will try to give a fuller answer in more then 500 chars.
John F. Miller
That makes a lot of sense. It is a shame I couldn't find any documentation on it.
artemave
John, here is 'another question' http://stackoverflow.com/questions/1476604/selecting-page-elements-with-webrat
artemave