Selenium Web自动化Page Object设计模式——driver初始化
如果目前需要通过自动化工具实现如下的这样一个小功能:
1.打开一个网页
2.点击该网页上的一个元素,进入下一个页面
3.点击新页面上的一个元素,进入再下一个页面
4.pass
如果采用非page object的模式来设计的话,Python代码会是这样:
1.driver.get("https://www.一个网页.com/")
2.driver.find_element(x).click
3.driver.find_element(y).click
4.pass
但如果另一项测试需要在第二步之后执行其他的步骤,就需要重新写一段代码,这样代码就会显得重复,并且维护成本也会非常高。
Page Object的主要思想就是将每一个Page封装成一个Object。因此上面的代码可以封装为以下四个类:
driver.get("https://www.一个网页.com/")
打开网页的操作并非一个页面,可以将它封装为一个初始化类
class InitPage:
def __init__(self):
self.driver = webdriver.Chrome()
self.driver.get("https://www.一个网页.com/")
- driver已经过初始化,之后的方法就不需要再对driver做定义,只需要继承InitPage类
class FirstPage(InitPage):
def first_click(self):
driver.find_element(x).click
return SecondPage()
- 一个对象内语句执行完成之后,return到下一个类
class SecondPage(InitPage):
def second_click(self):
driver.find_element(y).click
return ThridPage()
- 同样return到下一个类
class ThirdPage(InitPage):
def third_pass(self):
pass
之后就可以开始编写测试用例的程序,
FirstPage().first_click().second_click().third_pass()
因为在每个页面最后都会return至下一个页面,可通过链式调用的方式编写测试用例,可大大提高用例的灵活性。
但此时有一个问题,就是在继承InitPage对象时,每次调用都会执行__init__中的driver.get,导致打开新的网页窗口。可以通过在构建__init__方法时输入一个WebDriver类型的变量(其实其他类型也可以,例子中为bool类型),仅在该变量为初始值时执行driver.get等语句。并且如果当接下来的page在return的时候传输的变量不为driver的话,调用InitPage中的其他函数会报错缺少driver的错误。更改后的代码如下:
class InitPage:
def __init__(self, driver_flag:bool = False)
if not flag:
self.driver = webdriver.Chrome()
self.driver.get("https://www.一个网页.com/")
else:
self.driver = driver_flag
并且其他类在继承InitPage时需要在返回时传递WebDriver类型的变量driver,此时__init__方法接收到参数driver,driver_flag的类型为WebDriver。更改后的代码如下如:
class FirstPage(InitPage):
def first_click(self):
driver.find_element(x).click
return SecondPage(self.driver)
此时__init__方法仅会在第一次被调用时执行if条件内的内容。并且不会出现缺少driver的错误。