自分は今日、テストを全件除外して、一時ファイルができるのを見た。unittest discover -k no_such_testで全件除外したのに、テストモジュールの先頭に置いた処理は動いていたんだよね。
Claude Codeにテストを任せるとき、コマンド名だけで実行を許可する運用は粗い。python -m unittestもリポジトリ内のコードを実行する。ファイルを1個作るだけで、その境目を確認した。
1件、0件、同じimport
テスト名で絞れば対象外の処理も避けられるのか。Python 3.14.8で確かめた。追加パッケージは不要。下のコードは一時ディレクトリで3通りのコマンドを回し、終了時にディレクトリごと消す。
from pathlib import Path
import subprocess
import sys
import tempfile
with tempfile.TemporaryDirectory() as d:
root = Path(d)
marker = root / 'imported.txt'
(root / 'test_probe.py').write_text(
'from pathlib import Path\n'
'import unittest\n'
'Path("imported.txt").write_text("imported")\n'
'class Probe(unittest.TestCase):\n'
' def test_ok(self):\n'
' self.assertEqual(1 + 1, 2)\n'
)
cases = [('通常', []), ('名前で除外', ['-k', 'no_such_test']),
('ファイルで除外', ['-p', 'absent_*.py'])]
for label, args in cases:
marker.unlink(missing_ok=True)
result = subprocess.run(
[sys.executable, '-m', 'unittest', 'discover', *args],
cwd=root, capture_output=True, text=True
)
print(f'{label}: exit={result.returncode}, import={marker.exists()}')
print(result.stderr.strip())
出力から、各ケースの先頭行を抜き出した。
通常: exit=0, import=True
名前で除外: exit=5, import=True
ファイルで除外: exit=5, import=False
| 指定 | 実行したテスト数 | imported.txt |
|---|---|---|
| 通常 | 1 | 作られた |
| -k no_such_test | 0 | 作られた |
| -p absent_*.py | 0 | 作られなかった |
0件のケースはNO TESTS RANで終了コード5。それでもファイルはできている。失敗扱いで止めても、副作用は戻らない。
unittestが名前を絞る前にやること
同梱のunittest/loader.pyも確認した。_find_test_path()でファイル名を照合し、_get_module_from_name()でimportする。その後、loadTestsFromModule()を経てgetTestCaseNames()でテスト名を絞る。
だから-kで落としたテストにも、モジュールを読み込む段階はある。Pythonファイルのトップレベルに置いた書き込みは、その段階で動く。今回の-pはファイル名が一致せず、検証用モジュールのimportまで進まなかった。
ただし、-pを安全装置として扱うのも早い。選んだファイルが別のモジュールをimportすれば、その先の処理も動く。パッケージの__init__.pyやload_testsも読み込み経路に入るので、ファイル名だけ追っても足りない。
これはunittestの処理順の検証で、Claude Codeの脆弱性を示すものではない。
コマンドを許可する前に見る範囲
テストを回す前に、対象ファイルとimport先まで見る。外から受け取ったコードなら、認証情報を渡さず、書き込み先を作業領域に絞り、外向き通信も必要な範囲に限定して実行する。仮想環境で依存パッケージを分けても、OSのファイルや通信は隔離できない。
一時ディレクトリ名はログで追いにくい。中のファイル名をimported.txtに固定しただけで、確認が楽だった。
テスト件数と、プロセスが実行した処理は分けて読む。0件の表示にも、importの副作用は隠れる。エージェントに任せる範囲が広がるほど、読むコードと渡す権限をセットでレビューする機会は増えると見ている。手元のテスト実行手順にも、import時の処理を確認する一手を足せる。