各个大佬,最近摸索用 selenium 写基于 PO 模型的 ui 自动化框架。
由于每个页面写一个 page,其中 page 容易继承和初始化 driver 驱动,导致测试时会同时打开多个浏览器页面。
请问这如何避免,用 setup\teardown\conftest 可以解决吗?或者同时打开多个浏览器是否会有大影响吗?谢谢
我们是用 threadlocal 解决的,自定义注解 aware,通过注解 aware 注入到测试类,在监听类实现,自己注册个监听的类,单个机器多个 chrome 是可以跑的
创建一个 case 类,在 case 里面保持一个 driver 就行了,如果用了并行执行 case,那可能就要搞个 threadlocal 隔离下,但未必也能行,因为执行机器就一个 chrome,没测试过只能试试看
from selenium import webdriver
class DriverInit:
def driver(self):
driver = webdriver.Chrome()
return driver
driver = DriverInit().driver()
我直接单搞了一个类专门调用 driver 的,开始直接初始化一个,然后 basepage 直接用这个 driver 就行了
感谢回复。目前 Base 公共类继承 driver,Page 继承 Base,每个 Test 文件中,实例化相应的 Page,所以每执行一个 Test,便新建了一个 driver 浏览器。请问有何优化建议吗?
你要解决问题的思路是,为什么其中 page 容易继承和初始化 driver 驱动,导致测试时会同时打开多个浏览器页面。
?
显然是你的传参有问题。不是每一步都创建 driver,创建 driver 只调用一次,包括了打开浏览器、关闭浏览器,配合 yeild,放在 conftest 里面,在 setUp 和 tearDown 分别调用。
盲猜,你的 PO 模式的,page 模块的 driver
不是入参。每个模块都会重复创建。 我写个伪代码吧,帮你提供思路,仅供参考:
你的 conftest 配置:
# ./conftest.py
import pytest
import ... ...
@pytest.fixture(scope='function')
def operatorSeleniumDriver():
driver = 创建dirver
driver.打开浏览器
yield driver
driver.关闭浏览器
你的 page 模块的封装:
#./Page/ Login.py
class LoginStep:
def 选择登录的方式(self,driver):
driver.find_element(xxxxxxx)
pass
def 输入用户名密码登陆(self,driver):
driver.find_element(xxxxxxx)
pass
你的测试用例这样写:
# ./TestCase/test_login.py
import Page.xxx.Login
class Test_login:
def test_login(operatorSeleniumDriver):
driver = operatorSeleniumDriver
action = LoginStep()
action.选择登录的方式(driver)
action.输入用户名密码登陆(driver)
......
试试 driver 设置单例模式?