问答 po 模式下,pytest 的 conftest 怎么公用一个 driver

smeil · 2021年03月31日 · 最后由 hellohell 回复于 2021年04月01日 · 679 次阅读

现在遇到一个问题,po 模式,每个页面都做个了 py 文件,但是当用 conftest 跑前置时,conftest 里调用的类生成了一个 driver,然后跑完前置,想接下去跑拼接 case 时,又要重新调用一个页面类,这样就又重新打开了次 driver,举例:conftest 下跑了个 login 方法,他是调用 login 类的都运行在 login 对象下的 driver,这是跑完了登陆的步骤,要接下去跑比如充值操作,这是又要生成一个充值对象,但生存后 driver 被重新生成,就没法和登陆连贯用了,有人有解决方法吗。

共收到 11 条回复 时间 点赞

python 的 module 天然是单例的,所以找个地方初始化 driver = webdriver.Chrome(),其他地方都 import 就行了
或者这样:

driver = webdriver.Chrome()


class BasePage:
    def __init__(self):
        self.driver = driver

创建两个不同的页面 P1,P2 继承 BasePage,打印 id(P1().driver),id(P2().driver) 可以看出是同一个对象,
如果 BasePage 里写成 self.driver = webdriver.Chrome(),那每次实例化都是一个新的 driver

目前我是 self.driver = webdriver.Chrome() 这种方法,页面类继承 base 类,都是没问题的,但是如果用 conftest 的话就不知道怎么处理了,应为 conftest 没有继承,如果 conftest 方法在 case 下运行,后续接下去的操作不知道如何接上 conftest 里的 driver,有啥好办法吗,目前我想到的是在 conftest 下重新调用 driver,然后 conftest 下都吧这个 driver 当入参,但是貌似报错

@pytest.fixture(scope="session")

你试试在登录函数加上这个

Test_y 回复

用了 session 他直接报错 Fixture "get_driver" called directly. Fixtures are not meant to be called directly, are created automatically when test functions request them as parameters. See https://docs.pytest.org/en/latest/fixture.html for more information.

就不能写成

driver = webdriver.Chrome()


class BasePage:
    def __init__(self):
        self.driver = driver

conftest 里 import driver 么
另外重用 driver 不一定是好的方式

MarvinWu 回复

还是不太明白,我这在用例层写用例,每次都会生成相关页面类,页面类继承基类,基类生成 driver,因为是单例,所有运行都没问题,但是 conftest 下不知道如何使用,用了你的方法,不知道理解对不对,在用例层,最开始就生成一个 driver,然后吧这 driver 导入 conftest,conftest 下的方法直接传入这个 driver,然后用例层的一条 case 跑这个 conftest 方法,接下去的操作也传入刚开始生成的 driver 但是报错了 E selenium.common.exceptions.InvalidSessionIdException: Message: A session is either terminated or not started
应该是没用同一个 driver

确定代码里没有 driver.close() 吗?
我自己写了个 demo 没啥问题

smeil 回复

这个报错是因为 fixture 不能直接 get_driver() 来调用,而是应该作为函数参数,再 driver = get_driver。
scope="session"是用 conftest 最优雅的方式。

MarvinWu 回复

终于搞定了,和你说的大同小异,我是 conftest 下某个方法调用 driver,然后 yield 这个 driver,用例程,生成页面类的时候,传如这个方法的 driver

smeil 回复

问题是暂时解决了,但这样做未必就好,跟着项目慢慢体会吧

我记的按照一般原则,就是测试类执行一次,进行一次登录退出。保证单条用例(不如说是一个测试类)可以单独执行,不依赖其他。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册