Movatterモバイル変換


[0]ホーム

URL:


じゃあ、おうちで学べる

本能を呼び覚ますこのコードに、君は抗えるか

AI時代の異常系テストについて考える

はじめに

深夜2時、本番環境のアラートが鳴り響きます。外部APIタイムアウトを返し始め、リトライが暴発し、システム全体が連鎖的に停止しました。原因を調べると、外部サービスの一時的な遅延でした。たった数秒の遅延が、なぜシステム全体を止めたのか。答えは単純です。「外部APIが遅延したらどうなるか」を、誰もテストしていなかったからです。

私自身、このような障害を何度か経験してきました。コードをマージした翌朝にSlackが炎上していたこともあります。「なぜこのケースを考えなかったのか」と自分を責めながら、ホットフィックスを書いた夜もあります。そのたびに思います。あのとき、たった1つのテストを書いていれば。

これは「異常系テスト」の不足が引き起こした障害です。正常系のテストは比較的書きやすいです。入力があり、期待する出力があり、それを検証します。しかし、プロダクション環境で本当に問題になるのは異常系です。ネットワークが切断されたとき、システムはどう振る舞うべきか。データベースがタイムアウトしたとき、ユーザーには何を伝えるべきか。想定外の入力が来たとき、エラーメッセージは適切か。こうした問いに答えるのが、異常系テストです。

そして今、この異常系テストの世界が大きく変わりつつあります。2024年、AIがOpenSSLに20年間潜伏していた脆弱性を発見しました。人間が書いたファジング(ランダムなデータを入力してバグを探す手法)では見つけられなかった欠陥です。GoogleOSS-FuzzはAIによるファズターゲット生成で26件の脆弱性を発見し、既存の人間作成ターゲットから最大29%のカバレッジ向上を実現しました。人間だけでは見つけられなかった異常を、AIが発見する時代になりました。

本記事では、この変化を踏まえて異常系テストの考え方をまとめました。まず基本的な技法を押さえ、その上でAIやカオスエンジニアリングといったものを紹介します。あの深夜のアラートを、未来の自分や読者が経験しなくて済むように。

本題に入る前に

本記事を読む前に、いくつか断っておきたいことがあります。

私はテストの専門家ではありません。日々コードを書きながら、「この処理が失敗したらどうなるだろう」と考える、一人のエンジニアです。ここに書いてあることは、思いついたものをまとめただけなので不足もあるでしょう。実装しながら単体テストやエラーハンドリングを考える際のヒントとして使ってもらえればと思います。

もう一つ、大事なことがあります。すべてのパターンをテストする必要はありません。過度なテストパターンは無駄な工数を生むだけではありません。テストが増えれば増えるほどCIの実行時間は長くなり、開発サイクルは遅くなります。テストコードを読んで理解するにも認知コストがかかります。テストが多すぎると、「このテストは何を確認しているのか」を把握するだけで疲弊してしまいます。

テストのROI(投資対効果)を意識し、リスクの高い箇所に集中することが重要です。とはいえ、最近は生成AIのモデル精度が上がったおかげで、文脈を読み取ってテストコードを生成してくれるようになりました。「何をテストすべきか」を判断し、AIに生成を任せる。その使い分けが、今のエンジニアに求められています。

そして、ここが難しいところなのですが、異常系テストがどれくらい必要かは、その人の経験に大きく依存します。本番障害で痛い目を見た人は「ここまでテストすべきだ」と感じます。幸運にも大きな障害を経験していない人は「そこまでやる必要があるのか」と思います。これは良い悪いではなく、思考の枠組みそのものが異なるのです。だからこそ、チームとして、組織として「どこまでの異常を許容するのか」を明確にしておく必要があります。暗黙の了解ではなく、言語化する。そうしないと、「テストが多すぎる」「テストが足りない」という不毛な議論が続くことになります。

では、本題に入りましょう。

異常系テストとは

異常系テストとは、システムが想定外の状況に遭遇したとき、適切にエラーハンドリングできるかを検証するテストです。正常系テストが「うまくいくパス」を確認するのに対し、異常系テストは「うまくいかないパス」を確認します。

異常系と一口に言っても、その原因はさまざまです。「どこから異常が来るか」という視点で整理すると、4つの観点に分けられます。

  • 入力値の異常: ユーザーやクライアントから来ます。空文字、境界値超過、不正な形式など
  • 状態の異常: システム内部のデータに起因します。リソースが見つからない、すでに処理済み、権限不足など
  • 環境の異常: 外部依存に起因します。ネットワーク障害、DB接続失敗、ディスク容量不足など
  • 競合の異常: 並行処理に起因します。同時更新、デッドロック、レースコンディションなど

この順番には意味があります。入力値の異常は最も頻繁に発生し、テストも書きやすいです。状態の異常はビジネスロジックと密接に関わります。環境の異常はテストが難しいですが、本番では必ず起きます。競合の異常は最も見つけにくく、再現も難しいです。つまり、テストの書きやすさと、問題の発見しにくさは、おおむね逆の関係にあります。

それぞれについて見ていきましょう。

入力値の異常

フォームに全角スペースだけを入力して送信したら、システムがエラーを吐いた。そんな経験はないでしょうか。あるいは、絵文字を含む名前を登録しようとしたら、データベースエラーが返ってきた。ユーザーは悪意を持っていたわけではありません。ただ、開発者が「想定していなかった」だけです。どれだけ想像力を働かせても、ユーザーは必ずその想像の外側から来ます。

ユーザーからの入力は信用できません。これはセキュリティの基本原則ですが、テストにおいても同様です。

境界値分析(Boundary Value Analysis)

境界値分析は、ソフトウェアテストの古典的な技法です。入力値の境界付近でエラーが発生しやすいという経験則に基づいています。

# 例: 文字数制限が255文字の場合- 255文字 → 成功するべき- 256文字 → エラーになるべき- 0文字(空文字) → 要件による

よくある境界値のテストケース:

  • 最大値・最小値
  • 最大値+1・最小値-1
  • ゼロ
  • 負の値(許可されていない場合)

この技法は同値分割法(Equivalence Partitioning)と組み合わせて使うことが多いです。同値分割法では、入力値を「同じ振る舞いをするグループ」に分割し、各グループから代表値を選んでテストします。たとえば「1〜255文字」「256文字以上」「0文字」の3グループに分け、それぞれの代表値と境界値をテストします。

現代のAPI開発では、境界値分析の対象は数値入力を超えて拡張されています。APIのページネーション制限(page size=99, 100, 101)、リクエストペイロードサイズ制限、タイムアウト閾値、レートリミットの境界などが現代的なBVA対象です。

空値の扱い

境界値の中でも、特に扱いが難しいのが「空」という概念です。空値の扱いは設計上の判断が必要になります。

検討ポイント
空文字"" 許容するか、エラーにするか
スペースのみ" " トリムするか、エラーにするか
NULL 必須項目か、オプショナルか
undefined デフォルト値を使うか

テストを書くことで、こうした設計の曖昧さが明確になることがあります。「空文字を許容するか」という問いに対して、チームで合意を取る機会になります。

ここで気づくべき重要なことがあります。

異常系テストの気付きにくい価値は、バグを見つけることではありません。設計を問い直すことです。

「この入力が来たらどうするか」という問いを立てることで、仕様の穴が見えます。テストを書く行為そのものが、システムの堅牢性を高めています。テストが通るかどうかは、実は二次的な問題なのです。

文字種と特殊文字

空値に続いて、もう一つ厄介なのが文字種です。日本語を扱うシステムでは、文字種のテストが特に重要になります。

  • カタカナ・半角カタカナ
  • 環境依存文字(㈱、①など)
  • サロゲートペア(𠮷野家の「𠮷」など)
  • 絵文字

これらの文字が入力されたとき、システムがどう振る舞うかを確認します。データベースの文字コード設定やAPIエンコーディングによっては、予期しない動作をすることがあります。

セキュリティ関連の入力

ここまでは「意図しない入力」の話でした。しかし、世の中には「意図的に悪意のある入力」を送りつけてくる人もいます。セキュリティ関連の入力値テストは、インジェクション攻撃(悪意のあるコードを入力に紛れ込ませる攻撃)への耐性を確認します。OWASP Testing Guideは、このようなセキュリティテストの標準的な指針を提供しています。

インジェクション攻撃への対策はセキュリティテストの領域でもありますが、異常系テストとして「不正な入力が来たときにシステムが適切にエラーを返すか」を確認しておくことは重要です。

エラー推測(Error Guessing)という経験ベースの技法も有効です。過去のバグ傾向から共通パターン(NullPointerException、ゼロ除算、日時パース問題など)を識別し、重点的にテストします。

AIとファジングによる入力値テスト

ここまで紹介した技法は、人間がテストケースを考えるものでした。しかし、人間の想像力には限界があります。そこで注目されているのが、ランダムな入力を自動生成してバグを探すファジング(Fuzzing)です。

冒頭で触れたGoogleOSS-FuzzのAI活用は、まさにこの領域での成果です。AIが生成したファズターゲットにより26件の脆弱性が発見され、OpenSSLに20年間潜伏していた欠陥も見つかりました。人間が「こういう入力が来るかも」と想像する範囲を超えて、AIが異常な入力パターンを生成します。

www.theregister.com

もう一つ、Property-based testing(性質ベーステスト)という手法も企業での採用が加速しています。従来のテストは「入力Aに対して出力Bが返る」という具体的なペアを書きます。Property-based testingでは「どんな入力に対しても、この性質が成り立つ」という形で定義します。たとえば「リストをソートして逆順にしても、要素数は変わらない」といった性質です。

Python向けのHypothesisは週間300万ダウンロードを超え、numpyやastropyなどの科学ライブラリでバグを発見した実績があります。QuickCheckHaskell)、fast-check(JavaScript)、proptest(Rust)など、各言語でエコシステムが成熟しています。

入力値の異常は、ユーザーから直接来るものでした。次に見るのは、システムの内部で起きる異常です。

状態の異常

「さっきまで動いていたのに」。この言葉に覚えはないでしょうか。ユーザーが画面を開いている間に、別のユーザーがデータを削除します。システムの状態は常に変化しています。画面に表示された瞬間、それはもう過去です。

リソースの状態に関するテストでは、以下のようなケースを考慮します。

存在しないリソース

存在しないIDでアクセスしたときに、適切なエラー(404 Not Foundなど)が返ることを確認します。

削除済みリソース

削除されたリソースに再度アクセスしたときの動作を確認します。ユーザーがブックマークしていたページが、管理者によって削除されていた。よくある話です。「404 Not Found」で終わりなのか、「このコンテンツは削除されました」と丁寧に伝えるのか。論理削除と物理削除では挙動が異なります。論理削除なら「削除済み」というステータスを返せます。物理削除ならレコード自体が存在しないため、404を返すことになります。どちらの設計を採用しているかで、テストの期待値も変わります。

処理中のリソース

処理中(アップロード中、変換中など)のリソースにアクセスしたときの動作を確認します。「まだ準備ができていない」ことをクライアントに適切に伝えられるか。

不正な状態遷移

状態遷移が定義されているシステムでは、不正な遷移を試みたときの動作を確認します。

# 例: 注文のステータス遷移作成 → 確定 → 発送 → 完了# 不正な遷移作成 → 完了(確定と発送をスキップ)完了 → 作成(逆方向の遷移)

入力値の異常、状態の異常は、どちらもアプリケーション内部の話でした。しかし、システムは単独で動いているわけではありません。次は、システムの外側から来る異常を見ていきます。

環境の異常

環境の異常は、テストが最も難しい領域です。開発環境では再現しにくいですが、プロダクション環境では必ず発生します。ローカルで動いたからといって、本番で動く保証はありません。開発環境は、ある意味で嘘をつきます。ネットワークは常に安定し、データベースは常に応答し、ディスクは無限にあります。そんな理想的な環境でテストしても、現実の障害には備えられません。だからこそ、どういう異常が起こりうるかを知っておくことが重要です。

近年ではChaos Engineering(カオスエンジニアリング)という手法が注目されています。Netflixが提唱したこのアプローチでは、本番環境に意図的に障害を注入し、システムの回復力を検証します。AWS Fault Injection ServiceAzure Chaos Studioといったクラウドサービスも登場しています。これは上級者向けの手法ですが、まずは以下のような基本的な異常パターンを理解しておきましょう。

ネットワーク障害

対応方法としては、タイムアウト設定、リトライ、サーキットブレーカーなどがあります。サーキットブレーカーとは、外部サービスへのリクエストが連続して失敗したとき、一時的にリクエストを遮断する仕組みです。電気のブレーカーが過電流を検知して回路を遮断するのと同じ発想で、障害の連鎖を防ぎます。

データベース障害

対応方法としては、コネクションプールの適切な設定、リトライ、タイムアウトなどがあります。

外部サービス障害

  • API応答不可
  • レートリミット
  • 予期しないレスポンス形式

対応方法としては、サーキットブレーカー、フォールバック、キャッシュなどがあります。

リソース枯渇

リソース枯渇は、テストで再現するより監視とアラートで早期に検知する方が現実的です。とはいえ、リソースが枯渇したときにシステムがどう振る舞うか(gracefulに停止するか、エラーメッセージを出すか)は、設計段階で決めておく必要があります。

カオスエンジニアリングの実践

「本番環境に障害を注入する? 正気か?」。最初は誰もがそう思います。しかし、問いを変えてみましょう。「本番で障害が起きたとき、それが予期せぬものであることと、計画されたものであること、どちらがマシか?」

カオスエンジニアリングの市場規模は2025年に23.6億ドル、2030年には35.1億ドルに達すると予測されています。もはやニッチな手法ではなく、エンタープライズ標準になりつつあります。

www.mordorintelligence.com

Kubernetes環境ではLitmusChaosChaos Meshが代表的なツールです。LitmusChaosはCNCFインキュベーティングプロジェクトとして活発に開発が続いています。Chaos MeshはPodChaos、NetworkChaos、IOChaos、StressChaosなど多様な障害タイプを提供します。

hub.litmuschaos.io

GameDay(計画的なカオス実験演習)の実践も広がっています。まず最小の爆発半径(障害の影響範囲)から開始し、単一コンテナ→サービス→ゾーンと段階的にスケールアップします。本番環境を最初のターゲットにしてはなりません

レジリエンスパターン

環境の異常に備えるには、コードにレジリエンスパターンを組み込む必要があります。先に紹介したサーキットブレーカーに加え、以下のパターンが重要です。

  • Bulkhead(バルクヘッド): 船の隔壁のように、リソースを区画化して一部の障害が全体に波及することを防ぎます
  • Retry with Exponential Backoff(指数バックオフ付きリトライ): 失敗したら1秒後、2秒後、4秒後…と間隔を広げてリトライします。リトライストームを防止しながら一時的障害から回復します

これらのパターンを実装したら、カオスエンジニアリングで実際に障害を注入し、期待通りに動作するか検証します。パターンを実装しただけでは不十分で、テストして初めて信頼できます。

ここまで、入力値、状態、環境の異常を見てきました。最後に残るのは、最も厄介な異常です。複数のユーザーが同時にシステムを使うときに起きる問題、競合の異常です。

競合の異常

「ローカルでは動いたのに」。開発者なら誰もが経験するこの言葉の裏には、しばしば競合の問題が潜んでいます。開発環境では自分一人しかアクセスしません。しかし本番環境では、何百人ものユーザーが同時にボタンを押します。本番は、常に渋滞しています。その渋滞の中で、単体テストでは見えなかった問題が姿を現します。

複数のユーザーやプロセスが同時にリソースにアクセスすると、競合が発生しえます。これは単体テストでは見つけにくく、負荷テストや本番環境で初めて発覚することも多いです。だからこそ、「競合が起きたらどうなるか」を事前に設計しておくことが重要です。

同時更新

典型的なシナリオを考えてみましょう。

1. ユーザーAがデータを取得2. ユーザーBが同じデータを取得3. ユーザーAが更新を実行4. ユーザーBが更新を実行 → どうなるべきか?

ユーザーBの更新時点で、データはすでにユーザーAによって変更されています。このとき、システムはどう振る舞うべきでしょうか。主な対応方法は3つあります。

  • 楽観的ロック: データ取得時にバージョン番号を記録し、更新時に照合します。バージョンが変わっていれば「誰かが先に更新した」と判断し、後から更新しようとした側にエラーを返します
  • 悲観的ロック: 更新する意思を示した時点で排他ロックを取得し、他者は同じデータを更新できなくなります。確実ですが、ロック待ちによる遅延が発生しえます
  • 最後の更新が勝つ: 競合を検出せず、後から来た更新で上書きします。シンプルですが、先の更新は失われます

どの方法を採用するかは、ビジネス要件によります。在庫数のように「先の更新が失われると困る」データには楽観的ロックか悲観的ロック、ユーザーのプロフィールのように「最新の状態が正」でよいデータには最後の更新が勝つ方式、といった使い分けになります。

ボタン連打

UIにおいて、ユーザーがボタンを連打した場合の動作を確認します。「送信ボタンを押したけど反応がない。もう一度押そう」。ユーザーは待ってくれません。ネットワークが遅いとき、ボタンが反応しないとき、人は本能的に連打します。「購入する」ボタンを連打したら2回購入されてしまった、という事故は避けたいところです。

対応方法としては、デバウンス(一定時間内の連続クリックを1回とみなす)や、送信中はボタンを無効化する二重送信防止の仕組みがあります。サーバー側でも、同一リクエストを検出するためにリクエストIDを使った冪等性の担保を検討します。


ここまで、4種類の異常(入力値、状態、環境、競合)を見てきました。これらの異常が発生したとき、システムは何らかのエラーを返す必要があります。では、どのようなエラーを返すべきでしょうか。次は、エラーレスポンスの設計について考えていきます。

エラーレスポンスの設計

異常系テストでは、「エラーが起きないこと」ではなく「適切なエラーが返ること」を検証します。エラーレスポンスの設計は、クライアント側のエラーハンドリングに大きく影響します。適切なエラーを返せば、呼び出し側は何が起きたかを判断し、適切に対処できます。

ステータスコードの使い分け

ステータスコードとは、サーバーがクライアント(ブラウザやアプリ)に返す3桁の数字です。この数字を見れば、リクエストが成功したのか、失敗したのか、何が原因なのかが分かります。

HTTPの場合

  • 400 Bad Request: 入力値が不正
  • 401 Unauthorized: 認証失敗(ログインが必要)
  • 403 Forbidden: 権限不足(ログイン済みだがアクセス権がない)
  • 404 Not Found: リソースが存在しない
  • 409 Conflict: 競合(同時更新など)
  • 429 Too Many Requests: レートリミット(リクエストが多すぎる)
  • 500 Internal Server Error: サーバー内部エラー
  • 503 Service Unavailable: サービス利用不可(メンテナンス中など)

gRPCの場合(gRPCはGoogleが開発した高速な通信方式):

  • INVALID_ARGUMENT: 入力値が不正
  • NOT_FOUND: リソースが存在しない
  • ALREADY_EXISTS: リソースが既に存在
  • FAILED_PRECONDITION: 前提条件不成立
  • PERMISSION_DENIED: 権限不足
  • RESOURCE_EXHAUSTED: リソース枯渇

セキュリティ観点でのエラー設計

他ユーザーのリソースへのアクセスには、エラーコードの選び方に注意が必要です。ここには、多くの開発者が見落としている盲点があります。

素直に考えると、「存在するが権限がない」なら403 Forbiddenを返したくなります。HTTPの仕様としては正しいです。しかし、これには問題があります。攻撃者がIDを総当たりで試したとき、403が返れば「このIDのリソースは存在する」と分かってしまいます。つまり、正しいエラーコードを返すことが、セキュリティホールになるという逆説です。

そこで、他ユーザーのリソースへのアクセスには404 Not Foundを返すという設計があります。「存在するが権限がない」と「存在しない」を区別できないようにすることで、攻撃者に情報を与えません。GitHubのプライベートリポジトリも、この設計を採用しています。権限のないリポジトリにアクセスすると、「存在しない」と表示されます。

これは「嘘をつく」のではなく、「必要以上の情報を与えない」という設計です。エラーメッセージは親切であるべきですが、攻撃者にも親切である必要はありません。


異常の種類と、返すべきエラーレスポンスが分かりました。では、実際にどうやってテストを書けばいいのでしょうか。ここからは、異常系テストの書き方について説明します。

テストの書き方

期待するエラーの検証

異常系テストで最も基本的なのは、「期待するエラーが返ること」の検証です。正常系では「期待する結果が返ること」を確認しますが、異常系では「期待するエラーが返ること」を確認します。

# 例: 存在しないリソースへのアクセスで404が返ることを検証deftest_get_not_found():    response = client.get("/resources/nonexistent-id")assert response.status_code ==404

テストの独立性

各テストは独立して実行できるようにします。テスト間でデータを共有しません。

# テストごとに一意のIDを使用TEST_ID="test-$(date +%s)"

クリーンアップ

テスト終了後は作成したリソースを削除します。テストデータが残っていると、次回のテスト実行に影響を与える可能性があります。

テストピラミッドにおける異常系テスト

Mike Cohnの伝統的なテストピラミッド(ユニット→インテグレーション→E2E)では「各要件に対し少なくとも2つのテスト、1つは正常系、1つは異常系」が原則です。Kent C. Doddsの「Testing Trophy」モデルでは、インテグレーションテストを重視します。「テストがソフトウェアの使用方法に似ているほど、より多くの信頼を与える」という原則のもと、インテグレーションテストはユニットテストが見逃すエラー(コンポーネント間の相互作用問題)を捕捉します。

AIによるテスト生成

「テストケースを考えるのが面倒」「どこまでカバーすればいいか分からない」。そんな悩みを抱えたことはないでしょうか。AIによるテスト生成は、この問題に一つの解を与えます。

NVIDIAのHEPHフレームワークはLLM(大規模言語モデル)を用いてドキュメントからテストを自動生成します。Diffblue CoverはJavaコードの静的解析からユニットテストを生成します。qodo(旧Codium)はコード動作を分析してエッジケースを含むテストケースを生成します。これらのツールはエラーシナリオ、境界条件、例外処理パスを自動的に導出します。

ただし、AIが生成したテストをそのまま使うのは危険です。「何をテストすべきか」の判断は人間がすべきであり、AIはその実装を支援するツールに過ぎません。

テストの質を検証する:Mutation Testing

テストを書きました。カバレッジも高いです。しかし、そのテストは本当にバグを見つけられるのでしょうか。

Mutation testing(変異テスト)は、コードに意図的なバグを埋め込み、テストがそれを検出できるか評価する手法です。たとえばif (x > 0)if (x >= 0)に変更します。この変更をテストが検出できなければ、そのテストには穴があります。

PITest(Java)、Stryker Mutator(JS/TS/C#)、cargo-mutants(Rust)などのツールがCI/CDへの統合を進めています。cargo-mutantsはRustConf 2024で発表され、ソースコード変更なしで任意のRustプロジェクトに適用できます。

speakerdeck.com

異常系テストの優先順位

すべての異常をテストする時間はありません。リスクベースで優先順位をつけます。

  • Priority 1(毎スプリント): セキュリティ敏感入力(SQLインジェクションXSS)、金融・トランザクション操作、認証・認可障害
  • Priority 2(毎リリース): コアビジネス機能のエラーパス、統合ポイント障害、境界値違反
  • Priority 3(定期テスト: 複雑なエラーハンドリングフロー、二次機能のエッジケース
  • Priority 4(メジャーリリース前): 安定したレガシー機能、低トラフィック機能のエラーハンドリング

まとめ

異常系テストは「何が起きたら困るか」を事前に洗い出し、システムが適切に対処できることを検証する作業です。

本記事で紹介した内容を振り返ると、以下の5点が重要になります。

  1. すべてをテストする必要はない - リスクの高い箇所に集中します。テストにもROIがあります。チームで「どこまでの異常を許容するか」を言語化しておきましょう
  2. AIとツールを活用する - ファジング、Property-based testing、Mutation testingなど、人間の想像力を超える異常を発見する手法があります。AIによるテスト生成も現実的な選択肢になりました
  3. 環境の異常にはカオスエンジニアリング - 本番環境で必ず起きる障害を、事前に計画して注入します。レジリエンスパターン(サーキットブレーカー、バルクヘッド、指数バックオフ)を実装し、実際にテストします
  4. セキュリティ観点を忘れない - エラーメッセージやエラーコードが情報漏洩につながることがあります。403と404の使い分けはその典型例です
  5. テストを書くことで設計が明確になる - 「空文字を許容するか」「同時更新をどう扱うか」といった曖昧だった仕様が、テストを書く過程で具体化されます

異常系テストは面倒に感じることもあります。しかし、プロダクション環境で障害が発生してから対処するコストに比べれば、事前にテストを書くコストは安いです。深夜2時のアラート対応、原因調査、ホットフィックス、ポストモーテム。そのすべてを、1つのテストが防いでくれることがあります。

障害が起きたら、その教訓をテストとして残す。それが本当の意味での振り返りです。

異常系テストは、将来の自分を助けるための投資です。3ヶ月後の深夜2時、アラートが鳴らなかったとき、過去の自分へ感謝するでしょう。

明日からできること

大げさに考える必要はありません。次にコードを書くとき、1つだけ試してみてください。

「この処理が失敗したら、何が起きるか」を考える。

その問いを立てるだけで、異常系テストは始まっています。APIを呼ぶコードを書いたら、「このAPIタイムアウトしたらどうなるか」と考えます。データベースに保存するコードを書いたら、「保存に失敗したらどうなるか」と考えます。その問いに対する答えをテストとして書く。それだけでいいのです。

完璧を目指す必要はありません。昨日より1つだけ、システムを堅牢にする。その積み重ねが、深夜のアラートを1回減らし、ユーザーの信頼を1つ守ります。今日書いた1つのテストが、3ヶ月後の深夜2時を救います。AIがテスト生成を支援してくれる時代だからこそ、この「問いを立てる力」は人間にしかできない価値になります。

3ヶ月後の深夜2時。あなたのスマートフォンは静かなままです。アラートは鳴りません。それは偶然ではありません。過去のあなたが書いた1つのテストが、その夜の安眠を守っています。

このブログが良ければ読者になったりnwiizoXGithubをフォローしてくれると嬉しいです。

参考資料

🔍 Search
🦹‍♂️ Featured

引用をストックしました

引用するにはまずログインしてください

引用をストックできませんでした。再度お試しください

限定公開記事のため引用できません。

読者です読者をやめる読者になる読者になる

[8]ページ先頭

©2009-2025 Movatter.jp