pytest批量执行Playwright测试时出现Sync API与asyncio冲突错误
问题根源
从错误日志里的asyncio: mode=Mode.STRICT可以明确:pytest-asyncio插件启用了Strict模式,该模式会让asyncio事件循环在整个测试会话期间持续运行。而Playwright同步API(sync_playwright)的设计要求在无运行中asyncio loop的环境下使用,批量执行测试时全局loop持续运行,因此触发冲突报错;单独运行测试文件时未触发,是因为没有其他测试或插件启动全局asyncio loop。
解决方案
方案1:调整pytest-asyncio运行模式
在项目根目录的pytest.ini文件中修改配置,关闭Strict模式:
[pytest] asyncio_mode = auto
若项目无需异步测试,可直接禁用pytest-asyncio插件:
[pytest] addopts = -p no:asyncio
方案2:切换为Playwright异步API
若需保留asyncio环境,将同步测试代码改为异步版本:
import pytest from playwright.async_api import async_playwright @pytest.fixture(scope='class') async def browser(request): async with async_playwright() as p: browser = await p.chromium.launch(headless=False) request.cls.browser = browser yield browser await browser.close() @pytest.fixture(scope='function') async def page(browser): page = await browser.new_page() yield page await page.close() @pytest.mark.usefixtures('browser') class Test_titleclass: async def test_google(self, page): await page.goto('https://google.com') assert 'Google' == await page.title() async def test_portfolio(self, page): await page.goto('https://github-portfolio-pst99.vercel.app/') assert 'My Portfolio' == await page.title()
方案3:为同步fixture创建独立asyncio loop
修改同步fixture代码,手动创建并隔离独立loop,避免与全局loop冲突:
import pytest import asyncio from playwright.sync_api import sync_playwright @pytest.fixture(scope='class') def browser(request): # 创建并设置独立事件循环 loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: with sync_playwright() as p: browser = p.chromium.launch(headless=False) request.cls.browser = browser yield browser browser.close() finally: # 清理loop资源 loop.close() asyncio.set_event_loop(None)
验证方式
修改完成后,直接执行pytest命令,检查所有测试用例是否正常运行。
内容的提问来源于stack exchange,提问作者DevTestSecOps
相关产品推荐
相关产品推荐

