Claude CodeにpytestのCLAUDE.md規約を教える
pytestのtest_*.py命名やTestプレフィックスは、CLAUDE.mdやパススコープ付きルールに書かないとClaude Codeが毎回守るとは限りません。具体的な書き方と点検ポイントをまとめます。
pytestプロジェクトでClaude Codeにテストを書かせると、test_*.pyという命名やTestプレフィックスのクラス名から外れたファイルができることがあります。CLAUDE.mdやパススコープ付きのルールファイルにpytestの検出規則とプロジェクト固有の運用を明文化しておくと、このブレを減らせます。ここでは具体的な書き方と、明文化しても効かないときの切り分けをまとめます。TyperのCLIをテストで完了判定する流れはClaude CodeでTyper製CLIを作るにあります。
CLAUDE.mdの指示はどこまで効くか
CLAUDE.mdはシステムプロンプトの一部ではなく、システムプロンプトの後に置かれるユーザーメッセージとして渡されます。Claudeはこれを読んで従おうとしますが、曖昧な指示や矛盾した指示は厳密に守られるとは限りません。公式は強制される設定ではなく文脈として扱い、「2スペースのインデントを使う」「コミット前にnpm testを実行する」のように検証できる粒度で書くよう勧めています。
Claude CodeはプロジェクトルートのCLAUDE.md(または./.claude/CLAUDE.md)を起動時に読み込みます。サブディレクトリの奥にあるCLAUDE.mdは起動時には読まれず、Claudeがそのディレクトリ配下のファイルを読んだときに追加されます。読み込まれたかどうかは、セッション中に/contextを実行して「Memory files」欄で確かめられます。
同じ考え方は他の言語にも通じます。Claude CodeでExcel VBAマクロを書く手順ではObject Modelの規約を、Claude CodeでVitestを回す手順ではwatchを避けるコマンドの書き方を扱っています。PLATEAUのCityGMLから建物属性を取り出す手順では、データ仕様の読み方をCLAUDE.mdに固定する例を紹介しています。
pytestが拾うもの、拾わないもの
CLAUDE.mdに規約を書く前に、pytestが既定で何をテストとみなすかを押さえます。ここを取り違えて書くと、指示そのものが誤りになります。
pytestの既定の収集規則
収集される
test_*.pyまたは*_test.pyというファイルtestで始まる関数とメソッドTestで始まり、__init__メソッドを持たないクラスunittest.TestCaseのサブクラス
収集されない
check_c.pyのような別名のファイルTestで始まらないクラスのメソッド(unittest.TestCaseを継承する場合を除く)__init__メソッドを持つTestクラスtestで始まらない名前の関数
この既定は設定で変えられます。ファイル名はpython_files、クラス名はpython_classes、関数名はpython_functionsが受け持ちます。python_filesの既定値は["test_*.py", "*_test.py"]です。たとえばプロジェクトのpytest.iniが次のようになっているとします。
[pytest]
python_files = test_*.py check_*.pyこの状態でCLAUDE.mdに「ファイル名はtest_*.pyに統一する」と書くと、設定と指示が食い違います。命名の正は設定ファイルなので、CLAUDE.mdには実際の値をそのまま書くか、設定の場所を指す書き方にします。
もう1つ、既定のimport mode(prepend)では、__init__.pyを置かない構成のテストファイル名が一意でなければなりません。tests/api/test_utils.pyとtests/db/test_utils.pyのように、別ディレクトリでも同名のファイルが並ぶと衝突します。pytestは新規プロジェクトにimportlibモードを勧めていますが、既定は歴史的経緯でprependのままです。Claudeが新しいテストファイルを足すときに踏みやすい点なので、命名ルールの一部として書く価値があります。
/initで叩き台を作ってから調整する
Claude Codeには、既存コードベースを解析してCLAUDE.mdの叩き台を作る/initコマンドがあります。ビルドコマンドやテストの実行方法、コードから読み取れる慣習を書き出すので、pytestプロジェクトならpytestという実行コマンドくらいは拾われる可能性があります。すでにCLAUDE.mdがある場合、/initは上書きせず改善案を示します。
拾えるのはコードから読み取れる範囲だけです。Testプレフィックスのクラスを使う方針なのか、assert文で統一するのかといったチームの方針は、/initのあとに手で書き足します。
pytestの運用ルールをCLAUDE.mdに書く
CLAUDE.mdに書くのは、pytestの仕様そのものではなく、その仕様を前提にした自分のプロジェクトの運用です。次のような節が出発点になります。
## テスト
- 実行コマンド: `pytest -q`
- ファイル名は `pytest.ini` の `python_files`(`test_*.py` と `check_*.py`)に従う
- 別ディレクトリでも同名のテストファイルを作らない(`__init__.py` を置いていないため)
- テストクラスを使う場合は `Test` から始まるクラス名にし、`__init__` は定義しない
- 新しいアサーションは `assert` 文を使う(`self.assertEqual` は使わない)
- 例外の送出を確認するテストは `pytest.raises` を使う
- 一時ディレクトリが必要なテストは `tmp_path` フィクスチャを使う
- 浮動小数点の比較には `pytest.approx()` を使うassert文を指定するのは、pytestが標準のassert文を書き換えて中間値まで報告する仕組み(Advanced assertion introspection)を持つためです。self.assertEqualのようなunittest由来の書き方を混ぜなくても、失敗時の情報量は変わりません。
テストをクラスにまとめる場合、テストごとにクラスのインスタンスが別々に作られるので、あるテストでself.value = 1と書いても次のテストには持ち越されません。一方でクラス直下の変数はインスタンス間で共有されます。状態を持ち越したくないときはインスタンス属性に閉じる、という方針も一言添えておけます。
プロジェクトにどんなフィクスチャがあるかは、次のコマンドで一覧できます。
pytest --fixturesこのコマンドをCLAUDE.mdに書いておくと、Claudeが新しいテストを書く前に既存のフィクスチャを調べる手がかりになります。
明文化しても従わないときの切り分け
指示が守られないときは、次の順に点検します。
守られない指示の点検順
- 1
指示が検証できる粒度か
「テストをちゃんと書いて」ではなく「新しいテストは
tests/直下にtest_*.pyで追加する」のように書き直します。 - 2
ファイルが読み込まれているか
/contextの「Memory files」欄に対象ファイルが出ているかを見ます。出ていなければ配置場所かパスの指定が誤っています。 - 3
指示が競合していないか
ネストしたCLAUDE.mdや
.claude/rules/に、同じ話題で異なる指示がないかを探します。ユーザー単位のルールとプロジェクトのルールが衝突した場合も、どちらに従うかは決まっていません。/doctor prompt-audit(v2.1.283以降)なら、矛盾する指示や存在しないファイルへの参照を報告してくれます。ファイルは、依頼するまで書き換えられません。 - 4
CLAUDE.mdが長すぎないか
公式の目安は1ファイル200行未満です。長いと文脈の消費が増え、遵守率が下がります。
@でファイルを取り込んでも、取り込んだ先も起動時に読み込まれるため、文脈の節約にはなりません。 - 5
いつ読み込まれたかを記録する
InstructionsLoadedフックを使うと、CLAUDE.mdやルールファイルがいつ、なぜ読み込まれたかをログに残せます。設定例は次のとおりです。
InstructionsLoadedは読み込みの観測用で、ブロックや書き換えはできません。次の設定は、遅延読み込み(path_glob_matchとnested_traversal)だけを/tmp/instructions-loaded.logに書き出します。
{
"hooks": {
"InstructionsLoaded": [
{
"matcher": "path_glob_match|nested_traversal",
"hooks": [
{
"type": "command",
"command": "jq -r '\"\\(.load_reason) \\(.file_path) \\(.trigger_file_path)\"' >> /tmp/instructions-loaded.log"
}
]
}
]
}
}フックにはJSONが標準入力で渡されます。jqの式をサンプルのJSONに当てると、1行にまとまります。たとえばpath_glob_match /p/.claude/rules/testing.md /p/tests/test_a.pyのように、読み込まれたルールとそのきっかけになったファイルが並びます。tests/配下のファイルを触ったのに該当ルールの行が出なければ、pathsのパターンがマッチしていません。
置き場所をCLAUDE.md、ルール、Skillで分ける
pytestの規約は、効かせたい範囲によって置き場所を変えられます。
規約の置き場所
CLAUDE.md
起動のたびに読み込まれます。実行コマンドや命名規則など、毎回効かせたい内容向きです。
paths付きの.claude/rules/
Read・Write・Editで該当ファイルを扱ったときに読み込まれます。
tests/配下だけに効かせたい書き方向きです。Skill
呼び出されたとき、またはClaudeが依頼に関係すると判断したときに読み込まれます。複数ステップの手順向きです。
CLAUDE.mdをSkillsへ移す判断基準はCLAUDE.mdをSkillsに移行してコストを削減する方法にまとめています。
.claude/rules/でtests配下だけに絞り込む
.claude/rules/にファイルを置き、YAMLフロントマターのpathsでスコープを絞ると、そのパターンに合うファイルをClaudeが扱ったときだけ読み込まれます。
---
paths:
- "tests/**/*.py"
---
# pytest規約
- ファイル名は `test_*.py`
- クラス名は `Test` プレフィックス必須
- アサーションは `assert` 文.claude/rules/testing.mdのような名前で置けば、.claude/CLAUDE.md本体の行数は増えません。pathsにはブレース展開が使え、"{tests,integration}/**/*.py"のように複数のディレクトリを1行で指定できます。
注意点が2つあります。pathsを持たないルールファイルは、.claude/CLAUDE.mdと同じ優先度で起動時に読み込まれます。パススコープ付きのルールが働くのは、ClaudeがRead・Write・Editのいずれかで一致するファイルを扱ったときで、ツールを使うたびではありません。
個人の実行環境の違いはCLAUDE.local.mdに逃がす
テスト用データベースのURLや、手元だけのテストデータの置き場所など、チームで共有しない設定はCLAUDE.local.mdに書きます。プロジェクトルートに置く個人用のファイルで、CLAUDE.mdと一緒に読み込まれ、同じディレクトリではCLAUDE.mdの後に追加されます。.gitignoreに加えて、バージョン管理から外します。
複数のgit worktreeを行き来する場合、.gitignore済みのCLAUDE.local.mdは作成したworktreeにしか存在しません。worktreeをまたいで共有したいときは、ホームディレクトリに置いたファイルを@~/.claude/my-test-settings.mdのように取り込みます。作業ディレクトリの外を指す取り込みは、プロジェクトで初めて出会ったときに承認ダイアログが出ます。断ると、そのプロジェクトでは取り込みが無効のままで、ダイアログも再表示されません。
モノレポや複数チームでの運用
Claude Codeは、作業ディレクトリとその上位にあるCLAUDE.mdをすべて連結して読み込みます。順序はファイルシステムのルート側から作業ディレクトリ側へで、作業ディレクトリに近いものほど後に読まれます。サブパッケージごとにpytestの使い方が違うモノレポなら、ルート直下に共通の実行コマンド、サブパッケージ側にそのパッケージ固有の命名規則、という分担ができます。
他チームのpytest規約まで混ざると、同じ話題で異なる指示が並び、Claudeがどちらかを恣意的に選ぶ状態になりかねません。他チームのCLAUDE.mdを対象から外すにはclaudeMdExcludesを使います。設定手順はclaudeMdExcludesの設定手順にあります。
CursorやClineなど他のAIコーディングツールも併用しているなら、規約をAGENTS.mdに置く運用があります。Claude Codeは、作業ディレクトリとその上位にCLAUDE.mdもCLAUDE.local.mdも無いときにAGENTS.mdを直接読みます(v2.1.277以降)。作業ディレクトリかその上位にCLAUDE.md(またはCLAUDE.local.md)が1つでもあると、AGENTS.mdは読まれません。その場合はCLAUDE.mdに@AGENTS.mdと書いて取り込みます。/configの「Project instructions」にあるclaude-md-and-agents-mdを選ぶと、CLAUDE.mdとAGENTS.mdを併読する設定にもできます。詳細はAGENTS.mdとCLAUDE.mdで設定を統合する運用パターンを参照してください。
まとめ
pytestの検出規則は既定値が決まっていて、プロジェクトのpython_filesなどの設定で上書きされます。そのためCLAUDE.mdには規則の写しではなく、設定の実際の値と、同名ファイルを作らないといった運用ルールを書き、守られないときは/contextとInstructionsLoadedフックで読み込みの有無から調べるのが近道です。
Claude Codeの基本的な設定と運用はClaude Code完全ガイド、テストが失敗したあとの解析はpytestの失敗をMCPサーバーでClaudeに解析させるにあります。Home Assistantカスタムコンポーネントのように必須キーの多い構成を持つ開発では、Claude CodeでHome Assistantのカスタムコンポーネントを作るも参考になります。