如何在pytest fixture中yield Playwright对象复用?遇执行异常
问题排查与解决
核心问题:未正确使用Fixture
你定义了playwright_instance fixture,但测试函数test_for_SObject_connectivity完全没用到它——你在测试代码里重新用async with async_playwright()创建了实例,和fixture毫无关联。先把测试代码修正为正确使用fixture的形式:
import asyncio, pytest from SingletonObject import SObject from playwright.async_api import expect, async_playwright @pytest.fixture async def playwright_instance(): async with async_playwright() as playwright: yield playwright # 将fixture作为参数传入,pytest会自动注入实例 async def test_for_SObject_connectivity(playwright_instance): # 移除测试内的async with async_playwright(),直接使用fixture注入的实例 test = SObject(playwright_instance) await test.start() await expect(test.search_page).to_have_url("[specific url]")
异步Fixture的必要配置
使用异步fixture必须确保pytest-asyncio正确配置:
- 确保已安装
pytest-asyncio - 在项目根目录创建
pytest.ini文件,添加以下内容避免事件循环冲突:
[pytest] asyncio_mode = auto
关于Playwright官方插件的问题
使用官方插件时出现RuntimeError: Cannot run the event loop while another loops is running,通常原因是:
- 自定义fixture与插件提供的fixture重复创建事件循环
- 插件已封装
playwright、browser、page等fixture,无需自行定义playwright_instance
若要使用官方插件,直接调用其提供的fixture即可,示例:
import pytest from SingletonObject import SObject from playwright.async_api import expect # 直接使用插件的playwright fixture async def test_for_SObject_connectivity(playwright): test = SObject(playwright) await test.start() await expect(test.search_page).to_have_url("[specific url]")
同时保证pytest.ini的asyncio_mode配置正确,不要同时运行自定义异步fixture和插件fixture,避免循环冲突。
总结
- 修正测试函数,正确传入fixture参数,不要在测试内重复创建Playwright实例
- 配置
pytest-asyncio的异步模式,解决事件循环冲突问题 - 使用官方插件时,直接调用其提供的fixture,避免重复定义引发的问题
内容的提问来源于stack exchange,提问作者Cameron Wetzel
相关产品推荐
相关产品推荐

