kintone ユニットテストの基本

kintoneのカスタマイズコードに簡単なユニットテストを実装してみます。
BabelやWebpackを利用出来ない環境でもユニットテストを行うことが可能です。

# 対象

* ユニットテスト書いたことが無い
* ユニットテストが気になっている
* 普通のJavaScriptでユニットテストしたい

# 準備

kintoneカスタマイズ環境を作成します。

kintone-cliを利用するのが便利です。下記拙稿を参考にしてください。
https://qiita.com/sy250f/items/67667301129c26f8a5e7

kintone-cliを利用しない場合は、適当なディレクトをkintoneカスタマイズプロジェクトとして作成してください。

今回は下記のようにしてプロジェクトを作成します。

`$ kintone-cli init --install -p sample02`

`$ cd sample02`

`$ kintone-cli create-template -t Customization -l -i 100 -n sample02`

上記の設定でプロジェクトを作成すると、jsのあるフォルダは下記のようになっていると思います。

```
$ tree -L 3 ./sample02
./sample02
├── config.json
└── source
    ├── css
    │   └── style.css
    └── js
        └── script.js
```


# Jasmineの導入

テストフレームワークに、[Jasmine](https://jasmine.github.io/index.html)を利用します。
今回は素のJavaScriptでテストを実行したいので、Jasmineのスタンドアローン版を設置します。

こちらから、最新版のzipファイルをダウンロードして展開します。
https://github.com/jasmine/jasmine/releases

2022-12-22に確認した最新版は4.5.0でした。
https://github.com/jasmine/jasmine/blob/main/release_notes/4.5.0.md#jasmine-450-release-notes


展開したフォルダ(例えば、jasmine-standalone-3.6.0)をプロジェクトのsourceフォルダに設置します。

```
$ tree -L 3
.
├── config.json
└── source
    ├── css
    │   └── style.css
    ├── jasmine-standalone-3.6.0
    │   ├── MIT.LICENSE
    │   ├── SpecRunner.html
    │   ├── lib
    │   ├── spec
    │   └── src
    └── js
        └── script.js
```

# テスト対象ファイル作成

kintone-cliで作成されたテンプレートを元にテスト対象のファイルを作成します。

```javascript
// 元のファイル
(function () {
  'use strict';
  kintone.events.on('app.record.index.show', function (event) {
    console.log('Hello from kintone CLI');
    return event;
  });
})();
```

kintoneアプリを作成して、一旦適用して動作を確認しておきます。

console.log('Hello from kintone CLI');
部分を関数に切り出します。

```javascript
var SampleLib = (function () {
  'use strict';
  function SampleLib() {
  }

  SampleLib.prototype.hello = () => {
    return 'Hello from kintone CLI';
  }

  return SampleLib;
})();
```

呼び出し側は下記のようになります。

```javascript
(function () {
  'use strict';
  kintone.events.on('app.record.index.show', function (event) {
    const samplelib = new SampleLib();
    console.log(samplelib.hello());
    return event;
  });
})();
```

関数に切り出した部分を別ファイルにします。

ここでは、scriptLib.jsとしています。


# テストファイルの作成
テストファイルを作成します。
今回は、scriptSpec.jsとしています。

`$ touch scriptSpec.js`

中身は後で作成します。

ここまででsourceディレクト以下はこんな感じ

```
$ tree -L 3 ./source
./source
├── css
│   └── style.css
├── jasmine-standalone-3.6.0
│   ├── MIT.LICENSE
│   ├── SpecRunner.html
│   ├── lib
│   │   └── jasmine-3.6.0
│   ├── spec
│   │   ├── PlayerSpec.js
│   │   ├── SpecHelper.js
│   │   └── scriptSpec.js // テストファイル
│   └── src
│       ├── Player.js
│       └── Song.js
└── js
    ├── script.js
    └── scriptLib.js // テスト対象ファイル
```

# テスト実行ファイルの登録

Jasmineのテスト実行ファイル（テストランナー）にテスト対象のファイルとテストファイルを登録します。

テスト実行ファイルは SpecRunner.html です。
下記のように追加します。

```html
  <!-- include source files here... -->
  <script src="src/Player.js"></script>
  <script src="src/Song.js"></script>
  <script src="../js/scriptLib.js"></script>

  <!-- include spec files here... -->
  <script src="spec/SpecHelper.js"></script>
  <script src="spec/PlayerSpec.js"></script>
  <script src="spec/scriptSpec.js"></script>
```

# ユニットテストを書く

ユニットテスト用のファイル、scriptSpec.js を開いて編集します。
テストの書き方は specフォルダにあるサンプルコードを参考にすると良いかと思います。

基本のマッチャー(値テスト用の関数)に .toEqual() と.toBe() を使ってシンプルに値の比較をするだけでも良いかと思います。

## テスト実行

### テストが失敗することを確認

下記で実行すると、失敗することを確認します。

```javascript
(function (){
  'use strict';
  var samplelib;

  beforeEach(function() {
    samplelib = new SampleLib();
  });

  describe('Jasmineのテスト', function () {
    it('kintoneアプリの一覧を開いた時にコンソール出力する', function() {
        expect(samplelib.hello()).toEqual();
    });
  })

})()
```

![スクリーンショット 2020-08-26 9.21.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/8e741848-0c75-84b8-1e82-1ebb3c378747.png)


### テストが成功することを確認

`expect(samplelib.hello()).toEqual();`
この部分を下記に書き換えます。
`expect(samplelib.hello()).toEqual('Hello from kintone CLI');`

実行してテストがパスすることを確認します。

![スクリーンショット 2020-08-26 9.24.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/5e2c0cdf-99c1-eb64-cc6a-3ef1113d02a6.png)


# 備考

* Jasmineのzipファイルを解凍した際の、specとsrcフォルダにあるファイルはサンプルなので、削除してもOKです。

* kintoneのカスタマイズファイルは、グローバルで変数を汚染しないために[即時実行関数](https://developer.mozilla.org/ja/docs/Glossary/IIFE)で書くことが基本となっています。そのため、今回のサンプルではクラスを作成してテストファイルのセットアップ(前処理)関数([beforeEach](https://jasmine.github.io/api/3.6/global.html#beforeEach))にてクラスを読み込むようにしています。


# 参考

* [Jasmine](https://jasmine.github.io/)
* [kintone-cli](https://github.com/kintone/kintone-cli)