为 Firefox 和 Chrome 编写 selenium 测试时避免代码重复
Avoid code duplication when writing selenium tests for Firefox and Chrome
如果您为 Selenium 编写测试以检查例如Firefox 和 Chrome,测试看起来非常相似,除了设置,参见例如https://gist.github.com/devinmancuso/54904c005f8d237f6fec, which has identical functions test_search_in_python_chrome
and test_search_in_python_firefox
. There are patterns to avoid code duplication in selenium, e.g. the Page Object Pattern。
有没有办法避免这种巨大的代码重复?
您提供的link中setUp
的内容为driver
初始化。您可以在另一个 class 中处理此问题,并从 属性 文件
中读取浏览器类型
def get_driver(self):
browser = get_value_from_configurations_file()
url = get_value_from_configurations_file()
driver = None
if browser == 'chrome':
driver = webdriver.Chrome()
elif browser == 'firefox':
driver = webdriver.Firefox()
driver.maximize_window()
driver.get(url)
return driver
我通常在驱动工厂和测试之间使用 "middle man" 来处理 driver
操作并获取 PO 起点
class WebApplication:
def __init__(self):
self.__driver = WebDriverFactory().get_driver()
def get_driver(self):
return self.__driver
def get_home_page(self):
return HomePage(self.__driver)
并从基础测试中使用它 class
@pytest.mark.usefixtures("run_for_test")
class AbstractTest(ABC):
web_application = None
@pytest.fixture()
def run_for_test(self, request):
AbstractTest.web_application = WebApplication()
# set up for all tests
yield
# tear down for all tests
示例测试:
class TestExample(AbstractTest):
def test_example(self):
home_page = \
(self.web_application
.get_home_page())
这样,您只需更改配置文件,就可以编写一次测试,运行它可以在不同的浏览器上运行。
@Guy的回答指明了方向。 A solution 更简单一点的是使用 MixIns
:
class DuckMixin(object):
def testDuckLoads(self):
self.browser.get("https://duckduckgo.com")
self.assertIn("duckduckgo", self.browser.title.lower())
def testDuckSafe(self):
self.browser.get("https://duckduckgo.com")
(self.browser
.find_element_by_id("search_form_input_homepage")
.send_keys("porn" + webdriver.common.keys.Keys.RETURN))
# click to disable temporarily, then wait, then see if available
self.browser.implicitly_wait(10)
self.browser.find_element_by_class_name("js-safe-search-temp").click()
# assert that browser.find_element_by_class_name("js-safe-search-temp") still exists, else throws exception
self.browser.find_element_by_class_name("js-safe-search-temp")
class DuckDuckGoTestCaseFirefox(unittest.TestCase, DuckMixin):
def setUp(self):
profile = webdriver.FirefoxProfile()
profile.add_extension(extension=os.path.join(DIR, "..", "addon"))
self.browser = webdriver.Firefox(firefox_profile=profile)
def tearDown(self):
self.browser.close()
class DuckDuckGoTestCaseChromium(unittest.TestCase, DuckMixin):
def setUp(self):
profile = webdriver.chrome.options.Options()
profile.add_extension(extension=os.path.join(DIR, "..", "safe.zip"))
self.browser = webdriver.Chrome(chrome_options=profile)
def tearDown(self):
self.browser.close()
如果您为 Selenium 编写测试以检查例如Firefox 和 Chrome,测试看起来非常相似,除了设置,参见例如https://gist.github.com/devinmancuso/54904c005f8d237f6fec, which has identical functions test_search_in_python_chrome
and test_search_in_python_firefox
. There are patterns to avoid code duplication in selenium, e.g. the Page Object Pattern。
有没有办法避免这种巨大的代码重复?
您提供的link中setUp
的内容为driver
初始化。您可以在另一个 class 中处理此问题,并从 属性 文件
def get_driver(self):
browser = get_value_from_configurations_file()
url = get_value_from_configurations_file()
driver = None
if browser == 'chrome':
driver = webdriver.Chrome()
elif browser == 'firefox':
driver = webdriver.Firefox()
driver.maximize_window()
driver.get(url)
return driver
我通常在驱动工厂和测试之间使用 "middle man" 来处理 driver
操作并获取 PO 起点
class WebApplication:
def __init__(self):
self.__driver = WebDriverFactory().get_driver()
def get_driver(self):
return self.__driver
def get_home_page(self):
return HomePage(self.__driver)
并从基础测试中使用它 class
@pytest.mark.usefixtures("run_for_test")
class AbstractTest(ABC):
web_application = None
@pytest.fixture()
def run_for_test(self, request):
AbstractTest.web_application = WebApplication()
# set up for all tests
yield
# tear down for all tests
示例测试:
class TestExample(AbstractTest):
def test_example(self):
home_page = \
(self.web_application
.get_home_page())
这样,您只需更改配置文件,就可以编写一次测试,运行它可以在不同的浏览器上运行。
@Guy的回答指明了方向。 A solution 更简单一点的是使用 MixIns
:
class DuckMixin(object):
def testDuckLoads(self):
self.browser.get("https://duckduckgo.com")
self.assertIn("duckduckgo", self.browser.title.lower())
def testDuckSafe(self):
self.browser.get("https://duckduckgo.com")
(self.browser
.find_element_by_id("search_form_input_homepage")
.send_keys("porn" + webdriver.common.keys.Keys.RETURN))
# click to disable temporarily, then wait, then see if available
self.browser.implicitly_wait(10)
self.browser.find_element_by_class_name("js-safe-search-temp").click()
# assert that browser.find_element_by_class_name("js-safe-search-temp") still exists, else throws exception
self.browser.find_element_by_class_name("js-safe-search-temp")
class DuckDuckGoTestCaseFirefox(unittest.TestCase, DuckMixin):
def setUp(self):
profile = webdriver.FirefoxProfile()
profile.add_extension(extension=os.path.join(DIR, "..", "addon"))
self.browser = webdriver.Firefox(firefox_profile=profile)
def tearDown(self):
self.browser.close()
class DuckDuckGoTestCaseChromium(unittest.TestCase, DuckMixin):
def setUp(self):
profile = webdriver.chrome.options.Options()
profile.add_extension(extension=os.path.join(DIR, "..", "safe.zip"))
self.browser = webdriver.Chrome(chrome_options=profile)
def tearDown(self):
self.browser.close()