はじめに
七尾百合子さん、お誕生日 20日目 おめでとうございます! nikkieです。
自作のsphinx-revealjs-copycodeの開発の中での学びです。
目次
- はじめに
- 目次
- sphinx-revealjs v2とv3の両方でテストしたい
- Hatchを使って依存ライブラリのバージョンが異なるテスト環境を用意
- 依存ライブラリのバージョンを見てテストをスキップ(pytest)
- 終わりに
sphinx-revealjs v2とv3の両方でテストしたい
sphinx-revealjs-copycodeはv0.2.0で sphinx-revealjs v3 をサポートしました1。
v2とv3の両方をサポートしたわけです。
sphinx-revealjsは v2 -> v3 でバンドルされるReveal.jsのパスが変わっています。
https://sphinx-revealjs.readthedocs.io/en/stable/upgrade/3.x/#change-bundled-revealjs-path
sphinx-revealjs-copycodeは、sphinx-revealjsの静的ファイルの中にCopyCodeプラグインを追加する実装です。
sphinx-revealjsのバージョンを見て、CopyCodeプラグインを配置する必要がありました2
- v2では
revealjs4の下に配置 - v3では
revealjsの下に配置
そのため、テストにはsphinx-revealjs v2とv3の2環境が必要となりました。
ここにHatchを使いました。
Hatchを使って依存ライブラリのバージョンが異なるテスト環境を用意
Hatch3は用途ごとに仮想環境を用意できます。
uvや人力4ではプロジェクトで扱う仮想環境は1つだけですが、Hatchは複数の仮想環境をラップしてくれています。
これを使ってテスト向けの仮想環境を2つ作ります
% hatch --version Hatch, version 1.14.0
[tool.hatch.envs.test-sphinx-revealjs2] dependencies = ["pytest", "sphinx-revealjs>=2,<3"] [tool.hatch.envs.test-sphinx-revealjs2.scripts] run = "pytest -s -v" [tool.hatch.envs.test-sphinx-revealjs3] dependencies = ["pytest", "sphinx-revealjs>=3,<4"] [tool.hatch.envs.test-sphinx-revealjs3.scripts] run = "pytest -s -v"
sphinx-revealjs v2の仮想環境とv3の仮想環境の2つを作成しました。
sphinx-revealjs-copycodeはどちらの仮想環境にもeditable installされます。
1つのコマンドtask testで両環境のテストが流れるようにしました。
プロジェクト直下の仮想環境にtaskipy5を含む依存をインストールしています。
[tool.taskipy.tasks] test = "task test_v2 && task test_v3" test_v2 = "hatch env run -e test-sphinx-revealjs2 run" test_v3 = "hatch env run -e test-sphinx-revealjs3 run"
依存ライブラリのバージョンを見てテストをスキップ(pytest)
テストコード6にはpytestのマーカ pytest.mark.skipif を使いました。
from importlib.metadata import version import pytest @pytest.mark.skipif( not version("sphinx-revealjs").startswith("2."), reason="requires sphinx-revealjs v2", ) @pytest.mark.sphinx("revealjs", testroot="default") def test_arrange_copycode_plugin_sphinx_revealjs_v2( app: SphinxTestApp, ) -> None: app.build() assert (app.outdir / "_static/revealjs4/plugin/copycode").exists() @pytest.mark.skipif( not version("sphinx-revealjs").startswith("3."), reason="requires sphinx-revealjs v3", ) @pytest.mark.sphinx("revealjs", testroot="default") def test_arrange_copycode_plugin_sphinx_revealjs_v3( app: SphinxTestApp, ) -> None: app.build() assert (app.outdir / "_static/revealjs/plugin/copycode").exists()
importlib.metadata.versionで環境のsphinx-revealjsのバージョンを取得し、スキップ判定しています。
- sphinx-revealjs v2の環境
- v2のテスト(
revealjs4というパスの検証)のみ実行 - v3向けのテスト(
revealjsというパスの検証)をスキップ
- v2のテスト(
- sphinx-revealjs v3の環境
- v2向けのテスト(
revealjs4というパスの検証)をスキップ - v3のテスト(
revealjsというパスの検証)のみ実行
- v2向けのテスト(
終わりに
sphinx-revealjs-copycodeの開発の中で、sphinx-revealjs v2とv3それぞれでテストを実行したくなりました。
- 1プロジェクトに複数の仮想環境を用意できるHatchで2つのテスト環境を用意
- pytestのマーカで、sphinx-revealjsのバージョンを見てスキップ
uvが圧倒的に注目されていますが、今回のユースケースは(私の知る範囲の)uv単体では難しくて7Hatchが輝く状況だったように思います。
とはいえ依存ライブラリのバージョンが異なるテスト環境を用意することは、そんなに頻繁にはないでしょう。
uvは速さとeasyさを重視しているように見える。
— nikkie(にっきー) / にっP (@ftnext) 2025年2月1日
プロジェクトごとの単一.venvを管理してくれる。
ただ速ければ何してもいいよねという態度にも思える
Hatchはsimple(組み合わせ)志向なのかな
プロジェクトにいくつもvenvを作って管理する(テスト用途や型チェック用途
ここのメンタルモデルが難しめ