Skip to content

Instantly share code, notes, and snippets.

@Lucretiel
Last active December 14, 2015 22:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lucretiel/5159335 to your computer and use it in GitHub Desktop.
Save Lucretiel/5159335 to your computer and use it in GitHub Desktop.
Here's an example of what I was talking about earlier- I found common patterns in the HomePage suite, reformatted them into a series of generic tests and decorators.
#Generic test methods.
@nose.tools.nottest
def test_css_element(driver, selector, test):
'''
Find an element, then perform a test on that element
'''
test(driver.find_element_by_css_selector(selector))
@nose.tools.nottest
def click_and_test(driver, selector, test):
'''
Click a certain css selector, then perform a test on the driver
'''
def test_element(element):
element.click()
test(driver)
test_css_element(driver, selector, test_element)
@nose.tools.nottest
def click_and_test_url(driver, selector, url_test):
'''
Click a certain css selector, then perform a test on the current_url
'''
def test(driver):
url_test(driver.current_url)
click_and_test(driver, selector, test)
#Helper decorator
@nose.tools.nottest
def test_with(generic, selector):
'''
Helper decorator to make it even easier to compose tests. See examples below.
'''
def decorator(func):
@nose.tools.make_decorator(func)
def wrapper(self):
generic(self.driver, selector, func)
return wrapper
return decorator
#Helper decorator that includes self
@nose.tools.nottest
def self_test_with(generic, selector):
'''
Helper decorator to make it even easier to compose tests. See examples below.
This version provides the self paramater to the decorated function.
'''
def decorator(func):
@nose.tools.make_decorator(func)
def wrapper(self):
def test_func_wrapper(*args):
func(self, *args)
generic(self.driver, selector, test_func_wrapper)
return wrapper
return decorator
#EXAMPLE:
class HomePage(unittest.TestCase):
#All the regular setUp code and other stuff
#These tests should be identical to their counterparts
@attr(environment='all', device='all')
@self_test_with(click_and_test_url, homepageV1.logo_header["contact_link"])
def test_contact_us(self, url):
nose.tools.assert_equal(url, self.url_dict["contact_url"])
#Many functions, like the one above have a common pattern- get selector, define test, run generic.
#You can use a decorator to make this even easier. Just define the internal test, which
#is the most important part anyway, decorated with @test_with(generic_test, selector):
@test_with(test_css_element, homepageV1.as_seen_on["caption_text"])
def test_as_seen_on_text(element):
nose.tools.assert_equal(element.text, "As seen on:")
#If the above looks weird because you really want or need that self parameter,
#use the self_test_with decorator instead
@self_test_with(test_css_element, homepageV1.main_section["features"])
def test_bulleted_section_items(self, element):
self.failUnless(len(element) == 6)
#The latter 2 forms are good because they put the emphasis on the test itself- Not the boilerplate around it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment