自動化

静的解析と動的テストの違いとは|検出できるバグ・代表ツール・使い分けを比較

静的解析(静的検査)と動的テストは、どちらもソフトウェアの品質を上げる手法ですが、コードを「実行せずに調べる」か「実行して確かめる」かで役割がはっきり分かれます。この記事では、両者の違いを解析タイミング・検出できるバグ・対象範囲の観点で比較し、ESLintやSonarQube、Jest、Seleniumといった代表ツール、CI/CDでの使い分け、導入時につまずきやすい誤検知への対処までを整理します。

まとめ:静的解析と動的テストの使い分け

結論から示します。両者は競合ではなく補完関係で、開発の段階を分けて両方使うのが基本です。

  • 静的解析(静的検査/SAST):コードを実行せずに構文・規約違反・脆弱性を検出。開発初期〜コミット時に効く。
  • 動的テスト(DAST含む):実行して挙動を検証。メモリリークや性能問題など、動かさないと分からないバグを検出。
  • 検出領域が違う:未使用変数やSQLインジェクションは静的、スレッド競合や負荷時のクラッシュは動的。片方では穴が残る。
  • 入れる順番:コミット時に静的解析、CI/CDのビルド段階で動的テスト、というシフトレフトが定番。
  • つまずき所:静的解析の誤検知(False Positive)を放置するとルールが形骸化する。段階導入と例外設定が要。

以降で、定義・比較表・代表ツール・使い分け・誤検知対策の順に解説します。

静的解析と動的テストとは|実行しない検査と実行する検証

用語を先に揃えます。「静的検査」「静的テスト」「静的コード解析」はほぼ同義で、いずれもコードを実行せずに調べる手法を指します。本記事では一般的な「静的解析」に統一します。対になるのが、実行して確かめる「動的テスト」です。

静的解析(静的検査):ソースコードを実行せずに調べる

静的解析は、ソースコードの構文や論理構造を解析し、バグの芽や規約違反を実行前に見つける手法です。未使用変数、命名規則違反、到達不能コード、SQLインジェクションのような脆弱性パターンなどが対象になります。コンパイルや実行を伴わないため、書いた直後やコミット時に軽く回せるのが利点です。セキュリティ分野ではSAST(Static Application Security Testing)とも呼ばれます。

動的テスト:実際に動かして挙動を確かめる

動的テストは、プログラムを実行し、入力に対する出力や挙動が期待どおりかを検証します。ユニットテスト、統合テスト、負荷テスト、セキュリティテスト(DAST)などが含まれます。実行時にしか現れないメモリリーク、スレッド競合、特定負荷でのクラッシュなどを捉えられる一方、実行環境の準備や実行時間というコストがかかります。

静的解析と動的テストの違い|タイミング・検出できるバグ・対象

もっとも検索されているのが、この「違い」です。観点ごとに整理します。

観点 静的解析(静的検査) 動的テスト
実行 しない(コード解析) する(実行して検証)
タイミング 開発初期・コミット時 ビルド後・リリース前
得意なバグ 構文・規約・脆弱性パターン 実行時バグ・性能・競合
対象 可読性・保守性・セキュリティ 動作の正しさ・耐負荷
コスト 低い(高速・自動化容易) 高い(環境・時間が必要)

表のとおり、両者は「どの段階で何を見つけるか」が違います。静的解析は早く・広く・浅く、動的テストは遅く・深く・実態に即して検出します。だからこそ、どちらか一方では品質の穴が残り、両方を段階的に組み合わせる必要があります。

静的解析と動的テストで検出できるバグの具体例|未使用変数とメモリリーク

抽象論ではイメージしにくいので、実例で対比します。静的解析が見つけるのは「コードを読めば分かる問題」、動的テストが見つけるのは「動かさないと分からない問題」です。

静的解析の典型は、未使用変数・到達不能コード・命名規則違反のほか、SQLインジェクションやクロスサイトスクリプティング(XSS)のような既知の脆弱性パターンです。たとえば次のような未使用変数は、ESLintなら一瞬で指摘します。

// sample.js(静的解析が指摘する典型例)
function calc(a, b) {
  const unused = 0;      // 使われていない変数
  return a + b;
}
console.log(calc(1, 2));

$ npx eslint sample.js
sample.js
  3:9  warning  'unused' is assigned a value but never used  no-unused-vars

✖ 1 problem (0 errors, 1 warning)

一方、動的テストでしか捉えられないのは、メモリリーク、スレッド競合(デッドロック)、特定の負荷でのみ顕在化する性能ボトルネックやクラッシュです。これらは「正しく書けているように見える」コードで起きるため、実行して初めて分かります。検出領域が重ならないことが、両方を使う最大の理由です。

代表的な静的解析ツール|ESLint・SonarQube・言語別の選択

静的解析ツールは言語ごとに定番があります。JavaScript/TypeScriptはESLint、多言語横断の品質可視化はSonarQube、PythonはPylintやmypy、JavaはCheckstyleやSpotBugs(旧FindBugs)、PHPはPHPStanやPsalmが広く使われます。

ESLintは2024年4月のv9で設定形式が刷新され、フラットコンフィグ(eslint.config.js)が既定となり、従来の.eslintrcは非推奨になりました。これから導入するならフラットコンフィグ前提で構成します。PHPの静的解析でPHPStanとPsalmのどちらを選ぶか迷う場合は、PsalmとPHPStanの比較:機能や使用感の違いを検証で具体的な違いを確認できます。静的解析を含むコード品質管理の全体像は静的コード解析と他のコード品質管理手法との違いも参考になります。

代表的な動的テストの手法とツール|単体・E2E・負荷・DASTの使い分け

動的テストは目的別に手法が分かれ、それぞれ定番ツールがあります。重要度の高い順に整理します。

まず土台になるのがユニットテスト(単体テスト)で、関数やメソッド単位の正しさを検証します。JavaScriptならJest、JavaならJUnit、PythonならPyTestが定番です。次に統合テストで、モジュール間やAPIの連携を確認します。WebのE2EではSeleniumやCypressが使われます。負荷・性能テストにはApache JMeterやGatling、実行時のセキュリティ検証(DAST)にはOWASP ZAPやBurp Suiteを用います。DASTの検査原理とCI/CDへの組み込みはDASTとは?SASTとの違い・ZAPでのCI/CD組み込みと導入判断を実装視点で解説で扱っています。すべてを同程度にやる必要はなく、ユニットテストを厚く、負荷・セキュリティは要件に応じて、という配分が現実的です。

CI/CDでの組み合わせと使い分け|シフトレフトの実践

両者は入れる順番が肝心です。シフトレフト(テストを開発の早い段階へ前倒しする考え方)が定石です。具体的には、コードのコミットやプッシュの段階で静的解析を自動実行し、規約違反や脆弱性パターンを即座に弾きます。その後、CI/CDのビルド段階でユニットテスト・統合テストを回し、リリース前に負荷テストやDASTを実施します。

順番を逆にすると効率が落ちます。実行コストの低い静的解析を後ろに置くと、動かしてから初歩的な規約違反が見つかり手戻りが増えます。安いチェックを前、重いチェックを後ろ、が鉄則です。GitHub ActionsやJenkinsで、プッシュ時にESLintやSonarQube、ビルド時に自動テスト、という二段構えにするのが標準的な構成です。

静的解析の導入でつまずく誤検知への対処

静的解析の導入が失敗する最大の原因は、誤検知(False Positive)の放置です。実際には問題のないコードまで警告されると、開発者は警告全体を無視し始め、本当に危険な指摘も見逃されます。ルールが形骸化した静的解析は、入れていないのとほとんど変わりません。

対策は段階導入です。最初から全ルールを最大強度で有効化せず、まず重大度の高いルール(脆弱性・明確なバグ)に絞って導入し、誤検知が多いルールは無効化するか個別に例外設定します。既存コードの大量の警告は、基準時点を区切って「新規コードのみ厳格にチェックする」運用(ベースライン)にすると現実的です。静的解析は「全警告ゼロ」を目指す道具ではなく、危険な変更を止める道具だと割り切ると、定着します。逆に、誤検知を放置したまま警告件数だけを追うチームでは、まず導入すべきでないルールを外すところから始めるべきです。

よくある質問(FAQ)

静的検査と静的解析は同じ意味ですか?

ほぼ同義です。「静的検査」「静的テスト」「静的コード解析」はいずれも、コードを実行せずに構文や脆弱性を調べる手法を指します。セキュリティ文脈ではSAST(静的アプリケーションセキュリティテスト)とも呼ばれます。対義語が、実行して確かめる「動的テスト(DAST含む)」です。

静的解析と動的テストの違いは何ですか?

コードを実行するかどうかが本質的な違いです。静的解析は実行せずに構文・規約・脆弱性パターンを早期に検出し、動的テストは実行してメモリリークや性能問題など実行時のバグを検出します。検出できるバグの領域が重ならないため、両方を併用します。

静的解析だけで品質は十分ですか?

不十分です。静的解析はコードを読めば分かる問題に強い一方、実行時にしか現れないメモリリーク・スレッド競合・負荷時のクラッシュは検出できません。これらは動的テストでしか捉えられないため、静的解析と動的テストの併用が前提になります。

静的解析ツールのおすすめは何ですか?

言語で選びます。JavaScript/TypeScriptはESLint(v9以降はフラットコンフィグ)、多言語の品質可視化はSonarQube、PythonはPylintやmypy、JavaはCheckstyle・SpotBugs、PHPはPHPStan・Psalmが定番です。まず1つを軽く導入し、誤検知を見ながらルールを育てるのが失敗しにくい進め方です。

シフトレフトとは何ですか?

テストや品質チェックを開発工程の早い段階(左側)へ前倒しする考え方です。コミット時に静的解析、ビルド時に自動テストを回すことで、バグを早期かつ低コストで発見できます。後工程ほど修正コストが膨らむため、安いチェックを前に置くのが要点です。

関連記事

資料請求

RELATED POSTS 関連記事