今日からはじめるJS UnitTest
自己紹介
- ども。KAYACでJS書いてる@kyo_agoです
- 最近はスマホ環境で色々JS書いてます
テストをはじめる上で重要なこと
「理由」
テストを「書く理由」は何ですか?
なぜ「テストを書く理由」が重要なのか
- テストもプログラムの一部
- ただし、直接は機能を追加しない
- しかも、メンテナンスコストは高い
テストコードは本体のコードより「書く理由」がはっきりしていなくてはならない
書く理由がないならテストを書いては「いけない」
テストを書く前に以下の内容を考えましょう
- どういった結果を得たいのか
- もっと簡単な方法はないか
- どこまでやるのか
個人的に考えたテストを書く7つの理由
テストを書く7つの理由
- ロジックが想定した内容であることを確認する
- 複数ブラウザで動作確認をする
- 複数人で同時開発する場合に整合性を保つ
- ドキュメントとしてのテスト
- テストしやすい作りにするための設計手法
- 一度起こったバグが再発しない保証
- 趣味、スキルアップ
テストを書く7つの理由
- ロジックが想定した内容であることを確認する
- 複数ブラウザで動作確認をする
- 複数人で同時開発する場合に整合性を保つ
- ドキュメントとしてのテスト
- テストしやすい作りにするための設計手法
- 一度起こったバグが再発しない保証
- 趣味、スキルアップ
ロジックが想定した内容であることを確認する
- テスト対象が想定した動作を行うかを検証する目的で書く
- 検証外の動作を発見できることを成功とする
- コードカバレッジ重要
- 証明度合いを上げるにはテストに対しての専門的な知識が必要
- 一般に「ソフトウェア・テスト」と呼ばれる方法
テストを書く7つの理由
- ロジックが想定した内容であることを確認する
- 複数ブラウザで動作確認をする
- 複数人で同時開発する場合に整合性を保つ
- ドキュメントとしてのテスト
- テストしやすい作りにするための設計手法
- 一度起こったバグが再発しない保証
- 趣味、スキルアップ
複数ブラウザで動作確認をする
- 「エンジニアがIEでテストしない問題」
- ブラウザ自体とアプリケーションのテストは分けて考える
- 違うブラウザで想定外の挙動にならないことが目的
- 細かい挙動まで確実にテストするのは難しい
- 複数ブラウザをリモートから制御できるツールがおすすめ
テストを書く7つの理由
- ロジックが想定した内容であることを確認する
- 複数ブラウザで動作確認をする
- 複数人で同時開発する場合に整合性を保つ
- ドキュメントとしてのテスト
- テストしやすい作りにするための設計手法
- 一度起こったバグが再発しない保証
- 趣味、スキルアップ
複数人で同時開発する場合に整合性を保つ
- コードレビューを兼ねてテストを書く
- 技術継承やペアプロの一環として
- それぞれがお互いのコードを把握するのが目的
- 「メインコードを書く人」と「テストコードを書く人」を分ける方法も
- 参加者が増えるのでCIと連携しやすいツールがおすすめ
テストを書く7つの理由
- ロジックが想定した内容であることを確認する
- 複数ブラウザで動作確認をする
- 複数人で同時開発する場合に整合性を保つ
- ドキュメントとしてのテスト
- テストしやすい作りにするための設計手法
- 一度起こったバグが再発しない保証
- 趣味、スキルアップ
ドキュメントとしてのテスト
- コードのドキュメントをテスト形式で書く
- コードの使い方などを共有することが目的
- 主なAPIや使い方のみをピックアップしてテスト形式で書く
- ブラウザ上で実行可能なサンプルコード兼APIリファレンスにもなる
- ドキュメント化のみが目的なら実行はできなくてもいい
- 例:JSDeferred
テストを書く7つの理由
- ロジックが想定した内容であることを確認する
- 複数ブラウザで動作確認をする
- 複数人で同時開発する場合に整合性を保つ
- ドキュメントとしてのテスト
- テストしやすい作りにするための設計手法
- 一度起こったバグが再発しない保証
- 趣味、スキルアップ
テストしやすい作りにするための設計手法
- TDDやBDDと呼ばれる領域
- 「先にテストを書いてからコードを書く」場合が多い
- テストしやすいコードを書くことが目的
- 実行回数が多くなるのでコンソールから実行しやすいツールがおすすめ
テストを書く7つの理由
- ロジックが想定した内容であることを確認する
- 複数ブラウザで動作確認をする
- 複数人で同時開発する場合に整合性を保つ
- ドキュメントとしてのテスト
- テストしやすい作りにするための設計手法
- 一度起こったバグが再発しない保証
- 趣味、スキルアップ
一度起こったバグが再発しない保証
- バグが起こった場合に、そのバグが修正されたことを確認するテストを書く
- 同じ問題が再発した場合にテストで検知することが目的
- 「テストしやすい作りにするための設計手法」に近い
- CIと連携しやすいツールがおすすめ
テストを書く7つの理由
- ロジックが想定した内容であることを確認する
- 複数ブラウザで動作確認をする
- 複数人で同時開発する場合に整合性を保つ
- ドキュメントとしてのテスト
- テストしやすい作りにするための設計手法
- 一度起こったバグが再発しない保証
- 趣味、スキルアップ
趣味、スキルアップ
- 結構楽しいので趣味としてもおすすめ
- 自分が楽しむこと、次回テストを書くときに参考になることが目的
- テストを書いたことがないとどういった結果が得られるのか予想がつかないので正しい選択ができない
- プログラムを書いた経験だけではテストの設計、予想は困難
- ネット上に情報が多いツールがおすすめ
どの理由から始めたらいいのか
どの理由から始めたらいいのか
- 最初は「趣味、スキルアップ」、「ドキュメントとしてのテスト」がおすすめ
- ツールの使い方、テストの概念に慣れる
どの理由から始めたらいいのか
- 次は「一度起こったバグが再発しない保証」、「ロジックが想定した内容であることを確認する」を目標に
- 「テストしやすいコード設計」、「テストしにくいコードに対してのテスト手法」を身につける
どの理由から始めたらいいのか
- 「複数ブラウザで動作確認をする」、「複数人で同時開発する場合に整合性を保つ」はその後、必要に応じて
- 「テストしやすい作りにするための設計手法」は一番最後に
どこまでやったらいいのか
ツールに関して
どのテストフレームワークを選択するか
どのテストフレームワークを選択するか
- お手軽に始めたいならJasmineがおすすめ
- QUnitは情報が多い利点はあるが、CIへの移行が大変だったり、コンソールとの相性が悪い
- 複数ブラウザでの並行テストやスマホでのテストを行うならJsTestDriverがいい
どのテストフレームワークを選択するか
- ある程度大規模にやるならJsTestDriverがおすすめ
- OS問わず環境構築が楽、コンソールとの相性もいい、CIとの連携も簡単
- IEだろうがWindowsPhoneだろうがテストできる
- ただし、エラーが意味不明なのと、公式ドキュメントが壊滅的なのと、ASCII以外が化けるのが欠点
- 開発環境にWindowsを考えなくていいならBusterJSもおすすめ
- 参考リンク:基本的なはじめ方
おすすめ設定
フレームワークと同時に重要なのがmockツール
mockツールとは元のmethodを一時的に差し替えるためのツール
mockツール
- 「JSのテストが難しい」というのは「mockを正しく使えてない」場合が多い
- Jasmineは内部で持ってる
- 単体でSinonJSもある
- 個人的にはSinonJSおすすめだけど、Jasmine使うならJasmineだけでも
- 参考リンク:
0-9, JSのUnitTest関連技術
mockの用語説明
mockの用語説明
- spy
- 「対象のfunctionがどんな形で呼ばれたか」を記録しておくためのmethod
- 対象のfunctionの動きは変えない
- stub
- 「対象のfunctionをspyしつつ、動きを止めるfunction」に差し替える
- 「特定の引数の場合のみ動きを止める」、「特定の変数を返す」等にも差し替え可能
mockの用語説明
- mock
- 「対象のfunctionをstub化しつつ、特定の引数の場合自動でassertを投げるfunction」に差し替える
- stub+assertのようなもの
- fake*
- 主にDateやXHRを差し替えて非同期実行を同期化したり、特定の引数に特定の値を返すように差し替える
mockの用語説明
- 基本的にspy -> stub -> mockの順に高機能になって行く
- 高機能になるにつれてできることが増えていく
- ユーザが低機能APIに機能を足して高機能APIと同じ事をすることもできる
最後に
最後に
- 「テストを想定していないコードのテスト」はかなり難易度が高い
- テストになれるとテストしやすいコードを書く
- つまり、最初に書くテストほど難易度が高いという矛盾。。。
- 理想はテストを想定されて書かれたコードのテストから入る