コンテンツにスキップ

pytilpack.pytest

必要なextra

pip install pytilpack[pytest]

pytilpack.pytest

pytest用のユーティリティ集。

AssertBlock(data, suffix='.html', encoding='utf-8', errors='replace', tmp_path=None)

大きいデータ (画面のHTML等) をpytestのassertで確認するためのユーティリティ。

ブロック内でエラーが発生した場合、dataを一時ファイルに書き出し、そのパスを例外メッセージに出力する。

例::

def test_something():
    data = ... # 画面のHTMLなどの大きいデータ
    with pytilpack.pytest.AssertBlock(data, ".html"):
        assert "expected string" in data
ソースコード位置: pytilpack/pytest.py
def __init__(
    self,
    data: str | bytes,
    suffix: str = ".html",
    encoding: str = "utf-8",
    errors: str = "replace",
    tmp_path: pathlib.Path | None = None,
) -> None:
    self.data = data
    self.suffix = suffix
    self.tmp_path = tmp_path
    self.encoding = encoding
    self.errors = errors

__enter__()

コンテキストマネージャーのenter。

ソースコード位置: pytilpack/pytest.py
def __enter__(self) -> None:
    """コンテキストマネージャーのenter。"""

__exit__(exc_type, exc_val, exc_tb)

コンテキストマネージャーのexit。エラーが発生した場合はdataを一時ファイルに書き出し、パスをログと例外メッセージに出力する。

ソースコード位置: pytilpack/pytest.py
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
    """コンテキストマネージャーのexit。エラーが発生した場合はdataを一時ファイルに書き出し、パスをログと例外メッセージに出力する。"""
    del exc_tb  # noqa
    if exc_type is None:
        return
    if exc_type is AssertionError:
        path = create_temp_view(
            tmp_path=self.tmp_path, data=self.data, suffix=self.suffix, encoding=self.encoding, errors=self.errors
        )
        logger.error(f"アサーションエラー: {exc_val}, <{path}>")
        msg = str(exc_val)
        if len(msg) > 24:
            matches = [(i, p) for p in ("' in '", "' in b'") if (i := msg.find(p)) != -1]
            if matches:
                i, p = min(matches)
                msg = msg[: i + len(p)] + "..."
            else:
                msg = msg[:24] + "..."
        raise AssertionError(f"{msg}, <{path}>") from exc_val

__aenter__() async

非同期コンテキストマネージャーのenter。

ソースコード位置: pytilpack/pytest.py
async def __aenter__(self) -> None:
    """非同期コンテキストマネージャーのenter。"""
    return self.__enter__()

__aexit__(exc_type, exc_val, exc_tb) async

非同期コンテキストマネージャーのexit。エラーが発生した場合はdataを一時ファイルに書き出し、パスをログと例外メッセージに出力する。

ソースコード位置: pytilpack/pytest.py
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
    """非同期コンテキストマネージャーのexit。エラーが発生した場合はdataを一時ファイルに書き出し、パスをログと例外メッセージに出力する。"""
    self.__exit__(exc_type, exc_val, exc_tb)

create_temp_view(tmp_path, data, suffix, encoding='utf-8', errors='replace')

データの確認用に一時ファイルを作成する。

ソースコード位置: pytilpack/pytest.py
def create_temp_view(
    tmp_path: pathlib.Path | None,
    data: str | bytes,
    suffix: str,
    encoding: str = "utf-8",
    errors: str = "replace",
) -> pathlib.Path:
    """データの確認用に一時ファイルを作成する。"""
    output_path = tmp_file_path(tmp_path=tmp_path, suffix=suffix)
    if isinstance(data, str):
        data = data.encode(encoding=encoding, errors=errors)
    else:
        assert isinstance(data, bytes)
    output_path.write_bytes(data)
    logger.info(f"view: {output_path}")
    return output_path

tmp_file_path(tmp_path=None, suffix='.txt', prefix='tmp')

一時ファイルパスを返す。

ソースコード位置: pytilpack/pytest.py
def tmp_file_path(tmp_path: pathlib.Path | None = None, suffix: str = ".txt", prefix: str = "tmp") -> pathlib.Path:
    """一時ファイルパスを返す。"""
    if tmp_path is None:
        tmp_path = get_tmp_path()
    with tempfile.NamedTemporaryFile(suffix=suffix, prefix=prefix, dir=tmp_path, delete=False) as f:
        return pathlib.Path(f.name)

get_tmp_path()

temp_path fixtureの指す先の1つ上の階層と思われるパスを返す。

fixtureを直接使用することが望ましいが、手軽に利用したい場合向けの簡易関数である。

ソースコード位置: pytilpack/pytest.py
def get_tmp_path() -> pathlib.Path:
    """temp_path fixtureの指す先の1つ上の階層と思われるパスを返す。

    fixtureを直接使用することが望ましいが、手軽に利用したい場合向けの簡易関数である。

    """
    username = getpass.getuser()
    path = pathlib.Path(tempfile.gettempdir()) / f"pytest-of-{username}" / "pytest-current"
    path = path.resolve()
    # pytest-xdist環境ではワーカーごとのサブディレクトリが使われる
    worker_id = os.environ.get("PYTEST_XDIST_WORKER")
    if worker_id is not None:
        path = path / f"popen-{worker_id}"
    path.mkdir(parents=True, exist_ok=True)
    return path