【SAPUI5】テストの自動化 QUnit

##SAPUI5におけるテストの自動化
SAPUI5では、テスト自動化のために以下のフレームワークが組み込まれています。

- QUnit：javascriptの単体機能をテストする
- OPA5：ページ内でのユーザ操作をテストする（ボタンを押したときのアクションなど）

###テストを自動化するメリットとは
筆者はABAPの経験しかなく、テストのためにわざわざ別のコードを書くことのメリットが正直よくわかりません。一般的には、以下のようなメリットがあると言われます。

- 同じテストを何回も自動で実行できる
- ソースを変更したときの影響確認が簡単にできる

また、QUnitの[リファレンス](http://qunitjs.com/intro/#refactoring-stage-0)を読むと以下のようなメリットもありそうだと思いました。

- 自動でテストできるようにするためには、リソースを構造化しておくことが必要
- それゆえ、テストの自動化を想定して作ることで再利用しやすい構成になる

最初はテスト用のコードが思ったように動かずに苦労しそうです。ですが、慣れてしまえばトータルで見てテスト工数を減らすことができるかもしれません。

##QUnitとは
QUnitとは、javascriptのユニットテストをするためのフレームワークです。
SAPUI5でテンプレートからアプリを作成すると、QUnitが最初から組み込まれています。
公式リファレンス：https://api.qunitjs.com/

###QUnitで何ができるのか
ざっくりとですが、以下のようなことができます。

- APIを使ったテストのグループ化、実行、結果確認
- テスト結果の表示

**テスト結果の画面**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/276021/3cc78fb2-b8c0-c25c-62f8-41f85ee7fd59.png)


##QUnitテストのための最小限の構成
QUnitテストを実行するための最小限の構成は以下のようになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/276021/e1b0aa44-e4f7-82f7-9fba-8e8bd5d49976.png)

フォルダ構成
![image.png](https://qiita-image-store.s3.amazonaws.com/0/276021/e956b036-bc09-e14a-8b52-a8cd964bdcfa.png)

###結果表示用htmlページ
先頭2行は結果表示用のCSSと、qunitのライブラリの読み込みです。"test.js"というファイルがテスト用のコードにあたります。"formatter.js"がテスト対象機能です。

```html
<html>
    <head>
        <link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.9.2.css">
        <script src="https://code.jquery.com/qunit/qunit-2.9.2.js"></script>
        <script src="formatter.js"></script>
        <script src="test.js"></script>
    </head>
    <body>
        <div id="qunit"></div>
        <div id="qunit-fixture"></div>
    </body>
</html>
```
###テスト対象機能
以下のようなformatter機能をテストします。受け取った値が初期値なら空白("")を返し、そうでなければ小数点以下2桁に整形して返します。

```javascript
function currencyValue(sValue) {
	if (!sValue) {
		return "";
	}
	return parseFloat(sValue).toFixed(2);
}
```

###テスト用のコード
QUnit.moduleで以降のテストをグループ化し、QUnit.testでユニットテストを実行します。moduleと複数のtestがひとかたまりのテストを構成します。
assertionでテスト対象機能から返された値と想定する値を比較し、一致すれば成功です。

```javascript
QUnit.module("fomatter - Currency unit Conversion Test");

QUnit.test("Should round down to a two digit from 3 digit(positive)", function (assert) {
	var input = "3.123";
	var converted = currencyValue(input);
	assert.strictEqual(converted, "3.12", "The test for curr. formatter passed");
});

QUnit.test("Should round down to a two digit from 3 digit(negative)", function (assert) {
	var input = "-3.123";
	var converted = currencyValue(input);
	assert.strictEqual(converted, "-3.12", "The test for curr. formatter passed");
});
```
QUnitのassertionは複数の種類があります。詳細については以下のリファレンスをご参照ください。
https://api.qunitjs.com/assert/

###結果
test.htmlを実行すると以下のように結果が表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/276021/2cde5fa8-8da4-1f84-2c94-2d2a64094ca2.png)

##SAPUI5でのQUnitを実行
最小限の構成がわかったところで、SAPUI5でQUnitを実行するための構成について見ていきましょう。
###テストのための構成
テンプレートからアプリを作ると自動的にtestフォルダが作られます。テンプレートに含まれているformatter.jsやmodels.jsの機能については、テスト用のjsファイルもデフォルトで作られます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/276021/d816b0a2-d086-ae73-8637-3ef5abdf6397.png)
これらのファイルの関係は以下のようになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/276021/fffd4bda-4690-4ea7-19c1-5830437aba01.png)

このようにテスト対象機能のjsファイルとテスト用jsファイルは同じ構成、名称で作るのが慣例です（どの機能に対するテストかわかりやすいため）。**手を入れる必要があるのは、テスト用のコードだけです。**

###そのまま実行してみる
unitTests.qunit.htmlファイルを右クリックし、Run>Run as Unit Testで実行します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/276021/8d8ee7bd-6a35-4f61-ba80-7be0c6fc323d.png)

以下のように結果が表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/276021/d8ff759c-0fe5-a189-84a7-464ad5b2e93a.png)

結果が多すぎて見にくいときは、右上のフィルタからテスト対象を絞ることができます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/276021/f31cf9a3-2f68-d31c-a6c4-6e5c317f126b.png)

"Enable coverage"にチェックを入れると、テスト対象のコードのうち何%がテスト済かを表示できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/276021/de7dd164-ebb5-79fb-54dc-874ad75c9c02.png)

###このほかに何をテストすればいいのか？
デフォルトでもテスト用のコードが入っているわけですが、ほかに何をテストすればよいのでしょうか。
基本的には**自分で追加したcontrollerやformatterなどのjsファイル**がテスト対象となります。ただ、controllerのメソッドはDOMを変更したり、メッセージを出したり、画面との結びつきが強いので単体機能として切り出すのが難しそうです。おそらく、画面と絡む部分はOPA5テストの領域になるのでしょう。QUnitはインプットに対して決まったアウトプットを返すようなシンプルな機能向けと思われます。

##参考
[Testing your SAPUI5 application with OPA5](https://blogs.sap.com/2018/10/03/testing-your-sapui5-application-with-opa5/)
[Automated Testing for SAP Fiori Apps: Piece of cake with SAP Web IDE and the SAPUI5 testing tools](https://blogs.sap.com/2018/05/21/automated-testing-for-sap-fiori-apps-piece-of-cake-with-sap-web-ide-and-the-sapui5-testing-tools/)