Ian Truslove / ian.truslove@nsidc.org
26 Feb 2013
I didn't invent this.
I don't think Alister Scott did either, but it's from his blog article that I picked up the technique.
Cucumber is a tool for running automated acceptance tests written in a behavior driven development (BDD) stylewikipedia
Use the Page Object pattern to better organize your code
A Page Object is an object that represents a web page
...or a service endpoint, or anything else
Feature: Smoke tests for metadata feeds harvested by NSIDC's GI-Cat
Scenario Outline: Check Feed Endpoints
Given that <Datacenter>'s feed URL is <URL>
When I access the feed
Then the response code will be a 200
And the number of results will be greater than zero
Scenarios: Feed Endpoints
| Datacenter | URL |
| NSIDC | http://nsidc.org/oai/provider |
| CISL | http://www.aoncadis.org/oai/ |
| NMI | http://access.met.no/metamod/oai |
| EOL | http://data.eol.ucar.edu/jedi/catalog |
require 'rubygems'
require 'net/http'
require 'open-uri'
require 'nokogiri'
Given /^the feed URL is (.*)$/ do |url|
@url = url
end
When /^I access the feed$/ do
@results = Nokogiri::XML(open("#{@url}"))
end
Then /^the response code will be a 200$/ do
resp = Net::HTTP.get_response(URI.parse(@url))
resp.code.should == "200"
end
Then /^the number of results will be equal to (.*)$/ do |count|
@results.xpath('//oai:record', {
"oai" => "http://www.openarchives.org/OAI/2.0/"}
).count.should == count.to_i
end
Given /^that (.*)'s feed URL is (.*)$/ do |datacenter, url|
@feed = (datacenter == "EOL" ? Thredds.new(url) : Dif.new(url))
end
When /^I access the feed$/ do
@feed.access_feed
end
Then /^the response code will be a 200$/ do
@feed.response_code.should == "200"
end
Then /^the number of results will be greater than zero$/ do
@feed.num_records.should > 0
end
require 'net/http'
require 'open-uri'
require 'nokogiri'
class Feed
def initialize(url)
@base_url = url.sub(/\/+$/, '') # strip trailing slashes
end
def access_feed
@results = Nokogiri::XML(open("#{@base_url}"))
end
def response_code
resp = Net::HTTP.get_response(URI.parse(@base_url))
resp.code
end
def get_records(element, namespace)
@results.xpath("//#{element}", namespace)
end
end
Given /^I am on the search page$/ do
url = ENV["URL"] || "http://integration.nsidc.org/acadis/search"
@search_page = AcadisSearchPage.new(url, @browser)
end
When /^I search for "(.*?)"$/ do |search_term|
@search_page.search_for(search_term)
end
When /^I click the next page button$/ do
@search_page.click_next_page_button
end
Then /^there should be some search results$/ do
@search_page.results_count.should >= 1
end
Then /^all search results should have a button$/ do
@search_page.count_data_buttons.should == @search_page.results_count
end
Then /^the page number should be "(.*?)"$/ do |page_number|
@search_page.current_page_number.should == page_number
end
(chopped for brevity)
require "watir-webdriver"
class AcadisSearchPage
def initialize(url, browser=nil)
@url = url
@browser = browser or Watir::Browser.new
@browser.goto @url
wait_until_loading_is_complete
end
def wait_until_loading_is_complete
@browser.div(:id => 'loading-results').wait_while_present
@browser.span(:class, 'results-count').wait_until_present
sleep 0.5
end
def search_for(term)
@browser.text_field(:id, 'keyword').set term
@browser.button(:id, 'search-now').click
wait_until_loading_is_complete
@results_history.push AcadisSearchResultsPage.new(@browser)
end
def click_next_page_button
@browser.a(:class, 'button next').click
wait_until_loading_is_complete
@results_history.push AcadisSearchResultsPage.new(@browser)
end
# Accessors
def total_results_count
last_results_page.total_num_results
end
def current_page_number
last_results_page.current_page_number
end
def first_result_date_modified
last_results_page.first_date_modified
end
end
There's no magic
Basic OO, Interface Segregation Principle