Недавняя статья про WebDriver напомнила мне немного рассказать об используемом нами комплексе для автоматизации тестирования Web-приложений.
Итак, в основе тестов лежит лежит связка RSpec + Watir WebDriver (для Rails-приложений более уместно будет взглянуть в сторону Capybara). При поддержке Bundler и локальных WebDrivers осуществляется лёгкая инсталляция на рабочем месте тестировщика (установить Ruby 1.9, Rubygems, Bundler, и выполнить bundle install
). Исходник Gemfile:
source :rubygems
gem "watir-webdriver", "~>0.6.1"
gem "rspec-core", "~> 2.0"
gem "rspec-expectations", "~> 2.0"
gem "rr", "~> 1.0"
gem "ci_reporter", "~> 1.7"
За счет гема ci_reporter осуществляется интеграция с Jenkins CI, а за счёт гема parallel_tests и Selenium Grid распараллеливание тестов (на сегодня parallel tests пока не используются в production).
Вот пример теста:
describe "FirstSite" do
before(:all) do
site! "first"
end
# returns true on success; otherwise false.
def login_as(data)
browser.rel_goto "/"
browser.title.should include 'example.com'
browser.text_field(:id => 'login').set data[:login]
browser.text_field(:id => 'password').set data[:password]
submit_button = browser.button(:id => 'submit')
submit_button.click
browser.url =~ %r{/welcome$}
end
def logout
browser.rel_goto "/"
browser.button(:id => 'logout').click
end
describe :login do
auth = fixture :auth
describe :successful do
after(:each) do
logout
end
auth.keys.select { |key| key.kind_of?(Symbol) }.each do |key|
next if key == :wrong
it "Logging in as #{key} should be OK" do
login_as(auth[key]).should be_true
end
end
end
describe :wrong do
it "Logging in with wrong credentials should fail" do
login_as(auth[:wrong]).should_not be_true
end
end
end
end
Тестируемые сайты и способ тестирования определяются в настройках.
---
production:
sites:
first: "http://staging.example.com"
webdriver:
hub: "http://192.168.13.6:8888/wd/hub"
test:
sites:
first: "http://staging.example.com"
webdriver:
hub: "http://192.168.13.6:8888/wd/hub"
development:
sites:
first: "localhost:5678"
webdriver:
local: true
За счёт задания переменных окружения WATIR_ENV и WATIR_BROWSER мы определяем окружение тестирования для конкретного прогона тестов.
Вся кастомизация выполняется двумя файлами. .rspec:
--format nested
--color
--require ./spec_helper.rb
spec_helper.rb:
require "rubygems"
require "bundler/setup"
require "yaml"
require "watir-webdriver"
require "rspec/core"
$LOAD_PATH << File.join(File.dirname(__FILE__), 'lib') # для различных библиотек.
module RegruHelpers
include Selenium
def site!(site)
RSpec.configuration.site = RSpec.configuration.sites[site]
end
def fixture(name)
RegruHelpers.symbolized YAML.load_file(
File.join(File.dirname(__FILE__), 'fixtures', "#{name}.yml")
)
end
def screenshot!(text = '')
directory = File.join(File.dirname(__FILE__), 'spec', 'screenshots')
file_name = "#{example.metadata.full_description}-#{text}.png"
file_path =File.join(directory, file_name)
browser.screenshot.save file_path
end
def save_html!(text = '')
directory = File.join(File.dirname(__FILE__), 'spec', 'html')
file_name = "#{example.metadata.full_description}-#{text}.html"
file_path =File.join(directory, file_name)
File.open(file_path, "w") do |f|
f.print browser.html
end
end
Watir::Browser.class_eval do
def rel_goto url
goto "#{RSpec.configuration.site}#{url}"
end
end
def browser
RSpec.configuration.browser ||= begin
local = RSpec.configuration.watir_settings[:webdriver][:local]
if local
Watir::Browser.new(RSpec.configuration.browser_type)
else
capabilities = WebDriver::Remote::Capabilities.send(
RSpec.configuration.browser_type,
:javascript_enabled => true
)
Watir::Browser.new(
:remote,
:url => RSpec.configuration.watir_settings[:webdriver][:hub],
:desired_capabilities => capabilities
)
end
end
end
end
RSpec.configure do |config|
config.mock_with :rr
config.add_setting :watir_settings
config.add_setting :browser_type
config.add_setting :sites
config.add_setting :site
config.add_setting :browser
config.include RegruHelpers
config.extend RegruHelpers
environment = ENV['WATIR_ENV'] || 'test'
browser_type = (ENV['WATIR_BROWSER'] || 'chrome').to_sym
watir_settings = RegruHelpers.symbolized YAML.load_file(File.join(File.dirname(__FILE__), 'settings.yml'))[environment]
RSpec.configuration.watir_settings = watir_settings
RSpec.configuration.sites = watir_settings[:sites]
RSpec.configuration.site = watir_settings[:sites]['first']
RSpec.configuration.browser_type = browser_type
config.after(:suite) do
unless RSpec.configuration.browser.nil?
RSpec.configuration.browser.close
RSpec.configuration.browser = nil
end
end
config.after(:each) do
if example.metadata.exception
screenshot!('after')
save_html!('after')
end
end
def self.symbolized(hash)
r = hash.dup
hash.each_pair do |k, v|
if k.kind_of?(String)
if v.kind_of?(Hash)
v = symbolized v
end
r[k.to_sym] = v
end
end
r
end
end
Автор: akzhan