支払いサービス変更は、単位テストで数千回合格しても、実稼働で破綻することがある。 その理由は、請求 API が idempotency キーを異なる方法で解釈していることである。 失敗は、コミットがパイプラインの高速部分を通過してから、長い間、夜間の統合ジョブがインターフェイスに到達するまで、気付かれなかったままになる。
CI/CD統合テストの問題は . 単位テストでは、孤立したロジックが正しく動作することを証明する。 統合テストでは、コンポーネント、サービス、スキーマ、キュー、外部依存関係がまだ一致していることを証明する。 現代の配信パイプラインでは、その証拠は、開発者が無視することになるスローのチェックの壁ではなく、トリガー決定に影響を与えるべきである。CI/CDは、主流のソフトウェア配信モデルとなっている。 mablが2024年のDevOpsテストレポートによると、
の世界規模の組織がDevOpsの変革を優先している。 ただし、 のテスターがCI/CDプロセスの定義と維持に携わっており、 says almost CI/CD統合テスト CI/CD 50% CI/CD 10% CI/CD
目次
- CI/CD統合テストの制御点
- 統合テストの位置付け
- 環境とデータの管理
- GitHub アクション
- CI/CD統合テストの信頼性戦略
- デプロイの促進ルールとゲーティングポリシー
- CI/CD統合テストの長期的な信頼性のための採用チェックリストと観察性
CI/CD統合テストはリスクの制御ポイントです
統合テストは、リリースリスクが実際のものになる場所です。単体テストでは、支払いハンドラーが idempotency キーを正しくフォーマットすることを確認できますが、ハンドラー、HTTP クライアント、請求 API、永続化レイヤー、リトライ動作が一緒に動作するときに一致することを証明するのは統合テストのみです。
CI/CD統合の自然な制御点は、継続的インテグレーションと継続的デリバリーの間です。コミットは単にユニットスイートが緑の場合でも、デプロイ可能と見なされるべきではありません。コミットは、プロダクションライクの環境で変更されたインターフェイスがまだ機能することを証明する信頼できる証拠を生み出すことで、昇格を獲得するべきです。

CI/CDの改善アプローチの体系的なレビューは、頻繁な統合と自動検証の欠如は、欠陥を速く移動させるだけであることを示しました。CI/CD改善アプローチの優先事項として、ビルドとテスト時間の短縮、結果への視覚化の向上、継続的テストのサポート、欠陥の検出、デプロイの信頼性の向上が含まれます。同様の研究レコードで定義されたCI/CDの定義は、頻繁なcode統合を自動ビルドで検証し、テストを含むことで、欠陥を早期に検出できるようにします。
制御点を意図的に作成する
統合テストを開始するには、次のステップに従います。
- ブロッキングテスト 重要な契約を保護し、メージまたは昇格前に同期的に実行します。
- 隔離テスト 不安定性を調査するチームが調査する間、配信をブロックしないようにして、可視性を維持し、証拠を生み続けます。
- 非同期テスト コミットが高速ゲートを通過した後、コミットがクリアした後、より広範なワークフロー、フルステージング構成、または高コストのインフラを実行します。
CI/CD統合テストの統合
実用的なルール: 安定した統合証拠にゲートを設置せよ、統合スイートの存在にせよ
そのルールに従って、実装の残りはそのように行う。パラレル化できる独立したチェックを実行し、偽の失敗を測定し、隔離と昇格の明示的な条件を定義せよ。CI/CD統合をより広範なデリバリープラクティスに接続したいチームは、継続的統合の利点を参照してください。 統合テストはユニットテストとエンドツーエンドテストの間で位置しています。.
単体テストとエンドツーエンドテストの間で統合テストが位置する場所です。
エンドツーエンドテストはその逆の立場を取っています。ユーザージャーニーをフルスタックで実行することで、エンドツーエンドテストは高リスクのワークフローで価値があります。エンドツーエンドテストはまた、ブラウザ、ネットワーク、サービス、インフラストラクチャの境界を超えて実行されるため、診断と安定性が難しくなります。すべてのマージがエンドツーエンドの全体に待たされる場合、開発者は、集中した__CAPGO_KEEP_0__レベルの統合テストよりもはるかに少ない情報を得ることがよくあります。
API
統合テストは中間地帯を占める。実際または実際に近い依存関係を使用して、サービス間の動作を検証するには、完全なUIオーケストレーションを必要とせずに。レイヤーはHTTPとgRPCコール、キューの公開、データベースのマイグレーション、キャッシュのインタラクション、スキーマの互換性をカバーできます。
統合パターン3つ
Testcontainersを使用したインプロセスコンポーネントテスト アプリケーションコンポーネントと依存関係であるPostgreSQL、Redis、Kafkaなどをスタートします。このパターンは、パERSISTENCE、SERIALIZATION、TRANSACTION、またはブローカーセマンティクスに関連する欠陥リスクがある場合に、セットアップコストを値打ちにします。テストは実際の依存関係を提供する一方で、テスト境界を狭く維持します。
契約パターンを使用したクロスサービス契約テスト 消費者とプロバイダー間の契約に焦点を当てます。サービスを独立してリリースするチームがいる場合、契約の変化に対する迅速なフィードバックが必要な場合に強力な選択肢です。契約テストは、非機能的な統合テストを置き換えるべきではありませんが、互換性のないインターフェイスが共有環境に到達するのを防ぐことができます。
APIレベルのテスト 構成されたステージングスタックに対してテストします。複数のデプロイされたサービスを実際のネットワークパスを通じて呼び出します。このパターンは、ルーティング、認証、サービスディスカバリー、デプロイ構成、またはインフラストラクチャポリシーが重要なワークフローに使用します。セットをビジネスクリティカルパスに焦点を当ててください。ステージングスタックを完全にプロビジョニングするコストが高く、失敗したときに分離するのが難しいからです。
| パターン | 実行時 | 環境の忠実さ | 適切なもの |
|---|---|---|---|
| Testcontainersを使用したインスタンス内コンポーネントテスト | 速いから中程度 | 実際に選択された依存関係 | データベース、キャッシュ、ブローカー、そしてアプリケーションコンポーネントの動作 |
| Pactまたはスキーマレジストリを使用した消費者-提供者契約テスト | 速い | 高レベルのインターフェイスの忠実性 | 独立してリリースされたサービス間のAPIとイベントの互換性 |
| APIが組み込まれたステージングスタックに対するテスト | 中程度から遅い | 高レベルのシステムの忠実性 | ネットワークパス、認証、ルーティング、そして重要なマルチサービスワークフロー |
Syncマージスイートを意図的に狭く保つ。実用的な目標は、統合パスを10分未満でマージコミットに保つことです。 マージコミットごとに統合パスが10分未満で保つ、すると、広範なシナリオを非同期実行に移行することができます。統合パスを分割したいチームは、自動テストの範囲を確認することができます。 がしかし、統合パスを分割する基本的な原則は単純です: 実際性を実現するコストを支払う必要があります。リリース決定が変わる場合。環境とデータの管理
環境管理とデータの管理を通じて信頼できるテストを実施する
環境とデータの管理を確実にするための3つのステップの図示。 依存関係を信頼できるものに開始する。Testcontainersは、各ジョブごとに廃棄可能なPostgreSQL、Redis、Kafkaインスタンスをプロビジョニングすることができます。主な利点は、Docker自体ではありません。バージョン、構成、起動、終了の制御が可能です。 再現可能なジョブシーケンス

CI/CD統合テストの基本原則
CI/CD統合テストの基本原則
code を固定シーケンスで実行し、テスト code が自動設定を改造しないようにします:
- 依存関係を起動します。 PostgreSQL コンテナを起動し、実際のヘルスチェックを待ちます。プロセスが実行中であることを前提としているのではなく。
- マイグレーションを適用します。 アプリケーションが使用する同一のマイグレーションパスを実行します。プロダクションとは異なる手作業で管理されるテストスキーマを作成しないでください。
- 決定論的ファイクスをロードします。 シナリオに必要なレコードのみをシードし、各ジョブに分離されたデータを与え、並列実行が他のジョブの状態を汚染できないようにします。
- 契約アサーションを実行します。 リクエストフォーマット、レスポンス動作、イベントスキーマ、ステータス遷移、保存結果を検証します。
- 全てを解体します。 テストが失敗しても、後続のジョブが汚染された状態を継承しないように、コンテナと一時ボリュームを破棄します。
90秒のPostgreSQL起動時間は、マイグレーションとトランザクションの欠陥を検出するのに十分なコストです。完全なステージングクラスターは別の決定です。インフラストラクチャの消費量が増え、構成ドリフトが増加し、失敗の起源が増えるからです。最小限の忠実な環境から始め、契約カバレージまたはプロダクションのインシデントが、より狭い境界が欠落している意味のある失敗モードを示すまで、境界を拡大します。
仮想化と意図
一部の第三者システムは、すべてのパイプラインで安全にプロビジョニングできません。WireMock、Mountebank、Hoverflyは依存関係をシミュレートできますが、シミュレーションは維持される契約として扱う必要があります。ただし、理想的なレスポンスのみを返すモックでは、認証期限切れ、レート制限、不正なペイロード、タイムアウトハンドリング、スキーマの進化などを明らかにしません。
エフェメラルなプレビュー環境は、複数のデプロイされたサービスが協力して機能するリスクに依存する場合に便利です。Docker Composeは、CI構成とローカル構成をコンパクトに提供し、Kubernetesの名前空間は、デプロイメントの動作自体をテストする必要がある場合にプルリクエスト環境を分離できます。どちらのアプローチを使用しても、依存関係のバージョンを固定し、各実行で使用された構成を記録する必要があります。
シークレットはデータと同じ規律を必要とします。テストフィクスチャ外に資格情報を保存し、プラットフォームの保護されたメカニズムを通じてアクセスを回転させる必要があります。 CapgoのCI/CDパイプラインにおけるシークレットの管理に関するガイド 環境ライフサイクルについての短いビジュアルウォークスルーは、チームが環境ライフサイクルについて一致することができます。
パイプラインの例は__CAPGO_KEEP_0__アクション、GitLab CI、Jenkins
GitHub
ワークフローの形が重要なので、ランナーはそれほど重要ではありません。ビルドを一度行い、依存関係を予測可能にプロビジョニングし、独立したテスト グループを分割し、機械が読み取る結果を公開し、ブロッキング バウンダリを明確にします。プラットフォーム間でシンタックスが異なる場合でも、オペレーティング ルールは一貫しています。
GitHub アクション
ドメインまたはシャードに基づいて統合テストを分割することができる場合、行列はよく機能します。サービス コンテナは依存関係をランナーに近く保ち、JUnit 出力は Pull Request とダウンストリーム システムに安定した結果形式を提供します。
name: integration
on:
pull_request:
jobs:
integration:
strategy:
fail-fast: false
matrix:
suite: [billing, orders, notifications]
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: test
POSTGRES_DB: app_test
options: >-
--health-cmd "pg_isready -U postgres -d app_test"
--health-interval 5s
--health-timeout 5s
--health-retries 12
redis:
image: redis:7
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm run test:integration, --suite=${{ matrix.suite }}
- if: always()
uses: actions/upload-artifact@v4
with:
name: junit-${{ matrix.suite }}
path: test-results/*.xml
アクションと依存関係のバージョンを固定すると、環境の漂流が減ります。GitHub アクションは、主に行列と分離されたジョブを通じて並行性を公開するため、各シャードが分離されたデータと予測可能な期間を持つ場合にのみ行列を使用してください。
GitLab CI
GitLab CI は、準備、テスト実行、レポートを分離できます。子パイプラインは、複数のサービスを所有する大きなリポジトリが異なる統合環境を持つ場合に便利です。アーティファクトは、テストジョブが失敗してもJUnit 結果を保存します。
stages:
- build
- integration
build-image:
stage: build
script:
- docker build --tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
integration:
stage: integration
parallel:
matrix:
- SUITE: [billing, orders, notifications]
image: "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
services:
- name: postgres:16
alias: postgres
- name: redis:7
alias: redis
script:
- ./scripts/migrate-test-db.sh
- npm run test:integration, --suite="$SUITE" --reporter=junit
artifacts:
when: always
reports:
junit: test-results/*.xml
複数のサービスを所有する大きなリポジトリが異なる統合環境を持つ場合、GitLab 子パイプラインを使用してください。単一のモノリシック ファイルを維持するのが難しい場合は、親パイプラインがプロモーション決定を担当し、個々の子パイプラインが通過しても全体のリリース信号が曖昧になるのを防ぎます。
Jenkins
Jenkinsは、チームが自社でエージェントをホストしたり、通常のネットワークアクセスを必要とする場合に便利です。宣言型のJenkinsfileは、Dockerベースのエージェントを割り当てて並列にスイートを実行できますが、チームはプラグイン、コントローラー、エージェント、イメージのメンテナンスを負担します。
pipeline {
agent none
stages {
stage('Build') {
agent { docker 'node:22' }
steps {
sh 'npm ci'
sh 'npm run build'
stash name: 'build', includes: 'dist/**'
}
}
stage('Integration') {
parallel {
stage('Billing') {
agent { docker 'my-org/integration-runner:stable' }
steps {
unstash 'build'
sh './scripts/start-test-dependencies.sh'
sh 'npm run test:integration, --suite=billing'
}
}
stage('Orders') {
agent { docker 'my-org/integration-runner:stable' }
steps {
unstash 'build'
sh './scripts/start-test-dependencies.sh'
sh 'npm run test:integration, --suite=orders'
}
}
}
}
}
post {
always {
junit 'test-results/*.xml'
}
}
}
| 機能 | GitHub アクション | GitLab CI | Jenkins |
|---|---|---|---|
| 並列実行 | マトリックスジョブと分離されたジョブ | parallel そしてマトリックスジョブ |
宣言型 parallel ステージと分散されたエージェント |
| 環境制御 | ホストされたまたは自社のランナー | ホスト型または自主型ランナー | 自主管理のコントローラーとエージェント |
| 結果の可視性 | アーティファクトとチェック注釈 | JUnitレポートとアーティファクト | JUnitパブリッシャーとビルド履歴 |
| バージョン再現性 | 固定アクション、イメージ、セットアップバージョン | 固定イメージとランナー構成 | 固定エージェントイメージと制御されたプラグイン |
| 最適な運用 | GitHub-中心のリポジトリ | GitLabを中心とするデリバリー | 自社で拡張されたカスタマイズが必要なチーム |
GitHubを利用しているチーム GitHub Actionsを利用した自動ビルドとリリース すべての3つのランナーで重要な設計上の選択肢は同じです: すべての高コストのテストを同期マージブロッカーとして実行しないこと
フレイキーな統合テストの信頼性戦略
リトライは診断に役立ちますが、広範囲にわたるリトライは信頼性の悪い戦略です。 実際の欠陥を緑色のビルドに変える、環境の不安定性を隠す、パス率のダッシュボードが実際のパイプラインよりも健康に見えるようにする
問題の規模は、公開されたエンジニアリングデータで見ることができます。 Googleは、約 テストの 一定のフレイキネスを含む すべてのテスト実行の フレイキネスを示す結果を返すことがありました。 また、別の研究では Google のテスト失敗の 4.56% が flaky テストによるもので、AWS の継続的インテグレーションとデリバリーのテストガイドでまとめられている。 テストが不安定だったため、以下の要点にまとめました。 Panto による flaky テスト統計のレビューによると、flaky テストは 4.6% であると報告されている。ソフトウェア開発パイプラインにおける flaky インテグレーションテストの管理のための信頼性戦略のフローチャート。 変更する前に測定する flakiness を追跡する: flaky 失敗 ÷ 総実行 × 100 flaky 失敗の割合

flaky 失敗の割合
flaky 失敗の割合
flaky 失敗の割合
CI/CD統合テスト 7から30日間の期間を使用し、スイート、テスト、ランナーイメージ、依存関係、環境ごとに計算します。1つのランナーでしか失敗しないテストは、すべての環境で失敗するテストとは別の対処方法です。
使用する分類:
- 製品の失敗: 関連するゲートをブロックし、codeまたは契約を修正します。
- 環境の失敗: ヘルスチェック、リソース制限、ネットワーク、依存関係のセットアップを修正します。
- テストの失敗: アサーション順序、共有状態、タイミング、クリーンアップ、またはフィクスチャ設計を修正します。
- 分類できない不安定性: 一時的に隔離し、オーナーと期限日を割り当てます。
通常の原因を除去する
共有可能な状態を共有すると、順序依存性が生じます。各ジョブに独自のスキーマ、ユニークな識別子、またはトランザクションロールバック境界を与えます。非同期システムでは、条件に基づくポーリングとタイムアウト制限が必要であり、任意の睡眠はありません。有効期限のロジックに時刻をインジェクトし、コンテナの健康状態を待ち、プロセスの起動を待つのではなくします。
シャーディングは壁時計時間を短縮しますが、悪いテストを修正しません。シャードを独立して実行し、各シャードのログを保存し、診断のために失敗したテストまたはシャードのみを再実行します。環境の障害が1つの統合チェックに発生した場合、パイプライン全体を再実行するのではなく、シャードを独立して実行します。
テストは、環境で実行される環境で連続して緑の実行が行われるという定義された安定性ポリシーを満たすまで、隔離されます。ポリシーでチームが選択した厳密な閾値が記録されます。隔離ラベルを削除するのではなく、観察された安定性によって昇格が得られます。
ゲーティング ポリシーとデプロイメント プロモーション ルール
品質ゲートは、次の環境に移動するために、このアーティファクトが十分な信頼できる証拠を持っているかどうかを答えるべきです。組織が蓄積したすべてのテストをダンプグラウンドに変えるのではなく。
非実施のギャップは警告です。2025年の調査を引用する TestkubeのCI/CDテスト分析 報告によると 組織の72%がCI/CDで自動QAを実行しているのに対し、 のみ 26% テストが失敗した場合にデプロイをブロックする品質ゲートを実施する。採用の実施なしでは、リリースの決定は記憶、急務、または手動チェックリストに任せることになる。
ステージごとにゲートを使用する
コミット時には、高速なユニットテストと保護されたインターフェイスの変更または重要なインターフェイスを保護する安定した統合サブセットでブロックする。ステージング時には、より広範な組み込まれた環境のチェックとデプロイ構成の検証を追加する。生産前に、承認されたアーティファクト、成功した保護された環境の検証、およびリスクモデルがそれを必要とする場合の明示的な承認を要求する。
| ステージ | 通過率が必要 | 隔離が許可されている | 承認 |
|---|---|---|---|
| コミットまたはプルリクエスト | すべてのブロッキングチェックが通過 | ブロッキングサブセット外のテストのみ | 自動マージ保護 |
| ステージングプロモーション | すべての重要な統合チェックが正常に実行されます。 | 文書化された所有者とリスクレビューの場合にのみ許可されます。 | チームまたはサービス所有者 |
| キャニラリーオールバックまたは制限されたロールアウト | プロモーションチェックとライブヘルスシグナルが正常に実行されます。 | 保護されたパスをカバーする保護されたクォラントテストは実行されません。 | オンコールまたはリリース所有者 |
| 本番プロモーション | すべての必要なゲートが監査証拠とともに正常に実行されます。 | ブロッキングパスクォラントは実行されません。 | ポリシーがそれを要求する場合にのみ、明示的な承認が必要です。 |
「通過率」と「raw パーセンテージ目標」とは異なるため、注意してください。スイートは高通過率を示すことができますが、繰り返し同じ支払いまたは認証パスで失敗することもあります。重要なパスをカバーするカバレッジを動作に基づいて定義し、次にそれらのチェックを決定論的に通過するように求めます。
非対象を表示する
ブランチ保護を設定して、チェックが失敗した場合にマージを防止する。環境保護ルールを設定して、推進には必要な承認とアーティファクトが必要になるようにする。インシデントの際には、人間のオーバーライドが必要になる場合があるが、明示的な理由、名前の付いた承認者、タイムスタンプ、フォローアップチケットが必要である。
隔離は、失敗を無視する許可ではない。制御された方法で、証拠を保存しながら、配信を続ける。隔離されたテストが保護されたリリースパスをカバーしている場合、ポリシーはそれをブロッキング状態に戻すか、リスクの決定が必要になる前に推進する必要がある。
採用チェックリストと長期的な信頼の観察性
チームは、CI/CD統合テストに失敗することが多い。あるいは、スピードが遅いスイートから始めるか、モックが広すぎて、実際のエラーをテストしないスイートを作る。段階的な採用計画は、どちらの罠も避ける。

フェーズ1、信頼できる信号を作る
既存のパイプラインから始める:
- 最初のゲートを設定する: 重要なサービス契約を特定し、安定したチェックのみをブロッキングにする。
- リトライ動作を定義する: 診断のためにターゲットされたリトライを許可する。失敗を成功に変える silient リトライは許可しない。
- 並列化を有効にする: スイートを境界ドメイン、依存性、またはシャードに分割し、ジョブごとに隔離されたデータを使用します。
- テスト結果を公開する: JUnit レポート、ログ、コンテナ ステータス、および失敗分類をすべての実行で保存します。
この段階では、最大カバレッジを求めるのではなく、最も高価なノイズの源を削除し、再び開発者信頼を回復して実際の依存性カバレッジを拡大するために使用します。
第2段階、環境の信頼性を高める:
依存性が低コストで再現できるものにTestcontainersを追加します。サービス所有権が分散されている場合に契約テストを導入します。ルーティング、デプロイ構成、またはクロスサービス動作がコンパクトなジョブで正確に表現できない場合に、エフェメラル環境を使用します。
選択の決定は、証拠に基づくものでなければなりません。生産インシデントがマイグレーション不一致を露呈した場合に、実際のデータベースパスを追加します。独立してデプロイされたサービス間でAPIが漂いました場合は、消費者と提供者の契約を追加します。Kubernetes構成に依存する失敗がある場合に、エフェメラルネームスペースに対して関連するチェックを実行するのではなく、モックが同じことを証明するものと仮定するのではなくします。
第3段階、観察性をトリアージに接続する:
キャプチャ テスト時間の百分位数環境構成の差異、ロックされた依存性バージョン、リトライパス比率、関連アプリケーションログとトレースをOpenTelemetryを使用してキャプチャします。有用なダッシュボードは、以下を表示する必要があります:
- フレイクレートバーンアップ: どのスイートとテストが、より少しだけ決定論的になること。
- 平均グリーンタイム: 失敗したパイプラインが回復するまでにかかる時間。
- 失敗モードクラスタ: 失敗がcode、環境、依存関係、またはテスト設計に関連しているかどうか。
- 隔離品目録: 隔離されたテスト、所有者、そしてレビューの必要な時期を示すもの。
- 昇格証拠: 各環境変更前に通過したゲートを示すもの。
このは、 アプリケーション観測性の運用上の意味CI/CD統合テストの制御点
ポリシーを1ページにまとめ、ブロッキングサブセット、隔離ルール、環境所有権、リトライ制限、アーティファクト要件、オーバーライドプロセスを含めましょう。 失敗データが変更されたときにのみ、重大インシデントが会話を強制する必要はありません。
Capgoは、Webビルド後に署名されたライブアップデートバンドルの自動アップロードをサポートするCI/CD統合を提供します。 チャンネルは、機能ブランチ、ステージング、およびプロダクションワークフローをサポートできます。 CapacitorJSまたはElectronチームが統合テスト証拠を制御されたモバイル配信に接続する必要がある場合、以下のURLを参照してください。 Capgo APIを評価し、ロールアウトワークフローを実施してください。