Sencha Architect と Sencha Test で開発環境を構築する

Sencha Architect と Sencha Test で開発環境を構築する手順をメモっとく。

この記事では、ワークスペースを用いてアプリケーションのプロジェクトとテストのプロジェクトを分離する。そうすることでコンポーネントごとのテストを書けるようにして、テスト実行の安定性と速度を向上させている。

# 前提条件

この記事では下記バージョンの Sencha ツール群を使用している。

| Tool             | Version   |
|------------------|-----------|
| Sencha Architect | 4.2.7     |
| Sencha Ext JS    | 7.1.0.48  |
| Sencha Cmd       | 7.1.0.16  |
| Sencha Test      | 2.3.0.328 |

# ワークスペースを生成する

Sencha Cmd を使用してワークスペースを生成する。

```shell-session
$ sencha generate workspace example
$ cd example
$ git init
$ git add .
$ git commit -m "Generate workspace"
```

# Sencha Architect プロジェクトを新規作成する

Sencha Architect でプロジェクトを新規作成する。フレームワークとして Ext JS 7.1.x Modern を選択し、テンプレートとして Blank Project を選択する。

![New Project](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67627/e2a36de7-0f5c-9216-da9f-861854feee77.png)

プロジェクト設定 (Project settings) でポート番号を1842番に指定する。Sencha Architect のプロジェクトファイルに保持されるポート番号が動的に変わるのを防ぐため。

![Project Settings](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67627/647ec616-f335-17fd-760c-70a30f783465.png)

Sencha Architect プロジェクトを下記の設定で保存する。Save Path をワークスペースに指定するのを忘れやすいので注意すること。

* Save Path: ＜ワークスペース＞
* Project Name: main
* App Name: Example

![Save Project](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67627/f71c6a98-aa93-7c48-278f-ae21e3d9a69e.png)

Sencha Architect が生成するローカルファイルを Git が無視するように設定する。

```shell-session
$ cat << EOS >> .gitignore
.architect
.arch-internal-preview.css
EOS
$ git add .
$ git commit -m "Generate main project"
```

# Sencha Test プロジェクトを生成する

Sencha Cmd でテストプロジェクトを生成する。SDK としてワークスペースにある Ext JS を指定する。また、スターターテンプレートを無効にして、Modern ツールキットを使用するようにも指定する。

```shell-session
$ sencha -sdk=ext generate app -starter=false -modern ExampleTest test
```

app.json にあるクラスパスの設定に `"../main/app"` をオーバーライドの設定に `"../main/overrides"` を追加する。

```shell-session
$ sed -i "" 's|"app"$|"app", "../main/app"|' test/app.json
$ sed -i "" 's|"overrides"$|"overrides", "../main/overrides"|' test/app.json
```

test/app.js のメッセージボックスを表示する処理を削除する。

```javascript:test/app.js
/*
 * This call registers your application to be launched when the browser is ready.
 */
Ext.application({
    name: 'ExampleTest'
});
```

テスト実行時にブラウザーの種類を表示するようにコードを追加する。テスト実行のデモをするときには便利。必須ではない。

```javascript:test/app.js
/*
 * This call registers your application to be launched when the browser is ready.
 */
Ext.application({
    name: 'ExampleTest',

    requires: [
        'Ext.Panel'
    ],

    launch: () => {
        var config = { floated: true, right: 0, bottom: 0 };
        if (Ext.isChrome) Ext.merge(config, { iconCls: 'x-fab fa-chrome',  title: 'Chrome'  });
        if (Ext.isEdge  ) Ext.merge(config, { iconCls: 'x-fab fa-edge',    title: 'Edge'    });
        if (Ext.isGecko ) Ext.merge(config, { iconCls: 'x-fab fa-firefox', title: 'Firefox' });
        if (Ext.isOpera ) Ext.merge(config, { iconCls: 'x-fab fa-opera',   title: 'Opera'   });
        if (Ext.isSafari) Ext.merge(config, { iconCls: 'x-fab fa-safari',  title: 'Safari'  });
        Ext.create('Ext.Panel', config).show();
    }
});
```

Sencha Studio でワークスペースを開く。New Project ではなく Open Project であることに注意。Example ワークスペースの ExampleTest アプリケーションでテストプロジェクトの初期化 (Initialize Test Project) を実施する。タブが ExampleTest Tests になっていることを確認してから Initialize Test Project ボタンをクリックすることに注意。

![Initialize Test Project](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67627/93dcb976-d31f-e486-efc9-b87db38d951b.png)

テストプロジェクトを下記の設定で保存する。コードカバレッジが正常に出るようにコードカバレッジフィルター (Code Coverage Filters) も合わせて設定しておく。

* Location (URL): http://localhost:1841/test/
* Automatically start app watch: Enable
* Code Coverage Filters:
    * ^/ext/.*?$
    * ^/build/.*?$
    * ^/test/.*?$

![Test Project Settings](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67627/7d51c616-1ae9-0dc2-42b4-3274f533f7a7.png)

コンポーネントテストのためのシナリオを下記の設定で新規作成する。

* Name: Component
* Test type: In-browser
* Directory: component
* Additional Libraries: すべて削除する

![Scenario Settings](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67627/e94f938b-2a75-9557-41a4-a206d7b74070.png)

```shell-session
$ git add .
$ git commit -m "Generate test project"
```

# 実装とテストができるか確認する

Sencha Architect で右上のツールボックス (Toolbox) からボタン (Button) をドラッグアンドドロップして追加する。

![Add MyButton to main project](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67627/38723e13-6543-81ef-53aa-cf464bc2d99f.png)


ツールバーの保存ボタンをクリックして保存し、保存ボタンの右隣のアイコンをクリックして、プレビュープロジェクト (Preview Project) ダイアログのプレビュー (Preview) ボタンをクリックしてプレビューする。下記のように全画面の MyButton が表示されれば実装はきちんとできている。

![MyButton in main application](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67627/7e124b1c-b0c7-c2c0-20b4-8e51e5aa1f39.png)

Sencha Studio で Jasmine テストスイートを MyButtonTest という名前で作成する。

![Create Jasmine test suite](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67627/48912e49-1e91-c47f-b465-775f403a0f4d.png)


MyButton をクリックして、`tap` イベントが発生することを確認するテストを記述する。

ここで `beforeEach` メソッドで、テスト対象の `MyButton` コンポーネントを生成し、テストアプリケーションのビューポートに追加している。テストではそのボタンを取得し、ボタンにイベントハンドラーを動的に付与し、`tap` イベントが発生したら `done` メソッドを呼び出してテストを成功させるようにしている。なので、後続する `click` メソッドの呼び出しで、`tap` イベントが発生し、前述のイベントハンドラーが実行されることでテストが成功する。`afterEach` メソッドでテストのために生成したコンポーネントを破棄して、ひとつのテストケースが完了する。

```javascript:test/test/component/MyButtonTest.js
describe("MyButtonTest", function () {
    let component;

    beforeEach(function () {
        component = Ext.create("Example.view.MyButton");
        Ext.getApplication().viewport.add(component);
    });

    afterEach(function () {
        component.destroy();
    });

    it("fires \"tap\" event after clicking", function (done) {
        ST.button("[text=MyButton]")
            .and(button => button.on("tap", () => done()))
            .click();
    });
});
```

![MyButtonTest.js](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67627/4c59c156-5317-d86d-20e0-6bcb84666d51.png)

Component テストシナリオを選択し、ブラウザー (Browsers) からテストを実行したいブラウザーを選ぶ。そうすると、Sencha Studio からアプリケーションを立ち上げるか確認するダイアログが出ると思うので、Sencha Studio にアプリケーションを立ち上げてもらう。そして、テスト実行 (Run) ボタンをクリックする。

![Run tests](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67627/121301c9-9f0f-a8fb-e3ad-fb12db88f3b8.png)

テストが無事に完了すれば開発環境が正常に構築できたことになる。

---

この記事では Sencha Architect と Sencha Test で開発環境を構築する方法について説明した。生産性高く SPA が作れる環境だと思うので、興味のある人はトライアル版で試してみてほしい。