Selenium Web自动化Page Object设计模式——循环执行测试用例

继续优化上一篇博客的设计
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()的最后一个方法中,

  1. 如果return到其他class中并传入self.driver参数,下一次循环的用例就不会调用driver.get方法打开新页面,导致下一次用例无法查找到其对应的元素。
  2. 如果在return之前执行driver.quit(),则会报出“由于目标计算机积极拒绝,无法连接。”的错误,因为driver已经被停止,无法被返回。
  3. 如果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到其他类。

posted @ 2020-12-30 16:40  Ravenna  阅读(404)  评论(0编辑  收藏  举报