Pytest + 异步剧作家:测试执行在第一个测试通过后永远挂起

问题描述 投票:0回答:1

我在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 的 Playwright 插件的情况下运行所有测试的方法,因为我认为应该有一种方法可以在不使用 Playwright 插件的情况下运行我的测试。
  • 我发现了一个类似的问题here,但它没有答案,所以我问的是我的具体案例,也涉及剧作家。

更新(2024-04-25)

这是

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

该过程永远陷入困境:(

也许还有我没有提到的其他细节:

  • 我正在 conda 环境中开发
  • 我使用的是 Windows 机器
python pytest playwright playwright-python pytest-asyncio
1个回答
0
投票

你解决这个问题了吗?

我最近遇到了同样的问题,解决方案是在测试中的

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 事件循环

© www.soinside.com 2019 - 2024. All rights reserved.