決済サービスの変更は、数千のユニットテストに合格しても、請求APIがサービスが想定するのとは異なる方法で冪等性キーを解釈するため、本番環境で壊れる可能性があります。この障害は、コミットがパイプラインの高速な部分を通過した後も、夜間の統合ジョブがインターフェースに到達するまで気づかれないまま放置されることがあります。
これは、運用上の問題であり CI/CD統合テスト。ユニットテストは、分離されたロジックが正しく動作することを証明します。統合テストは、コンポーネント、サービス、スキーマ、キュー、外部依存関係が依然として整合していることを示す証拠を提供します。モダンなデリバリーパイプラインでは、その証拠がトリアージの判断を形成するべきであり、開発者が無視するようになった遅いチェックの壁になってはいけません。
CI/CDは、主流のソフトウェアデリバリーモデルとなりました。 mablの2024年DevOpsテストレポート によると、世界の組織の 約90% がDevOps変革を優先しており、テスト担当者の 50% がCI/CDプロセスの定義と維持に関与し、組織の 10% だけがCI/CDを全くデプロイしていないと報告しています。実務的な帰結は明確です:統合検証は、今やデリバリー規模で動作しなければなりません。
目次
- なぜ統合テストがCI/CDの制御点なのか
- ユニットテストとE2Eテストの中間に位置する統合テスト
- テストの再現性を高めるための環境とデータ管理
- GitHub Actions、GitLab CI、Jenkins 向けのパイプライン例
- フレーキーな統合テストの信頼性対策
- ゲートポリシーとデプロイ昇格ルール
- 長期的な信頼のための導入チェックリストと可観測性
なぜ統合テストはCI/CDの制御点なのか
統合テストは、リリースリスクが具体的になる場所です。ユニットテストで決済ハンドラーがidempotency keyを正しくフォーマットできることは確認できますが、ハンドラー、HTTPクライアント、請求API、永続化レイヤー、リトライ動作が連携して動作する際に互いに合意していることを証明できるのは、統合テストだけです。
そのため、統合ステージは継続的インテグレーションと継続的デリバリーの間の自然な制御点となります。ユニットスイートがグリーンだからといって、コミットがデプロイ可能とみなされるべきではありません。変更されたインターフェースが本番環境に近い構成で依然として機能することを示す信頼できる証拠を生み出すことで、昇格を勝ち取るべきです。

この区別が重要なのは、自動検証なしでの高頻度統合は欠陥をより速く伝播させるだけだからです。CI/CD改善手法の体系的レビューでは、ビルドとテスト時間の短縮、結果の可視化向上、継続的テストの支援、障害検出、デプロイ信頼性の向上といった優先事項が繰り返し指摘されています。同じ研究記録の別のレビューでは、テストを含む自動ビルドによって検証される高頻度のcode統合を軸に継続的統合を定義し、欠陥を迅速に検出できるようにしています。
制御ポイントを意図的に構築する
統合テストは、それが支援する意思決定に基づいて分類することから始めます:
- ブロッキングテスト 重要な契約を保護し、マージまたはプロモーション前に同期的に実行します。
- 隔離テスト チームが不安定性を調査している間も、可視性を保ち続け、証拠を生成し続けますが、デリバリーをブロックしません。
- 非同期テスト コミットが高速ゲートを通過した後、より広範なワークフロー、完全なステージング構成、または高コストなインフラストラクチャを検証します。
これは、「すべてのテストをCIに入れるべきか」と議論するよりも有用です。正しい問いは、そのテストが特定のプロモーション決定に影響を与えるほど信頼性があり、価値があるかどうかです。
実践的なルール: 統合スイートの存在ではなく、安定した統合証拠に基づいてゲートを設定します。
実装の残りは、このルールから導き出されます。インターフェースが失敗しうる箇所では本番環境に近い依存関係を使用し、独立したチェックを並列化し、誤検知を測定し、隔離と昇格の明確な条件を定義します。この作業をより広いデリバリープラクティスと結びつけたいチームは、以下も参照できます。 継続的インテグレーション(CI)のメリット.
ユニットテストとE2Eテストの中間に位置する統合テスト
テストピラミッドはコストモデルであり、厳格な法則ではありません。ユニットテストは関数、クラス、またはモジュールを分離するため高速です。その速さは即時フィードバックを得るのに理想的ですが、モックを使うと、シリアライズの違い、データベースの制約、認証設定、キューの挙動といった、システム境界で発生する失敗を覆い隠してしまうことがあります。
対照的に、エンドツーエンド(E2E)テストは、フルスタックにわたるユーザーのジャーニーを実行するため、リスクの高いワークフローにおいて価値があります。一方で、ブラウザ、ネットワーク、サービス、インフラの境界をまたぐため、原因の特定や安定性の確保が難しくなります。すべてのマージをE2Eテストの完了まで待つことになると、開発者へのフィードバックが遅れ、焦点を絞った API レベルの統合テストよりも情報量が少なくなることがよくあります。
統合テストはその中間を担います。UI全体のオーケストレーションを必要とせず、実環境に近い依存関係を使ってサービス間の挙動を検証します。このレイヤーでは、HTTPやgRPCの呼び出し、キューへのパブリッシュ、データベースのマイグレーション、キャッシュの相互作用、スキーマの互換性などをカバーできます。
3つの有用な統合パターン
Testcontainersを使用したインプロセス・コンポーネントテスト PostgreSQL、Redis、Kafkaなどの依存関係と並行してアプリケーションコンポーネントを起動します。このパターンは、永続化、シリアライズ、トランザクション、またはブローカーのセマンティクスに関わる欠陥リスクがある場合に、セットアップコストに見合う価値があります。テストに実際の依存関係を提供しつつ、テストの境界を狭く保つことができます。
Pactやスキーマレジストリによるサービス間コントラクトテスト コンシューマーとプロバイダー間の合意に焦点を当てます。チームがサービスを独立してリリースし、コントラクトのドリフトに対する迅速なフィードバックが必要な場合に、強力な選択肢となります。コントラクトテストは行動統合テストの代替にはなりませんが、互換性のないインターフェースが共有環境に到達することを防ぐことができます。
構成されたステージングスタックに対するAPIレベルのテスト 実際のネットワークパスを通じて、デプロイされた複数のサービスを呼び出します。ルーティング、認証、サービスディスカバリー、デプロイ設定、またはインフラストラクチャポリシーが重要なワークフローにこのパターンを使用してください。完全なステージングスタックはプロビジョニングコストが高く、失敗時に分離が困難なため、ビジネス上重要なパスにセットを集中させてください。
| パターン | ランタイム | 環境の忠実性 | 最適なケース |
|---|---|---|---|
| Testcontainersを使用したインプロセス・コンポーネントテスト | 高速から中程度 | 実際に選択された依存関係 | データベース、キャッシュ、ブローカー、およびアプリケーションコンポーネントの挙動 |
| Pactやスキーマレジストリを使ったコンシューマー/プロバイダー契約テスト | 高速 | インターフェースの再現性が高い | 独立してリリースされるサービス間のAPIとイベントの互換性 |
| 構成済みのステージングスタックに対するAPIテスト | 中速から低速 | システムの再現性が高い | ネットワークパス、認証、ルーティング、および重要なマルチサービスワークフロー |
同期的なマージスイートは意図的に絞り込みます。実用的な目標は、統合パスを 1マージコミットあたり10分未満に抑えることです、その後、広範なシナリオを非同期実行に移行することです。この分割のより広い根拠を求めるチームは、以下を参照してください 自動テストに含まれるもの、しかし基本原則はシンプルです。リリース判断に影響する部分には、リアリズムの確保にコストをかける。
忠実なテストのための環境とデータの管理
誤った環境で実行されたテストは、誤った安心感を生み出します。不安定な共有環境で実行されたテストは、誤った失敗を生み出します。信頼できる CI/CD統合テスト には、依存関係の境界を明確にし、データ状態を再現可能な環境戦略が必要です。

忠実に実行できる依存関係から始めましょう。Testcontainers を使用すると、各ジョブ用に使い捨ての PostgreSQL、Redis、Kafka インスタンスをプロビジョニングできます。最大の利点は Docker 自体ではなく、バージョン、設定、起動、破棄に対する制御です。
再現可能なジョブシーケンス
テスト code にセットアップを即興でやらせるのではなく、固定されたシーケンスを使用してください:
- 依存関係を開始します。 PostgreSQL コンテナを起動し、プロセスが実行中であるだけでトラフィックを受け付けられると仮定するのではなく、実際のヘルスチェックを待ってください。
- マイグレーションを適用 アプリケーションが使うのと同じマイグレーションパスを実行してください。本番と乖離しうる手動管理のテストスキーマを作らないでください。
- 決定的なフィクスチャをロード シナリオに必要なレコードだけをシードし、各ジョブに隔離されたデータを渡して、並列実行が互いの状態を書き換えられないようにしてください。
- コントラクトアサーションを実行 リクエスト形式、レスポンスの挙動、イベントスキーマ、ステータス遷移、永続化の結果を検証します。
- すべてを破棄する テストが失敗しても、コンテナと一時ボリュームを破棄して、後続のジョブが破損した状態を引き継がないようにしてください。
PostgreSQLの起動に90秒かかっても、マイグレーションやトランザクションの欠陥を検知できるなら妥当なコストです。ステージング用の完全なクラスターを用意するかは別の判断です。インフラをより多く消費し、設定ドリフトを招き、障害の発生源も増えます。まずは本番に忠実な最小限の環境から始め、コントラクトカバレッジや本番インシデントから、その小さな境界では重要な失敗モードを見逃していると分かったときに広げてください。
仮想化を意図的に活用する
サードパーティのシステムの中には、すべてのパイプラインで安全にプロビジョニングできないものがあります。WireMock、Mountebank、Hoverflyなどを使えばそれらの依存関係をシミュレートできますが、そのシミュレーションは単なる便利な逃げ道ではなく、メンテナンスされるコントラクトとして扱う必要があります。理想的なレスポンスしか返さないモックでは、認証切れ、レート制限、不正なペイロード、タイムアウト処理、スキーマの進化を明らかにできません。
エフェメラルなプレビュー環境は、リスクが複数のデプロイ済みサービスの連携に依存する場合に役立ちます。Docker Compose はコンパクトなローカルおよび CI 構成を提供でき、デプロイ動作自体のテストが必要な場合は、Kubernetes の名前空間でプルリクエスト環境を分離できます。いずれのアプローチを採用しても、依存関係のバージョンを固定し、各実行で使用された設定を記録してください。
シークレットはデータと同じ規律が必要です。認証情報はテストフィクスチャの外に保存し、プラットフォームの保護メカニズムを通じてアクセスをローテーションしてください。 Capgo による CI/CD パイプラインでのシークレット管理ガイド は、リポジトリ設定から機密値を除外するための関連するガイダンスを提供しています。
短いビジュアルウォークスルーは、チームが環境ライフサイクルについて合意するのに役立ちます:
GitHub Actions、GitLab CI、Jenkins 向けのパイプライン例
ランナーよりもワークフローの形状が重要です。一度だけビルドし、依存関係を予測可能にプロビジョニングし、独立したテストグループを分割し、機械可読な結果を公開し、ブロッキングの境界を明確にします。構文はプラットフォームによって変わりますが、これらの運用ルールは一貫しています。
GitHub アクション
マトリクスは、統合テストをドメインやシャードで分割できる場合に有効です。サービスコンテナは依存関係をランナーに近づけ、JUnit出力はプルリクエストや下流システムに安定した結果形式を提供します。
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 Actionsは主にマトリクスと個別ジョブを通じて並列性を公開するため、各シャードが隔離されたデータと予測可能な実行時間を持つ場合のみマトリクスを使用してください。
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の報告によると、約 16%のテストに 多少のflakinessがあり、また 全テスト実行の約1.5%が 不安定な結果を返しており、別の研究では Googleのテスト失敗の4.56%が 不安定なテストに起因していることが判明しました。これは AWSのCI/CDテストガイダンスにまとめられています。また、Googleのデータでは、CIの成功から失敗への遷移の約 84%が 真のバグではなく不安定なテストによるものでした。Microsoftのプロジェクトでは、約 4.6%のテストが不安定だと報告されています Pantoのflaky test統計レビューによると、ある調査で。

ポリシー変更前に測定する
flakinessを以下のように追跡:
flaky失敗数 ÷ 総実行回数 × 100
次の 7〜30日間のウィンドウ、そしてスイート、テスト、ランナーイメージ、依存関係、環境ごとに計算する。1つのランナーでのみ失敗するテストと、すべての環境で失敗するテストでは、修正の問題が異なる。
これらのトリアージカテゴリを使用:
- プロダクトの失敗: 関連するゲートをブロックし、codeまたはコントラクトを修正する。
- 環境の失敗: ヘルスチェック、リソース制限、ネットワーク、依存関係の設定を修正します。
- テスト失敗: アサーションの順序、共有状態、タイミング、クリーンアップ、フィクスチャ設計を修正します。
- 未分類の不安定さ: 一時的に隔離しますが、担当者と有効期限を設定してください。
よくある原因を排除する
共有された可変状態は実行順序への依存を生みます。各ジョブに分離されたスキーマ、一意の識別子、またはトランザクションのロールバック境界を割り当ててください。非同期システムでは、場当たり的な sleep ではなく、タイムアウト付きの条件ベースのポーリングが必要です。有効期限のロジックにはクロックを注入し、プロセスの起動ではなくコンテナのヘルスを待つようにしてください。
シャーディングは実時間を短縮しますが、ダメなテスト自体は解決しません。各シャードを独立して実行し、すべてのシャードのログを保持した上で、診断には失敗したテストまたはシャードだけを再実行してください。統合チェックが1つ環境要因で失敗しただけで、パイプライン全体を再実行してはいけません。
テストが隔離を解除できるのは、定義された安定性ポリシー(実行される各環境での連続成功など)を満たした場合のみです。具体的な閾値はチームで決めてポリシーに記録してください。重要なのは、隔離ラベルを削除するのではなく、観測された安定性によって昇格が認められることです。
ゲートポリシーとデプロイ昇格ルール
クオリティゲートが答えるべき問いは1つです。このアーティファクトには、次の環境へ進むだけの信頼できるエビデンスがあるか? 組織が蓄積してきたあらゆるテストを詰め込む場所にしてはいけません。
この執行ギャップは警告です。 TestkubeのCI/CDテスト分析 によると、 72%の組織 がCI/CDでQAを自動化していますが、 26% テスト失敗時にデプロイをブロックする品質ゲートを強制しているのはわずかです。執行なき採用は、リリース判断を記憶、緊急性、または手動チェックリストに委ねることになります。
ステージ別のゲートを使用する
コミット時は、高速なユニットテストと、変更または重要なインターフェースを保護する安定した統合テストサブセットでブロックします。ステージングでは、より広範な構成環境チェックとデプロイ設定の検証を追加します。本番環境前に、承認済みアーティファクト、保護環境での検証成功、およびリスクモデルが要求する場合の明示的な承認を必須とします。
| ステージ | 必須パス率 | 隔離を許可 | 承認 |
|---|---|---|---|
| コミットまたはプルリクエスト | すべてのブロッキングチェックに合格 | ブロッキング対象外のテストのみ | 自動マージ保護 |
| ステージングへの昇格 | すべての重要な統合チェックに合格 | オーナーとリスクレビューが文書化されている場合のみ許可 | チームまたはサービスのオーナー |
| カナリアリリースまたは限定ロールアウト | 昇格チェックとライブヘルスシグナルに合格 | 隔離テストは保護パスをカバーしないこと | オンコールまたはリリースオーナー |
| 本番環境へのプロモーション | 監査証跡付きで全必須ゲートがパス | ブロッキングパスの隔離なし | ポリシーで要求される場合の明示的な承認 |
「パス率」を単なるパーセンテージ目標と混同しないこと。パス率は高く見えても、実際に重要となる決済や認証パスで繰り返し失敗している可能性があります。行動ベースでクリティカルパスのカバレッジを定義し、それらのチェックが決定論的にパスすることを必須にしてください。
バイパスを可視化する
ブランチ保護を設定し、ブロッキングチェックの失敗時にマージを防止してください。環境保護ルールを設定し、プロモーション時に期待される承認と成果物を要求してください。インシデント中の人間によるオーバーライドは必要になる場合がありますが、明示的な理由、指名された承認者、タイムスタンプ、フォローアップチケットを必須にしてください。
隔離は失敗を無視する許可ではありません。証拠を保全しながらデリバリーを継続するための管理された方法です。隔離されたテストが保護されたリリースパスをカバーしている場合、ポリシーはそれをブロッキング状態に復元するか、プロモーション前にリスク判断を要求すべきです。
長期的な信頼のための導入チェックリストとオブザーバビリティ
チームが統合テストで失敗するのは、主に2つのパターンです。巨大なスイートから始めてすべてのマージを遅くするか、本番環境で露呈する失敗を全く検証しないほど広範なモックを使った高速スイートを作成するかです。段階的な導入計画により、これらの罠を回避できます。

フェーズ1:既存のシグナルを信頼できるものにする
まずは既存のパイプラインから始めましょう:
- 最初のゲートを設定する: 重要なサービス契約を特定し、安定したチェックのみをブロッキングにします。
- リトライの挙動を定義する: 診断目的の限定的な再実行は許可しますが、失敗を成功にすり替えるサイレントリトライは決して行わないでください。
- 並列化を有効にする: 境界づけられたドメイン、依存関係、シャードごとにテストスイートを分割し、ジョブごとにデータを分離します。
- テスト結果を公開する: すべての実行において、JUnitレポート、ログ、コンテナの状態、および失敗の分類を保存します。
この段階では、カバレッジの最大化を追い求めないでください。まずは最もコストの高いノイズ源を取り除き、取り戻した開発者の信頼を活かして、実際の依存関係のカバレッジを広げましょう。
フェーズ2:環境の忠実度を高める
再現コストが低い依存関係には Testcontainers を追加します。サービスの所有権が分散している場合は、コントラクトテストを導入します。ルーティング、デプロイ設定、またはサービス間動作をコンパクトなジョブで正確に表現できない場合は、エフェメラル環境を使用します。
選択の判断は根拠に基づいて行うべきです。本番インシデントでマイグレーションの不一致が露呈した場合は、実際のデータベースパスを追加します。独立デプロイされたサービス間で API が乖離した場合は、コンシューマーとプロバイダー間のコントラクトを追加します。障害が Kubernetes の設定に依存する場合は、モックが同じことを証明しているかのように装うのではなく、エフェメラルネームスペースに対して関連するチェックを実行します。
フェーズ3: 可観測性をトリアージに接続する
キャプチャ テスト実行時間のパーセンタイル、環境設定の違い、ロックされた依存関係のバージョン、リトライによるパス率、および OpenTelemetry 経由で相関付けされたアプリケーションログとトレース。有用なダッシュボードは以下を表示すべきです:
- フレーク率の増加: どのスイートやテストが決定論的でない方向に向かっているか。
- グリーンになるまでの平均時間: 失敗したパイプラインが復旧までにどこで時間を費やしているか。
- 障害モードのクラスタリング: 障害が code、環境、依存関係、またはテスト設計のいずれかを軸にグループ化されているか。
- 隔離(quarantine)インベントリ: どのテストが隔離されているか、誰が責任者か、いつレビューが必要か。
- 昇格のエビデンス: 各環境を変更する前に、どのゲートを通過したか。
これは、次の運用上の意味を持ちます: アプリケーションのオブザーバビリティダッシュボードは単なる過去の記録保管庫ではありません。テストがブロックすべきか、非同期で待機すべきか、それとも隔離に戻すべきかという、今日の意思決定を変えるものであるべきです。
ブロック対象のサブセット、隔離ルール、環境のオーナーシップ、リトライ上限、アーティファクト要件、オーバーライド手順をまとめた1ページのチームポリシーを用意してください。見直すのは、大きなインシデントで話し合いが必要になった時だけでなく、失敗データが変化した時です。
Capgo は、Web ビルド後に署名済みの Live Update bundle をアップロードする処理を自動化する CI/CD 連携を提供しています。チャンネルを使えば、feature-branch、staging、production のワークフローに対応できます。CapacitorJS や Electron のチームで、統合テストのエビデンスを管理されたモバイル配信につなげたい場合は、こちらをご覧ください。 Capgo API とロールアウトのワークフローを評価できます。