イマドキのSalesforce開発のプロジェクト雛形を作った #salesforce

ひとまず取り入れたかった技術要素が盛り込めたので、公開してみました。

開発環境の構築は最初に必要な作業ですが、得てしてハードルが高いので、そのあたりの敷居を下げるのが狙いです。

Lightning Testing Service (LTS) の使い方

LTSを使ってみようとしたわけですが、ドキュメント( https://forcedotcom.github.io/LightningTestingService/ )の情報量が少なく、独自のテストを追加してテストを走らせる方法が、ソースを見るまで分からなかったので、簡単に使い方をメモします。

LTSのインストール

$ sfdx force:lightning:test:install

対象のスクラッチ組織に LTS の非管理パッケージをインストールします。
パッケージ名は「Lightning Testing Service with Examples」です。
デフォルトでは最新バージョンがインストールされ、執筆時点で1.3でした。

これはスクラッチ組織ごとに必須な処理ですが、そんなに大きなパッケージではないため、おおよそ10秒未満でインストールが完了するようです。これくらいだったらCIを回す上でも許容範囲かなと。

独自のテストを作成

$ sfdx force:lightning:test:create -n {テスト名}

ここで作成されるテストクラスは、実体(メタデータ)は静的リソースです。

静的リソースといってもZIPファイルではなく単なるJavaScriptなので、ここにテストを記述していくことができます。

テストスイートとなるLightningアプリケーションを作成

追加した独自のテストを実行させるためには、別途Lightningアプリケーションが必要なようです。
これは、LTSパッケージに含まれているテストスイートでは、LTSパッケージ内に事前に用意されているテストしか実行されないためです。
例えばjasmineTestsテストスイートは以下のように記述されており、3つのテストを実行させるように指定されていますが、当然、こちらで新たに追加したテストは含まれていません。

<aura:application>

    <c:lts_jasmineRunner testFiles="{!join(',', 
      $Resource.jasmineHelloWorldTests,
      $Resource.jasmineExampleTests,
      $Resource.jasmineLightningDataServiceTests
    )}" />

</aura:application>

自分で追加するテストスイート用のアプリケーションでは、上記を真似て、testFiles 属性のところで、作成したテストクラス(静的リソース)の名前を渡してあげるよう変更すればOKです。

<aura:application >
    <c:lts_jasmineRunner testFiles="{!join(',', $Resource.<テスト名>)}" />
</aura:application>

テスト関連のメタデータをデプロイ

上記のLightningアプリケーションと静的リソースをスクラッチ組織にデプロイします。

$ sfdx force:source:push

テストの実行

$ sfdx force:lightning:test:run -a <テストアプリケーション名>

ちなみに、標準でJUnitのレポート出力も用意されているので、Travis CIなどのサービスでなくJenkinsでレポートすることも余計な手間なくできそうです。

テストの書き方

テストコードの文法は、JasmineやMochaの流儀にしたがっていけばよいわけですが、Lightningコンポーネントのテストをするのが目的なので、テストコード中でLightningコンポーネントへのアクセスが必要になります。

LTSの場合、テストコード中では $T というグローバルなオブジェクトが利用できるので、それを使うみたいです。

Jasmineの場合はこんな感じ。

describe("c:Hoge", function () {
  it("sets component attributes", function (done) {
    var that = this;

    $T.createComponent("c:Hoge", null)  // テスト対象となるコンポーネントを作成
      .then(function (component) {

        // 必要であれば、$T.waitFor を使って、条件を満たすまでウエイトを入れることができる
        return $T.waitFor(function () {
          that.component = component;
          return 1 === 1; // サンプルのためすぐに true が評価されるようにして、抜ける
        }, 10000);
      }).then(function () {
        // $T.createComponent のコールバックに作成されたコンポーネントが渡されるので、それを使ってassertionを記述する
        expect(that.component.get("v.attr1")).toBe("aaaaa");
        done();
      }).catch(function (e) {
        done.fail(e);
      });
  });
});

テストコードはバージョン管理上どこに置くべき?

どうすべきなんでしょうね…。

sfdxで素直に作ったプロジェクトであれば foce-app がパッケージディレクトリとなっていると思うので、今回は force-app/test/default 以下にテストコード(静的リソース)やテストスイート(Lightningアプリケーション)を置くようにしてみました。