elfs: (Default)
[personal profile] elfs

So, remember my comment about unit testing yesterday?  This is what it looks like today. Here’s the features page:

Feature: Login
  In order to use the system
  As a customer
  I want to log in

  Scenario: Access page
    Given I am at the login page
    Then the page title should be "SecretProject"

  Scenario: Log in
    When I log in as "username" password "redacted"
    Then the page title should be "SecretProject - Project List"

And here’s the steps:

Given 'I am at the login page' do
  @browser.goto @options[:address]
end

Then /the page title should be "(.*)"/ do |title|
  @browser.title.should == title
end

When /^I log in as "([^\"]*)" password "([^\"]*)"$/ do |arg1, arg2|
  @browser.text_field(:name, 'username').set(arg1)
  @browser.text_field(:name, 'password').set(arg2)
  @browser.button(:xpath, "//input[@value='Login']").click
end

While I’m not entirely sold on the COBOL-esque nature of the unit tests, I respect the way cucumber makes you think about what you’re doing and generate scenarios and codify the steps to fulfilling those scenarios, all the while working well within the context of things like WATIR, Matchy, and so forth.

This entry was automatically cross-posted from Elf's technical journal, ElfSternberg.com

Cucumber

Date: 2009-04-15 09:43 pm (UTC)
From: (Anonymous)
When you add this to the watircraft framework it gets even sweeter as you can define page files that define the object on the page. Yeah it's one more file to maintain, but now your steps can just use a logical name and you get things like
login_page.goto
login_page.userid = arg1 #btw why 'arg1'? why not 'userid'? that's what you expect to be there after all
login_page.login_button.click

in the page file the login button up there would be defined like this

element(:login_button) {browser.button(:value, 'Login')}

(speaking of which, :value is a supported identifier for buttons, so you can do it directly like above, no need to resort to xpath, which is not really terribly speedy)

So you get steps that read cleaner, but more importantly if some dev refactors the page and changes the id or name or whatever you used to identify the login button, you've got ONE thing to change in ONE place (the page file)

and one has to love the satisfaction of the little iterations you make when working with it, and watching stuff go from red to green.. strange how motivating that ends up being.

I agree a bit about the 'gherkin' syntax being a bit verbose, but it has a few big advantages.. namely ANYONE can read those scripts and see what they do, and more so, when a new feature is defined, you can get nearly anyone from the customer down to WRITE those things.. You might need to re-write em a bit to allow consistent step names (and hence re-use) but still, when they want a new feature, you can say 'here, use this format to tell how this is supposed to behave, and oh how it behaves in a failure scenario (bad username) etc. AND they get to do that using their domain specific language, which can carry all the way into the code. Which gets everyone talking the same language. There's a great little video, an interview with Dan North where he described the effect of this where a SME and a Programmer were having this discussion, neither really knew the other's world, but because they had common nomenclature, the dev was able to describe the behavior of a code object, and it exactly paralleled the behavior of the 'real world' object of the same name.

oh and the 'as a, I want, so that' doesn't have to be there in cucumber for it to work.. however I think it's valuable just to remind anyone reading the script 'who wants the feature', 'what we are doing' and 'what's the business value of doing it' all of which are important things to keep in mind.

--Chuck van der Linden

Re: Cucumber

Date: 2009-04-15 09:58 pm (UTC)
From: [identity profile] elfs.livejournal.com
Huh. I tried the :value fields and it didn't work for me. I went with the XPath because I found it in an example and I understand XPaths quite well.

At one point, I had a working reimplementation of FireWatir that used Python and MozRepl instead of Ruby and JSSH. It was primitive, but it worked, and I'm familiar enough with what FireWater 1.2 was doing internally to be very uncomfortable with it. It works, but the amount of intermingling of javascript and ruby was unholy and poorly documented. I did find the idea of keeping a browser-side cache of unique IDs for every object encountered intriguing, as well as allowing FireWatir to use that cache to re-access those objects rather than having to look them up again.

Anyway, these are just baby steps along the way to word domination and application development and design. One thing I've always had trouble with, at least up to FireWatir 1.2, was accessing objects obscured by layers and layers of javascript. We had that problem testing EXT-JS objects, which are dynamically generated and allocated unique names. Much of an EXT-JS app is written in Javascript, and writing Watir scripts that tracked what you were attempting to do was more difficult than it seemed. I hope 1.6 is better; it's what I'm running now. (I'm also using Dojo, so that makes a difference, too.)

Date: 2009-04-15 11:27 pm (UTC)
From: [identity profile] norikos-author.livejournal.com
I like the way it makes me approach my app entirely from the viewpoint of the UI. It means that if one of my scenarios becomes unwieldy, I probably need to think about the UI, because it'll be unwieldy for my users, too.

Profile

elfs: (Default)
Elf Sternberg

December 2025

S M T W T F S
 12345 6
78910111213
14151617181920
21222324252627
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 9th, 2026 02:40 am
Powered by Dreamwidth Studios