mcpField
G
generating-apex-test

generating-apex-test

github.com/forcedotcomテスト・品質1.1k4.2k 回インストール1 日前に更新
リポジトリ

generating-apex-test について

Salesforce Apex のテストクラス生成と、テスト修正・カバレッジ分析の手順を定めたスキルです。Apex テストを作成・保守する開発者向けに、データ分離、明確なアサーション、非同期処理、正常系・異常系・一括処理のテストを扱います。

主な機能

  1. 011つの動作ごとにテストメソッドを構成
  2. 02TestDataFactory によるデータ分離
  3. 03Assert による明確な検証
  4. 04外部呼び出しのモックと異常系テスト
  5. 05テスト実行とカバレッジ分析
  6. 06最大3回のテスト修正ループ

活用シーン

  1. 01Apex クラスのテストクラスとメタデータを生成
  2. 02251件以上のレコードによるトリガー検証
  3. 03Queueable、Batch、Scheduled の非同期処理をテスト
  4. 04テスト結果とカバレッジから失敗箇所を調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/forcedotcom/sf-skills --skill generating-apex-test

インストール後、Claude Code で/generating-apex-testを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

CREDITS.md
assets/
test-class-template.cls
test-data-factory-template.cls
references/
assertion-patterns.md
async-testing.md
mocking-patterns.md
test-data-factory.md

詳細

Apex テストの生成

本番環境で使用できる Apex テストクラスを生成し、カバレッジ分析を伴う規律あるテスト・修正サイクルを実行します。

基本原則

  1. 1 メソッドにつき 1 つの動作 — 各テストメソッドでは単一のシナリオを検証します。正常系、異常系、バルクテストは分けてください。関連するものの異なる入力(例:null と空)を 1 つのメソッドにまとめてはいけません。_NullInput_ と _EmptyInput_ を別々のテストメソッドとして作成してください
  2. テストをバルク化する — 200 レコードのトリガーバッチ境界を超えるため、251 件以上のレコードでテストしてください。**Batch Apex の例外:**テストコンテキストでは execute() の呼び出しは 1 回のみ実行されるため、batchSize >= testRecordCount を設定してください。references/async-testing.md を参照してください
  3. テストデータを分離する — すべての @TestSetup では、レコードの作成を TestDataFactory クラスに委譲する必要があります。存在しない場合は、まず作成してください。@TestSetup 内でレコードリストを直接構築してはいけません。組織のデータ(SeeAllData=false)やハードコードされた ID に依存してはいけません。重複ルールの処理については、references/test-data-factory.md を参照してください
  4. 意味のあるアサーションを行う — テストデータのセットアップから算出した、厳密な期待値を使用してください。値が決定的な場合、範囲によるアサーションや概算の件数を使用してはいけません。必ず失敗メッセージを含めてください。references/assertion-patterns.md を参照してください
  5. Assert クラスのみを使用する — Assert.areEqual、Assert.isTrue、Assert.fail などを使用してください。従来の System.assert、System.assertEquals、System.assertNotEquals は使用しないでください
  6. 外部境界をモックする — コールアウトには HttpCalloutMock、SOSL には Test.setFixedSearchResults、データベース分離には DML モッククラスを使用してください。コンストラクターインジェクションを用いて、テストしやすい設計にしてください。references/mocking-patterns.md を参照してください
  7. 異常系をテストする — 正常系だけでなく、エラー処理と例外のシナリオも検証してください
  8. start/stop で囲む — Test.startTest() と Test.stopTest() を組み合わせて、ガバナー制限をリセットし、非同期処理を実行してください

Test.startTest() / Test.stopTest()

テスト対象のコードは必ず Test.startTest() / Test.stopTest() で囲んでください。

  • ガバナー制限をリセットし、テスト対象のコードのみを測定します
  • 非同期処理(キュー可能処理、バッチ、future メソッド)を同期的に実行します
  • スケジュール済みジョブを直ちに実行します

テストコードのアンチパターン

アンチパターン修正方法
ループ内の SOQL/DMLループの前に 1 回だけクエリし、検索には Map<Id, SObject> を使用します
アサーション内のマジックナンバーセットアップ定数から期待値を算出します
巨大なテストクラス(500 行超)動作領域ごとに複数のテストクラスに分割します
長いテストメソッド(30 行超)Given/When/Then をヘルパーメソッドに切り出します
汎用的な Exception の捕捉期待される具体的な型(例:DmlException)を捕捉します

ワークフロー

ステップ 1 — コンテキストを収集する

テストを生成または修正する前に、次を特定します。

  • テスト対象となる本番クラス
  • 既存のテストクラス、テストデータファクトリー、セットアップヘルパー
  • 希望するテスト範囲(単一クラス、特定のメソッド、スイート、またはローカルテスト)
  • カバレッジのしきい値(デプロイには最低 75%、90% 以上を推奨)
  • 組織に対してテストを実行する際の組織エイリアス
ステップ 2 — テストクラスを生成する

アセットテンプレートと参考ドキュメントに記載された構成、命名規則、パターンを適用します。

**必須 — ファイルの成果物:**各テストクラスについて、次の BOTH ファイルを作成します。

  1. {ClassName}Test.cls — テストクラス(出発点として assets/test-class-template.cls を使用)
  2. {ClassName}Test.cls-meta.xml — メタデータファイル:
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>66.0</apiVersion>
    <status>Active</status>
</ApexClass>

プロジェクトに TestDataFactory が存在しない場合は、assets/test-data-factory-template.cls を使用して TestDataFactory.cls と TestDataFactory.cls-meta.xml を作成します。

@TestSetup の例
@TestSetup
static void setupTestData() {
    List<Account> accounts = TestDataFactory.createAccounts(251, true);
}
テストメソッドの構成

Given/When/Then を使用します。

@isTest
static void shouldUpdateStatus_WhenValidInput() {
    // Given
    List<Account> accounts = [SELECT Id FROM Account];

    // When
    Test.startTest();
    MyService.processAccounts(accounts);
    Test.stopTest();

    // Then
    List<Account> updated = [SELECT Id, Status__c FROM Account];
    Assert.areEqual(251, updated.size(), 'All accounts should be processed');
}
異常系テスト — 例外のパターン

期待される例外を検証するには、Assert.fail を使った try/catch を使用します。

@isTest
static void shouldThrowException_WhenInvalidInput() {
    // Given
    List<Account> emptyList = new List<Account>();

    // When/Then
    Test.startTest();
    try {
        MyService.processAccounts(emptyList);
        Assert.fail('Expected MyCustomException to be thrown');
    } catch (MyCustomException e) {
        Assert.isTrue(e.getMessage().contains('cannot be empty'),
            'Exception message should indicate empty input');
    }
    Test.stopTest();
}
命名規則
  • should[ExpectedResult]_When[Scenario]:shouldSendNotification_WhenOpportunityClosedWon
  • [SubjectOrAction]_[Scenario]_[ExpectedResult]:AccountUpdate_ChangeName_Success
ステップ 3 — テストを実行する

デバッグ時は対象を絞って開始し、修正が安定したら範囲を広げます。

# Single test class
sf apex run test --class-names MyServiceTest --result-format human --code-coverage --target-org <alias>

# Specific test methods
sf apex run test --tests MyServiceTest.shouldUpdateStatus_WhenValidInput --result-format human --target-org <alias>

# All local tests
sf apex run test --test-level RunLocalTests --result-format human --code-coverage --target-org <alias>
ステップ 4 — 結果を分析する

次の点に注目します。

  • 失敗したメソッド — 例外の種類とスタックトレース
  • カバーされていない行とカバレッジの低い領域
  • 失敗の原因が不適切なテストデータ、壊れやすいアサーション、本番ロジックの不具合のいずれであるか
ステップ 5 — 修正ループ

テストが失敗した場合は、規律をもって修正ループを実行します(最大 3 回。失敗が続く場合は中断し、根本原因を報告します)。

  1. 失敗したテストクラスとテスト対象クラスを読む
  2. エラーメッセージとスタックトレースから根本原因を特定する
  3. 修正を適用する — テスト側の問題にはテストデータまたはアサーションを調整し、本番コードの問題は generating-apex スキルに委任する
  4. より広範な回帰テストの前に、対象を絞ったテストを再実行する
  5. すべてのテストが成功するか、反復回数の上限に達するか、設計変更が必要な根本原因が判明するまで繰り返す
ステップ 6 — カバレッジを検証する
レベルカバレッジ目的
本番環境へのデプロイ75% 以上Salesforce の必須条件
推奨90% 以上ベストプラクティスの目標
クリティカルパス100%ビジネス上重要なコード

すべての経路をカバーします。正常系、異常系/例外、バルク(251 件以上のレコード)、コールアウト/非同期処理が対象です。

コンポーネント別のテスト対象

コンポーネント主なテストシナリオ
トリガーバルクでの挿入/更新/削除、再帰ガード、項目変更の検出
サービス有効/無効な入力、バルク操作、例外処理
コントローラーページの読み込み、アクションメソッド、ビューステート
バッチstart/execute/finish、スコープの一致(バッチサイズ >= レコード数)、Database.Stateful の追跡、エラー処理、チェーン(個別のメソッド — finish() から Database.executeBatch() を呼び出すと UnexpectedException がスローされます)
Queueableチェーン(テストでは最初のジョブのみ実行)、バルク化、エラー処理、Test.startTest() の前にコールアウトのモックを設定
コールアウト成功応答、エラー応答、タイムアウト
セレクター有効/null/空の入力、バルク(251 件以上)、項目の値の設定、ソート順、System.runAs を使った WITH USER_MODE
スケジュールexecute(null) による直接実行、CronTrigger クエリによる CRON 登録
プラットフォームイベントTest.enableChangeDataCapture()、Test.getEventBus().deliver()、サブスクライバーによる副作用の検証

出力要件

テストクラスごとの成果物:

  • {ClassName}Test.cls + {ClassName}Test.cls-meta.xml(テスト対象クラスの API バージョンに合わせる。デフォルトは 66.0)
  • TestDataFactory.cls + TestDataFactory.cls-meta.xml(まだ存在しない場合)

参考ファイル

詳細なパターンは必要に応じて読み込みます。

参考資料使用する場面
references/test-data-factory.mdTestDataFactory のパターン、項目のオーバーライド、重複ルールの処理
references/assertion-patterns.mdアサーションのベストプラクティス、アンチパターン、よくある落とし穴
references/mocking-patterns.mdHttpCalloutMock、DML のモック、StubProvider、SOSL、メール、プラットフォームイベント
references/async-testing.mdBatch、Queueable、Future、Scheduled ジョブのテスト

コメント