Vue.js テスト導入に関してのまとめ

## テストについてのリファレンス（全般 -> Vue）
後半ほど重要度が高い
### ALL
 - [テスト仕様書](https://qiita.com/jun2014/items/cad7328978e709fe79f4)
    - テストの種類
        - 単体テスト
        - 結合テスト
        - 機能テスト
        - システムテスト（負荷テスト、ボリュームテスト、セキュリティテストetc)
        - 受け入れテスト（シナリオテスト）
        - 運用テスト
        - リグレッションテスト 
    - ①テスト計画
    - ②テスト設計
    - ③テスト仕様書
 - [テスト自動化について、調べてみた](https://qiita.com/yutachaos/items/857472c7d3c65d3cf316)
    - テストの種類
        - 単体テスト
            - 各moduleの機能を満たしているかを確認するテスト
            - 基本的にホワイトボックステスト
            - メソッド毎
            - 他のmoduleに依存する部分はstub,mock化してテスト
        - 結合テスト
            - 各moduleを連結してテストする
            - 外部APIなどの外部接続するものテストを段階的に行う場合も
            - 基本的にブラックボックステスト、場合によってホワイトボックステスト
            - 複数のmoduleを合わせてプログラムが要件を満たしているか
            - 各module(外部APIやDB部分)が連結する部分も合わせて
        - 総合テスト（UIテスト）
            - 外部APIやブラウザなど全ての条件を結合するテスト
            - 要件通りに動作するかを確認
            - 基本的にブラックボックステスト
    - テストの観点
        - 機能要件
            - クライアント要件を満たす部分
            - テストコードで担保できる部分
        - 非機能要件
            - 情報セキュリティ
            - パフォーマンスetc
    - テストコードの重要度は一般的に 単体テスト > 機能テスト > UIテストの順
 - [若手プロマネの羅針盤](https://pm-rasinban.com/ut-it-st)
    - 単体テスト・結合テスト・総合テストの違い
        - 単体テスト
        - 結合テスト
            - 内部結合テストと外部結合テストの違い
        - 総合テスト
        - テスト結果報告について

### Frontend
 - [フロントエンドのテストに真面目に向き合う](https://qiita.com/okmttdhr/items/cc58e83c259aa0049538)
    - <img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192967/6f11a4fc-1a2d-5e1a-73c3-28f988a31a5f.png">
    - 仮想DOMテスト vs 実DOMテスト
        - 実DOMはブラックボックステストになりがち
        - 仮想DOMテストは比較的制限あり
        - 実DOMは目視できる
    - テストの種類ごとの推奨ライブラリ
 - [フロントエンドのテストについて考える](https://qiita.com/okmttdhr/items/c1e80353928e121c4761)

 - [JavaScript開発のためのテスト入門第1回 テストとはなにか](https://app.codegrid.net/entry/js-test-intro)
    - 記述したテストケースが間違いなく動作することを保証するもの
 - [2016年から始めるフロントサイド~テスト編~](https://qiita.com/koichirokamoto/items/70def71da191c9c87551)
 - [2017年JavaScriptのテスト概論](https://postd.cc/a-complete-guide-to-testing-javascript-in-2017/)
    - テストの種類
        - 単体テスト: 入力をモック化し、個々の関数やクラスをテストし、出力結果が予想通りであることを確認するテスト
        - 結合テスト: いくつかのモジュールを組み合わせて予想通りに動作することを保証するテスト
        - 機能テスト: 製品自体を使って（例えばブラウザを使って）、あるシナリオをテスト
    - テストツールの種類
        - テストの環境を提供する（Mocha、Jasmine、Jest、Karma）
        - テストの構造を提供する（Mocha、Jasmine、Jest、Cucumber）
        - アサーション機能を提供する（Chai、Jasmine、Jest、Unexpected）
        - 生成、表示、テスト結果をウォッチする（Mocha、Jasmine、Jest、Karma）
        - スナップショットを比較する（Jest、Ava）
        - モック、スパイ、スタブを提供する（Sinon、Jasmine、enzyme、 Jest、testdouble]
        - コードカバレッジのレポートを生成する（Istanbul、 Jest)
        - シナリオ実行の管理ができるブラウザ、または疑似ブラウザの環境を提供する（Protractor、Nightwatch、Phantom、Casper）
    - 上記の用語説明（アサーション, スパイ, スタブ, モック）
 - [JavaScript Test-Runners Benchmark](https://medium.com/dailyjs/javascript-test-runners-benchmark-3a78d4117b4)
    - <img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192967/2748821a-7640-adfb-1228-c5bd0d3d7979.png">
 - [ついに jest の軍門に降った](https://qiita.com/karak/items/9d0ebf7bc50085624913)
    - jest選択理由
        - ①機能豊富、設定用意
        - ②ウォッチモードで起動すると、ファイル変更時に依存関係のあるテストだけ走る
        - ③スナップショットテスト
        - ④import/require をモックする必要がなくなった
    - jestデメリット
        - Benchmark.js と組み合わせるとこける
        - TypeScript から使おうとすると追加のパッケージ ＋ お約束の config がいる。mocha と比べると少しだけ手間が大きい
        - 全般にエコシステムが未成熟
 - [Facebook製のJavaScriptテストツール「Jest」の逆引き使用例](https://qiita.com/chimame/items/e97883fd46b67529d59f)
    - セットアップ
    - テスト構文  (describe, it, ...etc)
    - テストマッチャー  (.toBe(), .not, ...etc)
    - promise (resolve, rejectの検証)
    - モック  (mockImplementation, mockImplementationOnce)

### Vue
- [Vue.js公式: 単体テスト](https://012-jp.vuejs.org/guide/application.html#%E5%8D%98%E4%BD%93%E3%83%86%E3%82%B9%E3%83%88)
    - おすすめは、Karma と、そのプラグインの CommonJS pre-processor を使用して、テストを実行する方法
    - Vue.js のディレクティブは、非同期でデータ更新に反応するので、データ更新後の DOM ステータスに対してアサーションを行うには、Vue.nextTick のコールバックを利用する必要があります。
- [Vue Unit Test Performance Comparison](https://github.com/eddyerburgh/vue-unit-test-perf-comparison)
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192967/a0a9ae87-5898-281b-649b-687b39e00398.png)

- [vue-test-utils](https://vue-test-utils.vuejs.org/ja/)
- [Vue.jsテストハンドブック](https://lmiller1990.github.io/vue-testing-handbook/ja/#vue-js%E3%83%86%E3%82%B9%E3%83%88%E3%83%8F%E3%83%B3%E3%83%89%E3%83%96%E3%83%83%E3%82%AF)
- [「後悔しないためのVueコンポーネント設計」を読みました](https://cormorant.hatenablog.com/entry/2018/10/16/044726)
    - テストしやすいコンポーネント
        - 機能が少ない(メソッド数ではなく、担う役割)
        - 依存がない/少ない
        - 状態をもたない
    - ライフサイクルフックに直接処理を書かない
    -  Presentational Component と Container Component
    -  なにをテストするか
        -  templateで次の項目が正しく動作するか
            -  正しくレンダリングされるか
            -  v-on
            -  v-bind:props
            -  v-bind:attes
        -  propsが正しく受け取れるか
        -  methodsが正しく動作するか
        -  $emitでイベントが正しく発火するか
        -  slotが正しく動作するか
        -  コンポーネント同士が正しく協調しているか
- [1年間単体テストを書き続けた現場から送る Vue Component のテスト](https://speakerdeck.com/tsuchikazu/vue-component-test)
    - Componentの何をテストするのか
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192967/42e78a2d-d5f4-006e-da65-e448ed3acaca.png)
    - どうやってテストするのか
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192967/6ac481b4-ae57-cf5c-9cc6-9b04ac7f85c5.png)


        - LifeCycle
            - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192967/3e0b21ea-0b4e-7577-175d-74df77e7cf5d.png)

            - 得られる安心感が低い
        - Props, Vuex State
            - Story book推奨
        - User Interaction
            - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192967/42ebb733-2be8-0c78-6635-cea2a47a8689.png)

- [【2018年】Vueのテスト関連まとめ【非公式】](https://qiita.com/ykhirao/items/129e05f25c203cd0fde3)
    - [Cookbook推奨](https://jp.vuejs.org/v2/cookbook/unit-testing-vue-components.html)

### Vuex
- [Vuex テスト](https://vuex.vuejs.org/ja/guide/testing.html)


## 導入観点
- 導入しながら下記の観点で試行錯誤する

### テストライブラリ
下記の理由でjest採用
- 実DOMでの表示以外を網羅している（実DOM表示は、karma, StoryBook導入で補える？）
- パフォーマンスも他と大差ない
- 公式リファレンスが豊富
- 導入、設定も比較的容易

### Componentのテストって単体テスト？結合テスト？
- クラスベース言語のClass, functionの粒度問題と同じ
- Atomic Designのatomなら単体テストとして捉えられそう

(関数: Component全体, 引数: props, VuexState, 返り値: DOM, emit)

###  単体テスト vs 結合テスト
- どちらかといえば、要件を満たせているのか？（結合テスト）の方が重要だろう

### そのサービスの中で重要度を考える
- 重要度に合わせて、結合テストのみ、結合テスト&単体テストを考慮

### リファクタする範囲をテスト
密結合や粒度の大きいfunction, componentをリファクタするなら、テストを書いてから実施

### 今ままで発生している不具合、仕様検討もれから検討
- その不具合を発生させない（気づく）ために必要だったテストを実装
- 今後も、不具合、使用検討もれが発覚したらば、再発防止用のテストを実装（要検討）

### メンテナンスコスト
- 実コードを修正するたびにテストコードを変更する必要があることも考慮（単体テストがより生じやすい？）
- そもそも変更しなくて済むテストコードもありでは