【Salesforce/AppExchange】テストデータをコード化して、心地良いスクラッチ組織開発を心がける

# 本記事を読むとわかること
本記事の読者は、SalesforceのAppExchangeで公開しているアプリ開発をされている方向けです。
パッケージ組織のソースを使ってスクラッチ組織を作成する際、テストデータはどのように扱っていますか？

量が少ない場合、手で作成しているかも知れません。
自分も当時、カスタムオブジェクトのレコードをいちいち手で作成してから実装をしていました。

本記事では、スクラッチ組織を作った際に、簡単にテストデータを読み込む方法をご紹介します。

## 方法：下準備編
今回の効率化に関して、登場するファイルを紹介します。

1. テストデータを検索する用のsoqlファイル
2. 1によって出力されたテストデータを作成する用のjsonファイル
3. データのインポート手順を書いたjsonファイル

以上です。1のSOQLファイルを使って、インポートに必要なデータ構造を記録したファイルを作成し、3の手順書のようなものでインポートします。

## 方法：実践編
では、具体的な実践方法です。
さまざまなやり方があるのですが、今回は**既に環境にあるデータをテストデータにしたい場合**を想定します。

### SOQLファイルの作成
まず、`testData`などのディレクトリを作成します。
その中に、以下のようなファイルを作成してください。今回はAccountで試してみます。

```sql:Account.soql
SELECT FIELDS(STANDARD) FROM Account
```

`FIELDS(STANDARD)`は全てのカラムのデータを取ってくる書き方です。soqlでは「*」が使えないのでこうしています。
こちらのファイルは作成必須ではないのですが、何かあった時ようにどんなクエリを実行したか残しておくために作成しています。

### ターミナルでクエリを実行し、2のjsonを取得する

では、ターミナル等のコマンドラインで以下のコマンドを実行してください。

```console
sfdx force:data:soql:query -q "SELECT FIELDS(STANDARD) FROM Account" --json 
```

`--json`オプションをつけることで、結果の出力をjson形式にしています。
これをすることで、出力結果をそのままテストデータの2のjsonとして使用できます。

出力結果

```json
{
  "status": 0,
  "result": {
    "done": true,
    "totalSize": 1,

// 使うのはここから

    "records": [
      {
        "attributes": {
          "type": "Account",
          "url": "/services/data/v53.0/sobjects/Account/0010l00001NG1wsAAD"
        },
        "Id": "0010l00001NG1wsAAD",
        "IsDeleted": false,
        "MasterRecordId": null,
        "Name": "エンタイトルメントの取引先のサンプル",
        "Type": null,
        "ParentId": null,
        "BillingStreet": null,
        "BillingCity": null,
        "BillingState": null,
        "BillingPostalCode": null,
        "BillingCountry": null,
        "BillingLatitude": null,
        "BillingLongitude": null,
        "BillingGeocodeAccuracy": null,
        "BillingAddress": null,
        "ShippingStreet": null,
        "ShippingCity": null,
        "ShippingState": null,
        "ShippingPostalCode": null,
        "ShippingCountry": null,
        "ShippingLatitude": null,
        "ShippingLongitude": null,
        "ShippingGeocodeAccuracy": null,
        "ShippingAddress": null,
        "Phone": null,
        "Fax": null,
        "AccountNumber": null,
        "Website": null,
        "PhotoUrl": null,
        "Sic": null,
        "Industry": null,
        "AnnualRevenue": null,
        "NumberOfEmployees": null,
        "Ownership": null,
        "TickerSymbol": null,
        "Description": null,
        "Rating": null,
        "Site": null,
        "OwnerId": "内緒だよ",
        "CreatedDate": "2021-11-19T18:00:55.000+0000",
        "CreatedById": "内緒だよ",
        "LastModifiedDate": "2021-11-19T18:00:55.000+0000",
        "LastModifiedById": "内緒だよ",
        "SystemModstamp": "2021-11-19T18:00:55.000+0000",
        "LastActivityDate": null,
        "LastViewedDate": null,
        "LastReferencedDate": null,
        "Jigsaw": null,
        "JigsawCompanyId": null,
        "AccountSource": null,
        "DunsNumber": null,
        "Tradestyle": null,
        "NaicsCode": null,
        "NaicsDesc": null,
        "YearStarted": null,
        "SicDesc": null,
        "DandbCompanyId": null
      }
    ]
// 使うのはここまで

  }
}
```

nullが多いですが、いい感じです。
どのようなデータが取れたかの部分は使わないので、注意してください。

### テストデータの作成

では、`testData`ディレクトリに、上記のjsonの使う部分だけ貼り付けます。
以下のファイルを作成しましょう。

```json:testData/Account.json
{ // ココ忘れずに
    "records": [
      {
        "attributes": {
          "type": "Account",
          "url": "/services/data/v53.0/sobjects/Account/0010l00001NG1wsAAD"
        },
        "Id": "0010l00001NG1wsAAD",
        "IsDeleted": false,
        "MasterRecordId": null,
        "Name": "エンタイトルメントの取引先のサンプル",
        "Type": null,
        "ParentId": null,
        "BillingStreet": null,
        "BillingCity": null,
        "BillingState": null,
        "BillingPostalCode": null,
        "BillingCountry": null,
        "BillingLatitude": null,
        "BillingLongitude": null,
        "BillingGeocodeAccuracy": null,
        "BillingAddress": null,
        "ShippingStreet": null,
        "ShippingCity": null,
        "ShippingState": null,
        "ShippingPostalCode": null,
        "ShippingCountry": null,
        "ShippingLatitude": null,
        "ShippingLongitude": null,
        "ShippingGeocodeAccuracy": null,
        "ShippingAddress": null,
        "Phone": null,
        "Fax": null,
        "AccountNumber": null,
        "Website": null,
        "PhotoUrl": null,
        "Sic": null,
        "Industry": null,
        "AnnualRevenue": null,
        "NumberOfEmployees": null,
        "Ownership": null,
        "TickerSymbol": null,
        "Description": null,
        "Rating": null,
        "Site": null,
        "OwnerId": "内緒だよ",
        "CreatedDate": "2021-11-19T18:00:55.000+0000",
        "CreatedById": "内緒だよ",
        "LastModifiedDate": "2021-11-19T18:00:55.000+0000",
        "LastModifiedById": "内緒だよ",
        "SystemModstamp": "2021-11-19T18:00:55.000+0000",
        "LastActivityDate": null,
        "LastViewedDate": null,
        "LastReferencedDate": null,
        "Jigsaw": null,
        "JigsawCompanyId": null,
        "AccountSource": null,
        "DunsNumber": null,
        "Tradestyle": null,
        "NaicsCode": null,
        "NaicsDesc": null,
        "YearStarted": null,
        "SicDesc": null,
        "DandbCompanyId": null
      }
    ]
} // ココ忘れずに
```

今、ディレクトリは以下のような感じです。

```console
.testData
├── Account.json
└── Account.soql
```

### データのインポート手順を書いたjsonファイルを作成する
では、2で作成したテストデータをインポートするファイルを作成します。

`[プロジェクト名]-plan.json`という名前で作成してください。

```json:testData/hoge-plan.json
[  
  {
    "sobject": "Account__c",
    "saveRefs": true,
    "resolveRefs": true,
    "files": ["Account.json"]
  }
]
```

このような感じです。

ここまでできたら、スクラッチ環境の作成時に
`sfdx force:data:tree:import -p ./testData/hoge-plan.json`
を実行してあげれば、作成したテストデータをインポートできます。


ここまで説明すると、親子関係のデータはどうするんだ！と疑問に思いますよね...(__)
こちらに関しても別途方法はあるのですが、諸事情でここには書けないため参考記事を掲載しておきます。

階層があるデータのインポート時にも活用できますし、シェルスクリプトを組んで`package.json`にまとめておくと、スクラッチ組織作成時に全てのテストデータ作成＋権限の割り当てなんかもできるので、ぜひ挑戦してみてください。

https://qiita.com/hanamizuki10/items/35a8095a57ca2c8f1ca8

## 最後に
Salesforceで「アプリ開発」をしたいエンジニアも募集しています！
WEB系の言語も同時に経験できますので、ぜひご連絡くださいー！

https://www.wantedly.com/companies/company_3244501/projects