メインコンテンツへスキップ

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__ok
  • test_load_yaml__missing_file
  • test_validate__min_ok
  • test_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_pathPath だと分かる
  • 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(普段使い)

  1. VS Code左の Testing(試験管アイコン) を開く
  2. テスト一覧が出る(tests/test_*.py が収集される)
  3. ▶(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標準出力/標準エラーのキャプチャ無効化です。

  • pytestprint() が見えない(基本)
  • pytest -sprint() が見える

用途は デバッグ用です。

常時 -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の「実行とデバッグ」から

    • pytest
    • pytest (-s) を選ぶだけ

普段は通常pytest、必要な時だけ -s を選べるので、運用が破綻しません。


✅ 方法3:settings.jsonで常時 -s(非推奨)

.vscode/settings.jsonpytestArgs-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」を切り替えるのが快適

以上の型を作っておけば、時間が空いてもすぐテスト運用に戻れる。