Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
pytest プラグインを開発して DRY に自動テストを書こう
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Atsushi Inutsuka
September 28, 2024
Programming
3
480
pytest プラグインを開発して DRY に自動テストを書こう
PyCon JP 2024 ミニトーク
Atsushi Inutsuka
September 28, 2024
Tweet
Share
Other Decks in Programming
See All in Programming
20260127_試行錯誤の結晶を1冊に。著者が解説 先輩データサイエンティストからの指南書 / author's_commentary_ds_instructions_guide
nash_efp
0
880
AIで開発はどれくらい加速したのか?AIエージェントによるコード生成を、現場の評価と研究開発の評価の両面からdeep diveしてみる
daisuketakeda
1
970
Spinner 軸ズレ現象を調べたらレンダリング深淵に飲まれた #レバテックMeetup
bengo4com
1
230
AIによる高速開発をどう制御するか? ガードレール設置で開発速度と品質を両立させたチームの事例
tonkotsuboy_com
6
1.7k
今から始めるClaude Code超入門
448jp
7
8.2k
Patterns of Patterns
denyspoltorak
0
1.3k
CSC307 Lecture 05
javiergs
PRO
0
490
Package Management Learnings from Homebrew
mikemcquaid
0
190
Grafana:建立系統全知視角的捷徑
blueswen
0
320
Automatic Grammar Agreementと Markdown Extended Attributes について
kishikawakatsumi
0
180
なるべく楽してバックエンドに型をつけたい!(楽とは言ってない)
hibiki_cube
0
140
TerraformとStrands AgentsでAmazon Bedrock AgentCoreのSSO認証付きエージェントを量産しよう!
neruneruo
4
2.7k
Featured
See All Featured
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
0
140
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
200
How to build a perfect <img>
jonoalderson
1
4.9k
It's Worth the Effort
3n
188
29k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
0
430
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.2k
Paper Plane (Part 1)
katiecoart
PRO
0
4k
Marketing to machines
jonoalderson
1
4.6k
How to Talk to Developers About Accessibility
jct
2
120
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
3.6k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
130
What does AI have to do with Human Rights?
axbom
PRO
0
2k
Transcript
pytest プラグインを開発して DRY に⾃動テストを書こう PyCon JP 2024 ミニトーク
⾃⼰紹介 2 ⽝束 敦史 (Atsushi Inutsuka) SNS GitHub : inuatsu
X : sekainoinuatsu エンジニアリングマネージャ @ シンプルフォーム株式会社 ⾦融機関などで、法⼈⼝座開設時などに実施が必要な「法⼈の審査業務」において使っていただく プロダクトを開発し、SaaS サービスとして提供しています
発表を聞いて持ち帰っていただける知識 pytest のプラグインを使って何ができるか pytest のプラグインの実装の具体例 例としてデータベースへの読み書きを伴う⾃動テストを並列実⾏する実装を取り上げます pytest のプラグインの動作を保証するためのテストの書き⽅
4 pytest プラグイン開発を考えた背景
直⾯していた課題 以下のような構成の Python ディレクトリがあると想定
直⾯していた課題 以下のような構成の Python ディレクトリがあると想定 ⾊々なところに conftest.py が ある状態になる
直⾯していた課題 開発者から以下のような声が上がるようになりました ディレクトリごとに同じような factory や conftest 記述するの無駄な気がしてきた ディレクトリによって conftest の書きっぷりが異
なっていて認知負荷が⾼め… conftest.py に毎回 MySQL のコンテナの設定周りで 同じようなコードを書いているの、何かしら共通化 できないだろうか
直⾯していた課題 開発者から以下のような声が上がるようになりました ディレクトリごとに同じような factory や conftest 記述するの無駄な気がしてきた ディレクトリによって conftest の書きっぷりが異
なっていて認知負荷が⾼め… conftest.py に毎回 MySQL のコンテナの設定周りで 同じようなコードを書いているの、何かしら共通化 できないだろうか ⇒ 確かに、同じようなコードを⾊々なところに書いているのは DRY じゃない気がする…🤔
発想 同じような factory や conftest.py を記述しているのであれば、テストを実装する際 共通で必要な前処理∕後処理をまとめた pytest プラグインを作ればよいのでは?
発想 同じような factory や conftest.py を記述しているのであれば、テストを実装する際 共通で必要な前処理∕後処理をまとめた pytest プラグインを作ればよいのでは? pytest
プラグインとは? pytest の機能を拡張するために、hook 関数を使って pytest の様々なイベントに 対して特定の処理を実⾏できるようにしたもの 例えば、カバレッジレポートを出すのに使う pytest-cov などもプラグインの⼀種
pytest プラグインで提供したい機能 以下のような処理を全てのディレクトリの conftest.py で書いていたので、 プラグインの機能として提供することを検討しました Docker で MySQL のコンテナを起動する
起動した MySQL コンテナが healthy になるまで待機する 起動した MySQL コンテナの DB にデータベースを作成する 起動した MySQL コンテナの DB セッションを提供する factory およびそのセッションを提供する テストメソッドごとにデータベースのトランザクションを rollback する
12 pytest プラグインの実装準備
ディレクトリ構成 cookiecutter-pytest-plugin などを参考に、以下のようなディレクトリ構成にします libs ディレクトリ内に pytest-common というディレ クトリを追加
プラグインをインストールできるようにする pytest は、pytest11 というエントリポイントを探してプラグインを発⾒するので、 エントリポイントを提供する必要があります ◦ Poetry を使っている場合、プラグインのディレクトリの pyproject.toml に以下の記述を
追加します
15 pytest プラグインの機能開発
プラグインで提供する機能 先ほど⾔及した内、太字の 3 つに絞って具体的な実装を紹介します Docker で MySQL のコンテナを起動する 起動した MySQL
コンテナが healthy になるまで待機する 起動した MySQL コンテナの DB にデータベースを作成する 起動した MySQL コンテナの DB セッションを提供する factory およびそのセッションを提供する テストメソッドごとにデータベースのトランザクションを rollback する
データベースアクセスを伴うテスト 今回は、データベースアクセスを伴うテストはコンテナでデータベースを起動して、 コンテナ上のデータベースにアクセスしてテストをすることを前提とします データベースアクセスを伴うテストを実⾏する場合、テストケースの数が増えると テストにかかる時間が⻑くなることが懸念されます テストを並列実⾏できるようにすることで、必要に応じてテスト時間を短縮できるように します
テストの並列実⾏ DB アクセスを伴うテストがあると、pytest-xdist などのプラグインを使って並列実⾏ しても、他プロセスで書き込まれたレコードによりテスト結果が変わり得ます プロセス間でテスト結果に影響を与えない⼯夫として以下の⽅針を採⽤ ⼀つの MySQL コンテナ内に複数のデータベースを作成し、各プロセスがテスト実⾏中に 固有のデータベースを使うようにすることで、並列実⾏時のプロセス間の独⽴性を担保
MySQL コンテナの起動
MySQL コンテナの削除 ローカルで実⾏する時にテスト実⾏時間を少しでも短縮できるよう、 VOLUME_CLEANUP の環境変数を設定していたらコンテナを削除する際に ボリュームを削除しないように実装
単⼀プロセス∕複数プロセスでの MySQL コンテナ起動∕削除 単⼀プロセスか複数プロセスかにより条件分岐します pytest-xdist をインストールすると、単⼀プロセスで起動する場合 worker_id fixture が "master"
の値を返すので、それにより単⼀プロセスであることを判定 複数プロセスの場合、pytest-xdist を使うと session スコープの fixture は テストプロセスごとに実⾏されるため、複数回実⾏されてしまいます pytest-xdist のドキュメントで、filelock を使って session スコープの fixture が⼀度だけ 実⾏されるように保証する⽅法が紹介されているので、それを参考に実装
単⼀プロセス∕複数プロセスでの MySQL コンテナ起動∕削除
データベース作成 pytest-xdist では session スコープの fixture はプロセスごとに実⾏されることに ⾔及しましたが、その性質を使うことでプロセスごとに固有のデータベースを 作成して使う実装を実現できます pytest-xdist
を使うと、各テストプロセスで PYTEST_XDIST_WORKER という環境変数に ワーカ名が定義されます この性質を使い、test_db_{ワーカ名} という命名ルールでデータベースを作成し、 テストプロセス内でそのデータベースで DB セッションを提供するようにします。
データベース作成
25 pytest プラグインの⾃動テスト
テストを書くのに使えるプラグイン pytest には pytester というプラグインがあり、プラグインのコードのテストを 書くのに活⽤できます ◦ pytester はデフォルトでは無効になっており、tests ディレクトリ内の
conftest.py に 以下の記述をすることで有効化できます。 ◦ pytester では⼀時的な conftest.py やテストファイルを作成する API が提供されており、 それを活⽤することでプラグインの動作を検証することができます。
実際にテストを書いてみる
28 pytest プラグインの導⼊
プラグインのインストール 導⼊したいディレクトリでプラグインをインストールするだけで、プラグインに 実装されている fixture が使えるようになります ◦ Poetry で依存を管理している場合のインストールコマンド例 ◦ プラグインの中に書いた
fixture は⾊々なプロジェクトディレクトリの conftest.py に 書く必要がなくなり、テストの前処理、後処理を DRY に書くことができます
テスト実⾏時にプラグインが有効になっていることの確認⽅法 テスト実⾏時に最初に表⽰されるログにおいて、今回実装したプラグインの名前が plugins の箇所に表⽰されていれば、プラグインが有効になっています
31 まとめ
まとめ 1. ⾃分が管理するプロジェクトで導⼊できる pytest のプラグイン、意外と簡単に 作ることができます 2. ⾊々なディレクトリで conftest.py を書いていて、同じようなテストの前処理∕
後処理を全ての conftest.py で書いてしまっているな…という⽅は、 pytest のプラグインを⾃分で書いてみてはいかがでしょうか