继续优化上一篇博客的设计
Selenium Web自动化Page Object设计模式——driver初始化
https://www.cnblogs.com/Ravenna/p/14172411.html
假设现在的需求是,测试用例需要循环执行,每次执行需要打开的url都不同
原先的代码如下:
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
在这段代码中,如果通过driver.get打开的url需要传入一个变量才能使其有效,比如:
self.driver.get(f"https://www.一个网页{变量1}.com/")
当需要循环的次数非常小时,可以仅靠通过新建多个case来实现该功能。
若不考虑新建多个case的情况,在原有程序上做修改的话,把启动浏览器的代码放在初始页面的init方法中会导致许多问题,比如:
在链式调用FirstPage().first_click().second_click().third_pass()
的最后一个方法中,
- 如果return到其他class中并传入self.driver参数,下一次循环的用例就不会调用driver.get方法打开新页面,导致下一次用例无法查找到其对应的元素。
- 如果在return之前执行driver.quit(),则会报出“由于目标计算机积极拒绝,无法连接。”的错误,因为driver已经被停止,无法被返回。
- 如果return到其他class并且传入init方法的初始值False,因为其他class也继承了InitPage类,返回后就会打开一个新的页面,即使执行driver.quit()也只会把新打开的网页关闭。
一个有效的解决方案是:
将启动浏览器的代码从init方法中移除,封装在第一个页面的类的方法中,从init方法中移除,并且在调用这个方法时传入变量。
比如调用的第一个页面是FirstPage,便可以将driver.get放在first_click()方法中,修改后的代码如下:
class FirstPage(InitPage):
def first_click(self, 变量1):
self.driver.get(f"https://www.一个网页{变量1}.com/")
self.driver.find_element(x).click
return SecondPage(self.driver)
init方法中仅对driver做初始化
def __init__(self, driver_flag:bool = False)
if not flag:
self.driver = webdriver.Chrome()
else:
self.driver = driver_flag
链式调用的代码则修改为:FirstPage().first_click(变量1)
通过pytest的参数化方法,便可循环执行用例并传入变量,在最后一个页面执行完成之后只需执行driver.quit(),无需return到其他类。