This post is the sixth in a series of “Getting Started with Selenium Testing” posts from Dave Haeffner, a noted expert on Selenium and automated testing, and a frequent contributor to the Sauce blog and Selenium community. This series is for those who are brand new to test automation with Selenium and a new chapter will be posted every Tuesday (eight chapters in all).
Packaging For UseIn order to get the most out of our tests and page objects, we'll need to package them into a more useful structure. Let's do that using the examples from the previous write-ups.
Global Setup And TeardownFirst we'll need to pull the test setup and teardown actions out of our tests and into a central place. In RSpec this is straight-forward through the use of a 'spec_helper' file. # filename: spec_helper.rb
require 'selenium-webdriver' RSpec.configure do |config| config.before(:each) do @driver = Selenium::WebDriver.for :firefox end config.after(:each) do @driver.quit end endWe need to include the Selenium library here, and by doing so, can remove it from our tests. And by having our test configuration here, we can remove it from the `before(:each)` and `after(:each)` in our tests as well -- replacing them with a simple require statement at the top of the file (`require_relative 'spec_helper'`).
Base URLRather than hard-coding a URL in our tests and page objects, We'll want to put it someplace central, and we'll want it to be configurable. So let's create a 'config.rb' file in the parent directory and place it there.
# filename: config.rb ENV['base_url'] ||= 'http://the-internet.herokuapp.com'By using a conditional when setting the environment variable (`||=`) we are making it so we can override this value when launching our test suite (e.g., `base_url='http://localhost:4567'`). It essentially means if the environment variable already exists and contains a value, use it. Otherwise, set it to 'http://the-internet.herokuapp.com'. We can then reference this variable in our page objects where necessary (if we haven't already). For instance: # filename: login.rb
class Login ... def initialize(driver) @driver = driver @driver.get ENV['base_url'] + '/login' end ...
Folder OrganizationIt's about time we create some folders for our specs and page objects. To err on the side of simplicity, let's call the folders 'spec' (for our tests) and 'pages' (for our page objects). We are using 'spec' since it is a default folder that RSpec will look for. Here's everything we should have after creating folders and moving files around:
. |-- config.rb |-- Gemfile |-- pages | |-- dynamic_loading.rb | `-- login.rb `-- spec |-- dynamic_loading_spec.rb |-- login_spec.rb `-- spec_helper.rb
Updating Require StatementsAs a result of doing this, we will need to update the require statements in our tests. # filename: spec/login_spec.rb
require_relative 'spec_helper' require_relative '../pages/login' describe 'Login' do ...# filename: spec/dynamic_loading_spec.rb
require_relative 'spec_helper' require_relative '../pages/dynamic_loading' describe 'Dynamic Loading' do ...Note the use of double-dots (`..`) in the page object require statement. This is how we tell Ruby to traverse up a directory (from our spec directory) before trying to access the page objects folder. The `spec_helper` require remains unchanged since this file lives in the same directory as our tests.
Running EverythingNow that things are cleaned up, we can run everything. To do that we'll want to make sure to include our new config file. We can do that by specifying it at run time with `rspec --require ./config.rb`, or, `rspec -r ./config.rb` (for short). Note the `./` before `config.rb`. This tells RSpec that the config file is in the current directory. Give it a shot. All of the tests should run and pass. For more examples like this (along with complete working code) -- grab your copy of The Selenium Guidebook.
Dave is the author of Elemental Selenium (a free, once weekly Selenium tip newsletter that is read by hundreds of testing professionals) as well as a new book, The Selenium Guidebook. He is also the creator and maintainer of ChemistryKit (an open-source Selenium framework). He has helped numerous companies successfully implement automated acceptance testing; including The Motley Fool, ManTech International, Sittercity, and Animoto. He is a founder and co-organizer of the Selenium Hangout and has spoken at numerous conferences and meetups about acceptance testing.