首页 > 解决方案 > pytest 添加选项以跳过夹具设置

问题描述

假设我有一个使用 pyserial 连接的测试子集。跳过相关的测试功能与--runslow文档中的示例基本相同。

我的问题是:如何跳过夹具,以免出现测试设置失败错误?也就是说,如果未连接设备,则会在夹具设置期间引发错误。

如果连接完全失败,编辑(奖励)可能会自动初始化跳过标记?

编辑 2我想我真的在问这两个TODOs 中的哪一个是“正确”的方法?

编辑 3也许只是设置autouse=False并确保标记了使用夹具的每个测试功能?

这是我正在尝试做的一个例子:

# conftest.py

import pytest

from typing import List
from serial import Serial

from _pytest.nodes import Item
from _pytest.config import Config
from _pytest.config.argparsing import Parser


def pytest_addoption(parser: Parser):
    parser.addoption(
        "--live",
        action="store_true",
        default=False,
        help="utilize serial connection"
    )


def pytest_collection_modifyitems(config: Config, items: List[Item]):
    if config.getoption("--live"):
        return
    skip = pytest.mark.skip(
        reason="needs '--live' option to run"
    )
    for item in items:
        if "live" in item.keywords:
            item.add_marker(skip)


# fixtures (port, etc.) for connection...


# TODO need to apply skip mark
@pytest.fixture(scope='session', autouse=True)
def serial_connect(port: str, ) -> Serial:

    # TODO or catch and pass if config value is False
    with Serial(port=port, ) as new:
        yield new

标签: pythonpytest

解决方案


此实施取得了成功;将不胜感激反馈:

# conftest.py

import sys
import pytest

from typing import Optional
from serial import Serial, SerialException, \
    EIGHTBITS, PARITY_NONE, STOPBITS_ONE

from _pytest.config import UsageError
from _pytest.config.argparsing import Parser


def pytest_addoption(parser: Parser):

    parser.addoption(
        "--live", action="store_true", default=False,
        help="utilize serial connection for associated tests"
    )

    parser.addoption(
        "--port", action="store", type="string", default=None,
        help="serial port for establishing connection"
    )

    parser.addoption(
        "--timeout", action="store", type="float", default=None,
        help="port timeout for serial connection"
    )


@pytest.fixture
def live(request) -> bool:
    return request.config.getoption('live')


@pytest.fixture
def port(request) -> str:

    value = request.config.getoption('port')

    if value is not None:
        return value

    elif sys.platform.startswith('darwin'):
        return "/dev/tty.SLAB_USBtoUART"

    elif sys.platform.startswith('linux'):
        return "/dev/ttyACM0"

    elif sys.platform.startswith('win32'):
        return "COM14"

    else:
        pytest.skip("unspecified '--port' option")


@pytest.fixture
def timeout(request) -> Optional[float]:
    return request.config.getoption('timeout')


@pytest.fixture
def connection(live: bool, port: str, timeout: Optional[float]) -> Serial:

    if not live:
        pytest.skip("needs '--live' option to run")

    try:
        with Serial(
            port=port,  baudrate=460800, bytesize=EIGHTBITS,
            parity=PARITY_NONE, stopbits=STOPBITS_ONE, timeout=timeout
        ) as s:
            yield s

    except SerialException as e:
        raise UsageError(
            "invoked '--live' option, but connection failed"
        ) from e

推荐阅读