nikkie-ftnextの日記

イベントレポートや読書メモを発信

pytest.importorskip 〜インポートできなければ以降のテストをスキップ〜

はじめに

宮尾美也さん、お誕生日おめでとうございます1。nikkie (UUID 28fb3f96-a221-462c-93bd-567b431715b9) です。

直近のプルリクエストリーディングからメンテナ活動へ持ち帰れたものがありました。

目次

FastAPI のプルリクエストリーディングから

FastAPI が free-threaded Python をサポートしたプルリクエストを読みました。

ujson と orjson は free-threaded Python はサポートしていないので、ドキュメントのテストの GitHub Actions では 3.14t の時を除いてuv pip installします。
つまり Python 3.14t では環境に ujson と orjson がありません。
このとき、ドキュメントのテストをスキップさせるのにpytest.importorskipを使っていました。
https://github.com/fastapi/fastapi/pull/15149/changes#diff-35479135234916f81b5bc52ce5d1a0983691940c592081a03614fe2057d0e74b

# import 文が集まっています

pytest.importorskip("orjson")


# pytest のテストコードが続きます

pytest.importorskip

https://docs.pytest.org/en/stable/reference/reference.html#pytest-importorskip

Import and return the requested module modname, or skip the current test if the module cannot be imported.

pytest.importorskip("orjson")であれば orjson をインポートして返します。
インポートできない場合は現在のテストをスキップします。

How-to の中の「How to use skip and xfail to deal with tests that cannot succeed」より

docs.pytest.org

You can skip tests on a missing import by using pytest.importorskip at module level, within a test, or test setup function. (Skipping on a missing import dependency)

Skip all tests in a module if some import is missing (Summary)

SpeechRecogntion に導入

pytest.importorskipを知った時、メンテしている SpeechRecogntion に導入できそうと思いました。
だいぶ前ですが、extra の依存指定を私がミスっており、プルリクをいただいたことがありました。

faster-whisper =
    faster-whisper
+    soundfile

GitHub Actions での CI で extra ごとにテストを実行できれば恒久対応になりそうだなあとアイデアを温めていました。
今回pytest.importorskipを知って使いどころだと思い、恒久対応を実装しました(実装は GPT-5.4 による)

以下が起こっていて、暫定的には対応できているのですが、恒久対応としてextraごとに環境構築してテストを回すのがいいんですかね?pytest.mark.skipifとかpytest.importorskipとか使って。やるべきかいなか
https://github.com/Uberi/speech_recognition/issues/855
https://github.com/Uberi/speech_recognition/pull/856

やるべきです。ただし、extra ごとに毎回フルスイートを回すのではなく、base + all extras + extra別の最小検証 の3層にするのがちょうどいいです。

extra 別の最小検証を以下のプルリクエストで実装しました。

例えばtest_openai.pyは、openai がインストールされていない環境ではスキップします。

pytest.importorskip("openai")

終わりに

FastAPI のプルリクエストからpytest.importorskipを知りました。
過去に extra の依存指定を見落としてバグを仕込んでしまった SpeechRecogntion に、これを使った恒久対応を実装できました。
extra など追加の依存(optional dependencies)のある機能のテストコードで役立ちそうに思います