Here’s the framework I’ve come up with to implement the Page Objects design pattern in Python for my automated regression testing. The code has been simplified so it’s easier to follow. In my real code, I have a lot of custom handling of settings and application-specific helper functions that aren’t critical for understanding this pattern.
Setting up the test context
from ConfigParser import SafeConfigParser
from nose.plugins.skip import SkipTest
from selenium import webdriver
import sys
import unittest
class TestContext(object):
def __init__(self):
self._get_configuration()
self.driver = None
def _get_configuration(self):
config_parser = SafeConfigParser()
config_parser.read(r"setup.cfg")
settings = dict(config_parser.items('settings'))
self.driver_to_use = settings['browser']
def open_browser(self):
if(self.driver_to_use == 'Chrome'):
self.driver = webdriver.Chrome()
else:
self.driver = webdriver.Firefox()
class BaseTestCase(unittest.TestCase):
def skip_on_known_bug(self):
""" issues commented out means it's fixed """
known_issues = {
101: 'Browser crash',
#102: 'Firefox freeze',
}
for reason in self.skip_reasons:
if known_issues.get(reason, None):
raise SkipTest(reason, known_issues[reason])
def setUp(self):
unittest.TestCase.setUp(self)
self.skip_on_known_bug()
self.tc = TestContext() # used by all tests and Page Object classes
self.tc.open_browser()
self.tc.driver.get(self.tc.user_url)
def tearDown(self):
if sys.exc_info() == (None, None, None): # leave window open on fail
self.tc.driver.quit()
Page object
class UserLogin(BaseTestCase):
def __init__(self, context):
self.tc = context # make username, web driver, etc. available to the page object's methods
def login_valid(self, uname=None):
elem = self.tc.driver.find_element_by_id('user_id')
elem.send_keys(uname)
elem.submit()
The test case
import PageObjects
class TestCase(PageObjects.BaseTestCase):
def setUp(self):
self.skip_reasons = [] # bug tracker issue numbers
PageObjects.BaseTestCase.setUp(self)
def login_test(self):
UserLogin = PageObjects.UserLogin(self.tc) # pass in test context, such as the driver object and useful variables
UserLogin.login_valid() # each page has "services" you can use, which here are Python methods