Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

テストコード入門

勉強会の発表資料

  • Be the first to comment

テストコード入門

  1. 1. テストコード入門 2017/2/15 sh-ogawa
  2. 2. 目次  はじめに  テストコードとは  テストコードのメリット、デメリット  テストコードとの付き合い方  テストコードの書き方  テスト自動化  デモ  レガシーシステムとテストコード
  3. 3. はじめに テストコードを書いたことがない人向けに、 テストコードを書くと何が良いのかデモを交えて 紹介します。 ※デモの言語はJavaを使用します。 テストコードを書くだけだと、将来的にゴミ化す る可能性が高いため、書いたテストコードをゴミ にしないように自動テストについても扱います。
  4. 4. はじめに みなさま、テストコードと聞くとどんなイメージ を持ちますか?
  5. 5. はじめに 私は最初、以下のように思いました。  そもそも、どうやって書くの?  テストコードのテストもするの? それって2度手間では・・・  つまり、テストコードを書くと何が嬉しいの?
  6. 6. はじめに 参加いただいた方々の疑問・ネガティブな感情 をクリアにして、 テストコードを書くはじめの一歩を踏み出すきっ かけになる場とするべく、頑張って喋ります。
  7. 7. はじめに ちなみに
  8. 8. はじめに TDDとかBDD信者で はないので、 その辺、勘違いしない ようにお願いします!
  9. 9. テストコードとは
  10. 10. テストコードとは  書いたコードが、開発者目線で思ったとおりに 動いているか検査する  つまり、機能仕様を検査するわけではない  書いたコードの仕様を表す
  11. 11. テストコードとは 書いたプログラムについて、 そのロジックが想定通りの動きをしているか 確認するためのプログラムです。 以下のようなメソッドがあった場合、 public int add(int x, int y) { return x + y ;} addメソッドに「xに1」、「yに2」を渡したら、 戻り値が「3」になっていれば合格! ということを、コードベースで確認します。
  12. 12. テストコードとは また、テストコードは、書いたコードの仕様の側 面も満たします。 テストコードには、開発者が想定しているパター ンのテストが反映されています。 つまり、テストコードとは、開発者が想定してい るメソッドの使われ方を表しています。 このメソッド そんな使われ方、想定してないんですけど・・・ というのを防ぐのにも役立ちます
  13. 13. テストコードのメリット、デメリット
  14. 14. テストコードのメリット、デメリット メリット  中のロジックが変わらなければ、結果は同じに なる(ようにプログラムを書く)  逆に結果が変われば、何か内部的に変わったこ とを気付ける  人が実行して目で確認するよりも、 圧倒的に早く終わって、何よりも正確である リファクタリング しやすくなる
  15. 15. テストコードのメリット、デメリット メリット(応用編)  特定の条件で起こる不具合について、テスト コード上で再現させれば、何度でも瞬時に現象 を確認できる  不具合を対応したら、テストが成功になるため、 実装者レベルでの確認はスグに終わる  他人が作った機能であっても、テストコードが あれば、テストコードを実行することで、どん な機能かが概ね判る
  16. 16. テストコードのメリット、デメリット メリット(余談) OSSのライブラリやフレームワークの選定条件と して、テストコードの有無は、重要な要素になり ます。 なぜかというと、テストコードを実行することで、 どんな機能が提供されているかを簡単に確認でき るためです。
  17. 17. テストコードのメリット、デメリット デメリット  テストコードを書くのは、開発と同じくらい時 間がかかる(経験的に半分~同じくらい)  メンテナンスをし続けないと、ゴミになるため、 お世話が必要 テストコードを書かない勢力には めんどくさ・・・ という心理的な訴えが強力にはたらきやすい
  18. 18. テストコードのメリット、デメリット テストコードは、 以下のようなプロジェクトには向きません  クイック案件  作り切の案件 逆に、以下のようなプロジェクトでは 積極的に採用したいです  細かい仕様がよく変わる  開発終了後に、保守することが決まっている  人の出入りが、結構ある
  19. 19. テストコードとの付き合い方
  20. 20. テストコードとの付き合い方 テストコード書くぞ!! と決めたプロジェクトで失敗する事例(個人編)  量産されるコピペのテストコード  プロダクトコードのテスタビリティが低い (端的に云うと、コーディングセンス×)  1つのテストコードに複数パターンを混ぜ込む  テストコードに実行順序を持たせる テストコードは、プロダクトコードと同じように、 しっかりと設計して書かないと死にます
  21. 21. テストコードとの付き合い方 テストコード書くぞ!! と決めたプロジェクトで失敗する事例(組織編)  C0カバレッジ100%を目指す  テストコード書けば工数が浮くという勘違い  テストコードを書けば品質が担保できるという 勘違い  テストコードのメンテナンスをしない  なんでもかんでもテストコードを書かせる  性能試験などを書いてしまう こういうことをされると、 開発者が死にます
  22. 22. テストコードとの付き合い方 テストコードとの上手な付き合い方(個人編)  共通的に使うものは、テストコード共通みたい な形で、周りに提供する  テストコードをレビューする、してもらう  テスト可能なプロダクトコードを書く ⇒メソッドの戻り値voidは、本来おかしい テストしやすいプロダクトコードを上手く書く ということは、関数型プログラミングを学んでみると 個人的には良いと思います。
  23. 23. テストコードとの付き合い方 テストコードとの上手な付き合い方(組織編)  カバレッジは85%程度を目指させ、カバレッジ の変化に着目するようにする  テストコードはコストがかかることを認識する  新規開発では、テストコードだけに頼らず、打 鍵確認も行う(正常系だけでも良い)  テスト自動化して、テストが失敗したら通知す る仕組みを構築する  テストコードを書くのに、十分な時間を取れな い場合は、対象を重要機能のみに絞る  性能試験は、別フォルダに実装して行う ガチガチにやる必要はない
  24. 24. テストコードの書き方
  25. 25. テストコードの書き方  テスト用のライブラリを必ず使う  テスティングフレームワークを使って、 カバレッジを取得する  モックを上手く利用する  テストコードの実行は一瞬で終わる構成にする
  26. 26. テストコードの書き方 //プロダクトコード public class Calculation { /** 加法を行う */ public static int add(int x, int y) { return x + y; } /** 減法を行う */ public static int sub(int x, int y) { return x - y; } /** 乗法を行う */ public static int multi(int x, int y) { return x * y; } /** 除法を行う */ protected static int div(int x, int y) { if(y == 0) throw new IllegalArgumentException("Please pass a non-zero value to y."); return x / y; } }
  27. 27. テストコードの書き方 //テストコード public class CalculationTest { //例外を検知する @Rule public ExpectedException expect = ExpectedException.none(); @Test public void 加法の確認(){ assertEquals(3, Calculation.add(1, 2)); } @Test public void 減法の確認(){ assertEquals(4, Calculation.sub(6, 2)); } @Test public void 乗法の確認(){ assertEquals(12, Calculation.multi(6, 2)); } @Test public void 徐法の確認(){ assertEquals(2, Calculation.div(8, 4)); } @Test public void 徐法でゼロ除算させようとした場合に例外が発生することの確認(){ //デバッグすれば判るが、Ruleは毎回インスタンスを作り直すため、変更したら、変更しっぱなしにしておいて問題ない expect.expect(IllegalArgumentException.class); expect.expectMessage("Please pass a non-zero value to y."); assertEquals(2, Calculation.div(8, 0)); } } かなり端折ってますが、 ・メソッド名が項目になる(日本語OK) ・try-catchしなくても、 例外とそのメッセージの検査が可能 ・protectedまでは小細工しないで検査可能
  28. 28. テスト自動化
  29. 29. テスト自動化 先にも出ましたが、テストコードを書く場合は、 以下の理由からテストの自動化は必須です。  テストコードの作りっ放しは、将来的にテスト コードがエラーとなる ⇒テストコードのゴミ化を招く 折角書いたテストコードを ゴミ化しないために、テスト自動化をします。 これは必須です。
  30. 30. テスト自動化 必要なもの  CIを支援するツール オンプレの場合: Jenkins一択 ※弊社標準もJenkins クラウドサービスの場合: 選択肢は色々あるけど、プライベートリポジトリは大体有料 例外として、werckerは無料で作り放題(多分今だけだけど) でも、Java使えない CI何ぞやは、以下を読んでください。判らないことは聞いてください [DevOpsを支える技術勉強会(CI編)] http://www.slideshare.net/sh-ogawa/dev-opsci
  31. 31. テスト自動化 Jenkins 画面からテコテコ設定を入れても良いんだけど、、 世間だともうそういう段階ではないので、、
  32. 32. テスト自動化 Jenkins(Blue Ocean)
  33. 33. テスト自動化 Jenkins(Blue Ocean Pipeline) こんな感じで、何がどこまで正常に動いたかを見れちゃいます
  34. 34. テスト自動化 ソースはこんな感じで、Groovyで書きます node { stage('update') { git([url: 'https://github.com/sh-ogawa/auto-test- demo.git', branch: 'sonar']) } stage('test') { bat 'mvn clean jacoco:prepare-agent test jacoco:report -e | echo "ignore failure"' } stage('analyze') { bat 'mvn sonar:sonar -e' } } ソースの更新 テストコードの 実行&カバレッジ取得 テスト結果の解析
  35. 35. テスト自動化 余談ですが、Pipelineスクリプトを書く理由は、  画面からCIで回すシナリオを変えた場合に、何 を変えられたのか判らない  GUIベースは便利だが、職人技になりがち  シナリオをソースで残しておけば、何を変更さ れたか判るし、ソースを見れば何しているか判 る  Gitのホスティングサービス(GitBucketとか GitHub)を使っていればP-Rでレビューして、 OK -> マージという戦略が取れるため、属人化 しづらい
  36. 36. デモ
  37. 37. デモ 個人で行う場合は、IDEでテストした いコードを実行できる。 成功すると緑になる。 ※失敗は赤くなる
  38. 38. デモ 自動化構成 push hook pull build and test analyze save Analyze result 結果の閲覧
  39. 39. デモ SonarQube(テスト、解析結果)
  40. 40. レガシーシステムとテストコード
  41. 41. レガシーシステムとテストコード 最後に、テストコードがないシステムはどうやっ て書けば良い?について レガシーシステムでテストコードを書くには、  今動くものを絶対の正とする  テストを頑張って書き過ぎない ということを念頭において、テストコードを書く 仕様化テストを実施しましょう!
  42. 42. レガシーシステムとテストコード 仕様化テストの書き方  テストコードから対象のメソッドを呼ぶ インプットは実体に合わせるのが良い (実際の画面などを動かして、 入っているObjectを保存するとかいう 荒業を使ってもOK)  戻り値や、IN/OUT兼用パラメータに何が入っ ているかを見ながら、assertを書けば良い  カバレッジは上がらないはずなので、 半日~1日で上げられるところまでを対応して、 見切りをつける(これやらないと泥沼化します)
  43. 43. レガシーシステムとテストコード このようにして仕様化テストを作っておくことで、 将来、以下のようなイベントが発生した場合、 楽になります。  システム老朽化によるリプレース  フレームワークを載せ替えたい  言語のバージョンを上げたい  リファクタリングして、ソースを綺麗にしたい etc..
  44. 44. 質疑応答
  45. 45. ご静聴ありがとうございました

×