pytestをVS Codeで快適に運用する方法
🧭 はじめに
このページでは、Pythonプロジェクトで pytestをVS Code上で快適に使うための実践手順をまとめます。
対象は「忘れた頃に読み返して、すぐ同じ環境を再現したい」用途です。 単にpytestの使い方を説明するのではなく、
- どこにテストを置くべきか
- どう命名すべきか
- VS Codeでどう実行・デバッグするか
tmp_pathの中身をどう確認するか- 通常実行と
-s(print表示)をどう切り替えるか
まで含めて「運用の型」を作ります。
このページのゴールは、「pytestが動く」ではなく「pytestを普段使いできる状態にする」です。
📦 pytestのインストール方法
✅ 前提:venvを使う
pytestはプロジェクトごとに入れるのが基本です。
プロジェクトルートに .venv/ を作ります。
your-project/
.venv/
src...
tests...
venv作成(Windows / PowerShell)
python -m venv .venv
venv有効化(Windows / PowerShell)
.\.venv\Scripts\Activate.ps1
venv有効化(macOS/Linux)
source .venv/bin/activate
venvを作っていない状態でpytestを入れると、グローバル環境が汚れて将来のトラブル要因になりやすいです。
✅ pytestのインストール
venvを有効化した状態で実行します。
pip install pytest
インストール確認:
pytest --version
✅ requirements-dev.txt を作る運用(おすすめ)
「環境再現」のために、開発用依存を固定します。
requirements-dev.txt
pytest
インストール:
pip install -r requirements-dev.txt
requests / PyYAML など本体依存は requirements.txt、pytestなどは requirements-dev.txt に分離しておくと整理しやすいです。
🏷️ テスト関数の命名ルール(迷ったらこれ)
pytestは test_ で始まる関数を自動検出します。
✅ まずは一番基本
def test_xxx():
...
✅ おすすめ:__ 区切りで観点を分ける
テストが増えてくると、英単語を繋げた関数名が長くなりがちです。
__ を使うと、分類が一瞬で見えるようになります。
例:
test_load_yaml__oktest_load_yaml__missing_filetest_validate__min_oktest_validate__bad_book_id
pytestのテスト関数名は、落ちたときにそのまま原因特定の手がかりになるので、説明的であるほど価値があります。
✅ -k オプションで部分実行しやすい命名にする
pytestには名前で絞り込む機能があるため、命名がうまいほどデバッグ効率が上がります。
例:
pytest -k load_yaml
🗂️ 被テストコードとテストコードの配置(プロジェクトルート基準)
まず、プロジェクトルートは「テストも含めた箱」です。
✅ 推奨(小規模〜中規模の定番)
your-project/
bookstack_skeleton/
__init__.py
io.py
config.py
...
tests/
test_io.py
create_skeleton.py
ポイント:
tests/は パッケージ外(トップレベル) に置くbookstack_skeleton/の中にtests/を入れない → import解決がややこしくなりやすいtests/test_*.pyで自動収集される
tests配下のファイル名も test_*.py にするのが基本です。
✅ importはこう書く
テストでは「プロジェクトパッケージ」を普通にimportします。
from bookstack_skeleton.io import load_yaml
テスト内で相対import(from ..)はやらないのが基本です。テストは利用者の目線(public APIのimport)で書く方が強いです。
🧾 テストコードに含めると後で便利な docstring / 型アノテーション
pytestは「雑に書いても動く」ので、未来の自分が読めなくなるリスクがあります。 最低限これだけ入れておくと、後で修正が速いです。
✅ テスト関数のシグネチャに型を付ける
例:
from pathlib import Path
def test_load_yaml__ok(tmp_path: Path) -> None:
...
tmp_pathがPathだと分かる- IDE補完が効く
- 将来読み返した時に「これはfixture注入だな」と分かる
pytestでも型アノテーションは普通に有効で、特にファイル操作テストでは効きます。
✅ テスト関数docstringは「観点」だけで良い
テストコードは十分説明的になりがちなので、docstringは短いのが良いです。
def test_load_yaml__missing_file(tmp_path: Path) -> None:
"""異常系: ファイルが存在しない場合はInputError。"""
✅ ファイル先頭docstringで「テストケース一覧」を残す(おすすめ)
テストを増やすと「網羅性」が分からなくなります。 先頭に一覧を置くと、思考負荷が下がります。
tests/test_io.py 先頭例:
"""
テストケース一覧(pytest関数名):
- test_load_yaml__ok: 正常なYAMLはdictとして読める
- test_load_yaml__missing_file: ファイル無しはInputError
- test_load_yaml__parse_error: 壊れたYAMLはInputError
- test_load_yaml__root_not_dict: ルートがdict以外はInputError
- test_validate__min_ok: 最小構成で通る
- test_validate__pages_none: pages=Noneは空list扱い
- test_validate__bad_book_id: book_id不正はInputError
...
"""
この一覧はpytestの収集結果と一致するので、テストが落ちた時に逆引きしやすいです。
▶️ VS Codeでのテスト実行方法
VS Codeには2系統あります。
- Testing UI(試験管アイコン)
- ターミナル(pytestコマンド直打ち)
どちらか一方だけでもよいですが、使い分けると快適です。
✅ 方法A:Testing UI(普段使い)
- VS Code左の Testing(試験管アイコン) を開く
- テスト一覧が出る(
tests/test_*.pyが収集される) - ▶(Run Test)で実行
メリット:
- ファイルや関数単位でワンクリック実行できる
- 成功/失敗が視覚的に分かる
- 失敗箇所ジャンプが速い
VS Code側でpytestが認識されない場合、Python拡張機能が有効か、venvが選ばれているかを確認します。
✅ 方法B:ターミナル(確実・詳細制御)
プロジェクトルートで:
pytest
特定ファイル:
pytest tests/test_io.py
特定テストだけ:
pytest tests/test_io.py -k test_load_yaml__ok
📂 入出力ファイルの確認方法(tmp_path の中身を見る)
ファイルを扱うテストでは、一時ディレクトリが使われます。
pytestでは tmp_path fixture がよく使われます。
✅ tmp_path は自動生成される
def test_xxx(tmp_path: Path) -> None:
...
と書くと、pytestが テストごとに一時ディレクトリを作って渡します。
特徴:
- テスト間で衝突しない
- 毎回クリーンに開始できる
- 基本的にテスト終了後に掃除される
✅ 中身確認:printして -s で表示
tmp_path のパスとファイル一覧を出す例:
def test_load_yaml__ok(tmp_path: Path) -> None:
p = tmp_path / 'in.yaml'
p.write_text('book_id: 1\nchapters: []\n', encoding='utf-8')
print('tmp_path =', tmp_path)
print('files =', [x.name for x in tmp_path.iterdir()])
表示するには -s を付けます:
pytest -s
-sを付けない場合、pytestは print() を基本的に隠す(キャプチャする)ため、表示されません。
🧪 通常モードとデバッグオプション(-s)の切り替え方法(VS Code)
✅ -s の意味
-s は 標準出力/標準エラーのキャプチャ無効化です。
pytest→print()が見えない(基本)pytest -s→print()が見える
用途は デバッグ用です。
常時 -s にするとログが汚れるので、普段はオフが無難です。
🧰 VS Codeで -s を付けて実行する方法
✅ 方法1:ターミナルで実行(最短)
pytest -s
特定のテストだけ:
pytest -s tests/test_io.py -k test_load_yaml__ok
✅ 方法2:launch.jsonで「通常」「-s」を切り替える(おすすめ)
Testing UIは便利だけど、-s の切り替えはやりにくいです。
デバッグ実行メニューに2種類用意するのが強いです。
.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "pytest",
"type": "python",
"request": "launch",
"module": "pytest",
"args": ["tests"],
"console": "integratedTerminal"
},
{
"name": "pytest (-s)",
"type": "python",
"request": "launch",
"module": "pytest",
"args": ["-s", "tests"],
"console": "integratedTerminal"
}
]
}
使い方:
-
VS Codeの「実行とデバッグ」から
pytestpytest (-s)を選ぶだけ
普段は通常pytest、必要な時だけ -s を選べるので、運用が破綻しません。
✅ 方法3:settings.jsonで常時 -s(非推奨)
.vscode/settings.json で pytestArgs に -s を入れる方法もありますが、常時オンになるのでおすすめしません。
常時 -sにすると、printデバッグの残骸がCIや普段のテスト出力に混ざって読みにくくなります。
✅ 追加で入れておくと便利なpytest運用Tips
🧩 -k と -q は覚えておくと便利
-k: テスト名フィルタ-q: 出力を静かにする(quiet)
例:
pytest -q
pytest -k load_yaml
pytest -q -k validate
🧪 失敗した瞬間に止めたいなら -x
pytest -x
🔁 前回失敗だけ回すなら --lf
pytest --lf
開発中は --lf が強いです。修正→失敗テストだけ実行、のループが速くなります。
🧾 まとめ
- pytestは venvに入れる
- テストは
tests/に置き、関数名はtest_で始める - 命名は
__区切りで分類すると読みやすい tmp_pathはpytestが自動生成する一時ディレクトリprint()を見たいときはpytest -s- VS Codeでは
launch.jsonで「通常」「-s」を切り替えるのが快適
以上の型を作っておけば、時間が空いてもすぐテスト運用に戻れる。