Apexのテストデータ作成方法とテスト実行

Salesforce では、Apex コードのデプロイ前に **テスト（ユニットテスト）** を実施する必要があります。その際、実際のデータではなく **テストデータ** を作成して検証します。

この記事では、以下の流れで **テストデータの作成方法とテストの実行方法** を整理しました。

1. **Apex のテストとは？**
2. **テストデータの作成方法**
   - 手動で作成する方法
   - ファクトリクラスを使う方法
3. **テストデータの設定（@TestSetup の活用）**
4. **テストの実行方法**
5. **実際のコード例と解説**

---

## **1. Apex のテストとは？**
Salesforce では、Apex のテストを実施することが必須です。  
**テストの目的:**
- **コードの品質を保証する**
- **バグの早期発見**
- **デプロイ前のチェック**
- **Salesforce のガバナ制限（Governor Limits）に対応する**

**テストのルール:**
- `@isTest` アノテーションを付ける
- 実際のデータ（レコード）を使用しない（テストデータを作成する）
- コードカバレッジ 75%以上が必要（テストでカバーされている割合）

---

## **2. テストデータの作成方法**
### **① 手動でテストデータを作成**
テストメソッドの中で `insert` を使ってデータを作成する方法です。

**例: 単純なテストデータの作成**
```apex
@isTest
private class AccountTest {
    @isTest
    static void testAccountInsert() {
        // テスト用の Account レコードを作成
        Account acc = new Account(Name='Test Account');
        insert acc;

        // 挿入されたことを確認
        System.assertNotEquals(null, acc.Id);
    }
}
```
**ポイント:**
- `System.assertNotEquals(null, acc.Id);`  
  → 挿入後に `Id` が存在することを確認する。

**デメリット:**
- すべてのテストメソッドで毎回データを作る必要があり、冗長になる。

---

### **② ファクトリクラスを使ってテストデータを作成**
ファクトリクラスを使うと、共通のテストデータ作成処理をまとめることができます。

**例: テストデータを作成するファクトリクラス**
```apex
@isTest
public class TestDataFactory {
    public static Account createAccount(String name) {
        Account acc = new Account(Name = name);
        insert acc;
        return acc;
    }

    public static Contact createContact(String firstName, String lastName, Id accountId) {
        Contact con = new Contact(FirstName = firstName, LastName = lastName, AccountId = accountId);
        insert con;
        return con;
    }
}
```

**このファクトリを使うテストクラス**
```apex
@isTest
private class AccountTest {
    @isTest
    static void testAccountInsertUsingFactory() {
        // ファクトリクラスを使用してデータを作成
        Account acc = TestDataFactory.createAccount('Test Account');

        // データが作成されたか確認
        System.assertNotEquals(null, acc.Id);
    }
}
```

**ファクトリクラスのメリット**
✅ **コードの再利用性が高い**（複数のテストで使い回せる）  
✅ **テストデータ作成が簡潔になる**  
✅ **変更があってもファクトリクラスだけ修正すればOK**

---

## **3. テストデータの設定（@TestSetup の活用）**
`@TestSetup` を使うと、テストクラス内で **共通のデータ** を事前に作成し、すべてのテストメソッドで利用できます。

**@TestSetup の例**
```apex
@isTest
private class AccountTest {
    
    @TestSetup
    static void setupTestData() {
        Account acc = new Account(Name = 'Test Account');
        insert acc;
    }

    @isTest
    static void testAccountExists() {
        // 事前に作成されたデータを取得
        Account acc = [SELECT Id, Name FROM Account WHERE Name = 'Test Account' LIMIT 1];
        System.assertNotEquals(null, acc.Id);
    }
}
```

**メリット:**
✅ **テストデータの重複を減らせる**  
✅ **一度作ったデータを複数のテストで使える**  
✅ **データがテストごとに初期化される**

---

## **4. テストの実行方法**
Apex テストは **開発者コンソール・CLI・UI** などから実行できます。

### **① 開発者コンソールで実行**
1. **開発者コンソールを開く**
2. **[テスト] > [すべてのテストを実行]**
3. **結果を確認**

---

### **② CLI（SFDX）で実行**
```sh
sfdx force:apex:test:run --resultformat human --codecoverage
```
コマンドを実行すると、カバレッジ（テストのカバー率）とともに結果が表示されます。

---

### **③ UI（Setup画面）から実行**
1. **[設定] > [Apex テスト実行]**
2. **テストクラスを選択**
3. **[実行] をクリック**

---

## **5. 実際のテストコード例（まとめ）**
テストデータを作成し、ファクトリを使い、`@TestSetup` を活用する流れをまとめたコードです。

```apex
@isTest
public class TestDataFactory {
    public static Account createAccount(String name) {
        Account acc = new Account(Name = name);
        insert acc;
        return acc;
    }
}

@isTest
private class AccountTest {
    
    @TestSetup
    static void setupTestData() {
        TestDataFactory.createAccount('Test Account');
    }

    @isTest
    static void testAccountExists() {
        List<Account> accs = [SELECT Id FROM Account WHERE Name = 'Test Account'];
        System.assert(accs.size() > 0);
    }
}
```

---

## **まとめ**
| 方法 | 特徴 |
|------|------|
| **手動で作成** | `insert` を直接使う方法。シンプルだが、テストごとにデータを作成する必要がある。 |
| **ファクトリクラスを使う** | テストデータ作成を共通化し、コードをシンプルに保つ。 |
| **@TestSetup を使う** | 共通データを事前に作成し、テストごとにリセットされる。 |

Apex のテストでは **「データを適切に作る」ことが大事** です。  
ファクトリと `@TestSetup` を活用して、効率的なテストデータ管理を心がけましょう！🚀