pytest でカオスエンジニアリングを始めるガイド

概要 「本番で障害が起きてから対処する」のではなく「テスト段階で意図的に障害を起こして耐性を確認する」カオスエンジニアリングの考え方を pytest に組み込む手法。@pytest.mark.chaos というカスタムマーカーで障害注入テストを分類・選択実行できる。 セットアップ マーカー登録 1 2 3 4 5 # pyproject.toml [tool.pytest.ini_options] markers = [ "chaos: カオスエンジニアリング関連のテスト(障害注入・耐性検証)", ] 選択実行 1 2 3 pytest -m chaos # カオステストのみ pytest -m "not chaos" # 通常の CI(カオステストをスキップ) pytest -m "chaos or integration" 主要な障害注入パターン ネットワーク障害 1 2 3 4 5 @pytest.mark.chaos def test_api_timeout_fallback(): with patch("app.client.requests.get", side_effect=TimeoutError): result = app.client.fetch_user_profile(user_id=123) assert result == app.client.get_cached_profile(user_id=123) データベース障害 1 2 3 4 5 6 @pytest.mark.chaos def test_db_connection_lost(): mock_primary = MagicMock(side_effect=ConnectionError("Connection lost")) with patch("app.db.get_primary_connection", mock_primary): result = app.db.query_user(user_id=123) assert result is not None # リードレプリカから取得 ランダム障害 Fixture(確率的注入) 1 2 3 4 5 6 7 8 9 10 11 @pytest.fixture def chaos_network(monkeypatch): """30% の確率でネットワーク遅延を注入""" original_get = requests.get def unstable_get(*args, **kwargs): if random.random() < 0.3: time.sleep(random.uniform(1.0, 5.0)) if random.random() < 0.1: raise ConnectionError("Chaos: connection refused") return original_get(*args, **kwargs) monkeypatch.setattr("requests.get", unstable_get) Django との統合 1 2 3 4 5 6 @pytest.mark.chaos @pytest.mark.django_db def test_cache_backend_failure(client): with patch("django.core.cache.cache.get", side_effect=Exception("Redis down")): response = client.get("/api/users/1/") assert response.status_code == 200 # キャッシュなしでも正常応答 CI/CD 組み込み(GitHub Actions) 1 2 3 4 5 6 7 8 9 10 11 12 13 name: Chaos Tests on: schedule: - cron: '0 3 * * 1' # 毎週月曜 AM3:00 jobs: chaos-test: runs-on: ubuntu-latest env: CHAOS_ENABLED: "1" steps: - uses: actions/checkout@v4 - run: pip install -r requirements-test.txt - run: pytest -m chaos --tb=long -v 通常 CI では pytest -m "not chaos" で高速に回し、週次スケジュールジョブでカオステストのみ実行する運用が推奨される。 ...

2026年4月23日 · 2 分

pytest.mark.chaos で始めるカオスエンジニアリング — Python テストに障害注入を組み込む

「本番で障害が起きてから対処する」のではなく、「テスト段階で意図的に障害を起こして耐性を確認する」。これがカオスエンジニアリングの基本思想だ。Python の pytest には、この考え方をテストコードに組み込むためのシンプルな仕組みがある。 pytest.mark.chaos とは @pytest.mark.chaos は、pytest のカスタムマーカー機能を使って「カオステスト」を分類するためのラベルだ。pytest にはビルトインのマーカー(@pytest.mark.skip、@pytest.mark.parametrize など)があるが、chaos はユーザーが自由に定義するカスタムマーカーに該当する。 1 2 3 4 5 6 7 import pytest @pytest.mark.chaos def test_network_timeout(): """ネットワークタイムアウト時にフォールバックが機能するか""" result = call_api_with_timeout(timeout=0.001) assert result == "fallback_response" マーカーの登録 カスタムマーカーは pyproject.toml または pytest.ini に登録しておくと、PytestUnknownMarkWarning 警告を抑制できる。 1 2 3 4 5 # pyproject.toml [tool.pytest.ini_options] markers = [ "chaos: カオスエンジニアリング関連のテスト(障害注入・耐性検証)", ] 選択実行 1 2 3 4 5 6 7 8 # カオステストだけを実行 pytest -m chaos # カオステスト以外を実行(通常の CI) pytest -m "not chaos" # カオステストと統合テストを実行 pytest -m "chaos or integration" これにより、通常の CI パイプラインではカオステストをスキップし、定期的なレジリエンス検証時にだけ実行するという運用が可能になる。 ...

2026年4月17日 · 5 分