我在Python中使用async_playwright。当我想添加单元测试时,我需要为每个测试用例创建一个共享浏览器和页面。我正在使用
pytest_asyncio
为此创建固定装置。
这是我的
conftest.py
文件:
import pytest_asyncio
import asyncio
from playwright.async_api import async_playwright
from src.page_object.factory.playwright import PWPageOjectFactory
@pytest_asyncio.fixture(scope="session")
def event_loop(request):
"""Create an instance of the default event loop for each test case."""
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
@pytest_asyncio.fixture(scope="module")
async def browser():
async with async_playwright() as p:
browser = await p.chromium.launch()
yield browser
await browser.close()
@pytest_asyncio.fixture(scope="module")
async def page(browser):
factory = PWPageOjectFactory("https://www.google.com", browser)
print(factory.url)
page = await factory.create_page_object()
print(page)
return page
这是我的测试文件:
import pytest
from src.page_object.element.playwright import PWElement
from src.page_object.page.playwright import PWPageObject
pytest_plugins = ("pytest_asyncio",)
@pytest.mark.asyncio
async def test_po_factory(page):
assert page is not None
assert isinstance(page, PWPageObject)
@pytest.mark.asyncio
async def test_get_active_element(page):
element = await page.get_active_element()
assert element is not None
assert isinstance(element, PWElement)
@pytest.mark.asyncio
async def test_navigate(page):
element = await page.get_active_element()
await page.navigate_forward()
new_element = await page.get_active_element()
assert element.get_attribute("id") != new_element.get_attribute("id")
await page.navigate_backward()
new_element = await page.get_active_element()
assert element.get_attribute("id") == new_element.get_attribute("id")
当我执行
pytest tests
(其中tests
是包含先前文件的文件夹)时,第一个测试用例通过,然后执行永远卡住。
我在这里缺少什么?
我尝试过的事情:
event_loop
文件中删除了 conftest.py
夹具并得到了相同的结果。这是
pytest -vvv -s
的输出:
(example) C:\Users\MyUser\Desktop\projects\example>pytest -vvv -s
================================================= test session starts =================================================
platform win32 -- Python 3.12.2, pytest-8.1.1, pluggy-1.4.0 -- C:\Users\MyUser\miniconda3\envs\example\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\MyUser\Desktop\projects\example
plugins: asyncio-0.23.6
asyncio: mode=Mode.STRICT
collected 5 items
tests/test_pageobject.py::test_po_factory https://www.google.com
<src.page_object.page.playwright.PWPageObject object at 0x0000018A4EA38FB0>
PASSED
tests/test_pageobject.py::test_get_active_element
该过程永远陷入困境:(
也许还有我没有提到的其他细节:
你解决这个问题了吗?
我最近遇到了同样的问题,解决方案是在测试中的
loop_scope
标记中添加 asyncio
参数并将其设置为 module
。
像这样:
@pytest.mark.asyncio(loop_scope="module")
async def test_po_factory(page):
assert page is not None
assert isinstance(page, PWPageObject)
将此参数添加到模块中的所有测试中。
您可以移除
event_loop
固定装置。
参考 - asyncio 事件循环