memo: テスト

= テストの基本的な流れ
初期状態を設定し、関数を実行し、そのあと最終状態でアサート

------
= テストは大きく３種類に分類されます

- ユニットテスト
機能一つ一つの独立した依存性のないテスト。インプットに対し、アウトプットが適切か確認する。
特定の機能や特定のバグに限定してテストを行うことで、問題をピンポイントで特定し、再出するバグを防ぐ目的などに有効です。
ツール一例：Mocha, Jasmine and Tape

- 結合テスト
システムの独立した各パーツを複数同時に実行するケースをテストする場合や、データベースを参照するケースに、どのような動作をするか、状態遷移が正しいかを確認するためのテスト。


- 機能テスト(E2E テスト, Acceptance testsと呼称される場合もあります)
アプリケーションの機能の動作確認するテスト。
ウェブアプリのテストの場合は、ブラウザの自動テストを行うツールを利用します。
例：Selenium, Selenium WebDriver, Protractor, PhantomJS, CasperJS
ユーザーインターフェースのテストに実行されることが多いです。
例：サインアップフローなど


------
= Reactでのユニットテストのポイント
Reactで扱うコンポーネントのほとんどは、 自身で状態を持たないstateless functional componentです。
つまり、コンポーネントが関数であり、引数で受け取ったデータに対しては毎回同じビューが返されるという性質をもっていますので、
ユニットテストを行う際に、まずはコンポーネントが正しいデータをレンダリングしているかをテストすることが重要です。
インタラクティブな操作を含む場合は、インタラクションのテストも書く必要があります。

ビジネスロジックについては、Reactのユニットテストではなく、主にReduxのユニットテストを実行します。

Reactでのユニットテストでの定番ツール
- Jest（Jasmine2をベースに作られたテスティングフレームワーク)
- enzyme（テストユーティリティ）　
* create-react-app、react-native init を使用する場合は、デフォルトでJestが構成されており、Babelなどの設定は不要
* enzymeは別途セッティングが必要です。
例：
Reactにenzymeを連携させる場合: enzyme-adapter-react-16
Jestでenzyme-matchersを使用する場合: jest-enzyme 
など

-----
= Jestの概要
Reactアプリケーションを含む全ての JavaScriptコードのテストに利用が可能です。
Babel および ts-jest を介してTypeScriptともシームレスに統合されています。
Node.js上のjsdomで実行されるので、DOMを扱うテストもブラウザが必要なく、コマンドベースで実行できます。
ウォッチモードは変更されたファイルに関連するサブセットのテストのみを実行できるので、テスト範囲が広いときに効率的です。
JSDom設定を備えていて、ブラウザテストを記述できます。
Nodeを介して実行され、非同期テストに取り組め、組み込みのモック、スパイ、スタブなど高度な機能も備えています。
Jasmine 2 をベースに作られているので、JasmineのMatcherを踏襲できます。
Karmaのようなテストランナーも別でインストールする必要はありません。
豊富なMockライブラリなどが用意されており、Mockを自動で作成してくれる機能など、Mockが扱いやすい仕様です。
デフォルトではオフになっていますが、読み込んだモジュールは全てMockに置き換えられる仕様です。
テストダブル、スナップショットテストにも対応しており、Jestだけでさまざまなテストが行えます。

/ Jestのスパイ機能:
関数が特定の引数で呼び出されていることをアサートする際に利用します。
/ モック機能: 
既知の入力値でテストを確実に実行するために、特定のモジュールや振る舞いを偽装することです。
/ スナップショットテスト:
結果のデータ構造を想定したものと比較したい場合に実行します。
// スナップショットテストを行うには、別途react-test-rendererをインストールする必要があります。
react-test-rendererは、Reactコンポーネントを受け取って純粋なJavaScriptオブジェクトとしてレンダリングできるパッケージです。Jestがスナップショットをウォッチし続けるために使用されます

-----
= Jestの主な特徴

- Developer Ready
JavaScript テストソリューションをどのようなReactプロジェクトでも網羅的に容易にセットアップできます。 

- パフォーマンス: 
大規模、小規模のプロジェクトともにサポートするように設計されています。
balelのアウトプットをキャッシュすることで、必要最小限で迅速なイテレーションを行います。

- 高速なフィードバック
高速なインタラクティブウォッチモードは、変更されたファイルに関連するテストファイルのみを実行することで、結果を素早く知らせるように最適化されています。

- スナップショットテスト
Reactツリーまたは他のシリアライズ可能な値のスナップショットをキャプチャすることで、テストを簡素化し、また時間の経過による状態の変化を分析できる仕様です。

/ コンポーネントの出力が正しいかテストする際に、Reactコンポーネントで大量のアサーションを行うより、スナップショットテストを実行する方が効率的です。コンポーネントの動作が誤って変更されてしまうことがないので、より堅牢です。

- テストのアイソレーションとサンドボックス化された環境
Jest はパフォーマンスを最大化するため、テストをワーカーにまたがり並列実行する仕様です。
テストファイルはサンドボックス化され、グローバルなステートは各テストにて自動的にリセットされるため、複数のテストやグローバルモジュール、ローカルステートがコンフリクトを起こすことがありません。
コンソールのメッセージはバッファされ、テスト結果と共に出力されます。


-コードカバレッジレポート機能を内蔵
`--coverage` を使用すると、コード・カバレッジ・レポートを簡単に作成できる仕様です。
 Jest は、テスト対象でないファイルを含むプロジェクト全体からコード・カバレッジ情報を収集できます。

- ゼロ・コンフィギュレーション
React または ReacNativeプロジェクトを作成するのにcreate-react-app もしくは react-native init を使用した場合には、Jestはすでにが組み込まれています。
`__tests__` フォルダにテストを格納するか、テストのファイル名に.spec.js または.test.js拡張子を付けてると、いずれの場合でも、Jestはファイルを見つけて実行する仕様です。


-----
= enzymeの概要
Reactコンポーネントのテストを容易にするラッパーライブラリー。
Reactのテストユーティリティツールで、enzymeを使用するとテストコードが簡潔に書け、assertも簡単に出来ます。
テストのたびにブラウザーを立ち上げることなくDOMベースのテストを実行できます。

= enzymeの主な特徴
Reactのテストコードの記述を簡単にしてくれるテストユーティリティです。
紐づいた入れ子componentを無視するshallowレンダリングの機能を実装しており、component単体でテストが行える仕様です。
shallow render はテスト対象のcomponentのみを実際に走らせてrenderし、入れ子になっているcomponentについてはmockを代わりにrenderする仕様です。
また、テスト内でコンポーネントをレンダリングする際に、子componentも含めてフルレンダリングしてテストを行うことも可能です。
assertについてはjQueryライクのセレクタを使ってReactのcomponentツリーを検索出来る特徴があります。