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.

Springのプログラムモデルと動く仕様~テスト編~

1,757 views

Published on

2018/03/07のJSUGの資料です

Published in: Engineering
  • Be the first to comment

Springのプログラムモデルと動く仕様~テスト編~

  1. 1. JSUG Springのプログラムモデルと動く仕様 ~テスト編~ 株式会社ビッグツリーテクノロジー&コンサルティング SI事業部 アーキテクチャG 寺島 秀樹 #jsug
  2. 2. 2Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. • 設計? • 仕様? • ドキュメント? はじめに 筆者は「設計とは“考えること”であり、アウト プットはその一側面である」と考えている
  3. 3. 3Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 1. 物事をする方法。しかた。やりかた。 「まだほかに仕様があるだろう」 2. 機械類や建築物などの構造や内容。 「仕様の一部を変更する」 仕様とは? https://dictionary.goo.ne.jp/jn/107319/meaning/m0u/ デジタル大辞泉の解説
  4. 4. 4Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 「ユーザの要求を満たすために サービスやシステム、機能などが どのように振る舞うかを 定めたもの」と定義する この場での「仕様」の定義
  5. 5. 5Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 寺島 秀樹(@terahide27) (株)ビッグツリーテクノロジ&コ ンサルティング 所属 SIerを中心に アーキテクト・アジャイルコンサ ルタントとして就業 システムの保守運用から営業支援 まで手広くいろいろやってます CSP/CSPO/CSM TOCfE国際認定ファシリテータ/ アニメ/酒/ラーメン/ 自己紹介
  6. 6. 6Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. • テスト駆動開発の話 • アジャイルの話 • すごい話 今日しない話
  7. 7. 7Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. • 実際の事例 • テストと仕様とプログラムの話 • 現場で試してみようと思ってる話 (ちょっとだけ) 今日する話
  8. 8. 8Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 出来事
  9. 9. 9Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. • 某サービスを運用している現場 • 5週程度のイテレーションでリリースを繰 り返している • 保守を行うチームメンバは12人程度(ほと んどが経験3年目までの若いメンバ) • 自分はインフラのおもりや障害などの調査 を中心にしていて、開発のイテレーション にはあまり関わってなかった 背景
  10. 10. 10Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 「手が足りないからステージング環境 でテストしてください」 「かしこま〜」 ある日
  11. 11. 11Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. テスト仕様書「ユーザの区分がxxで商材のなんたらフラグ となんたらフラグが立っている時になんたら画面でなんた らするとほにゃららがほにゃららで...」 「?」 ユーザの区分がxxなのはわかった。(それ以外のユーザで はどうなるか書いてないけど一旦おいておこう) 「商材のなんたらフラグってどうやって立てるんですか? DB書き換えてええのん?」 「ステージング環境でそんなことしないでください」 「だったらどうやってその状態にするんですか?」(結構 マニアックな機能だった)
  12. 12. 12Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. Untestable Test Case
  13. 13. 13Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. • テストしたい観点は書かれていた • それをテストするための状態にする にはどうすればいいかが書かれてい なかった なにが問題だったか?
  14. 14. 14Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. • 操作やその結果に対してはみなさん よく気づく • その操作を行う事前の条件や状態を 忘れがち • e.g. エアコンの設定温度を20度に すると冷たい風がでる。本当? 事前条件を表す?
  15. 15. 15Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. • given 事前条件・状態 • when 対象に対する操作をした時 • then どうなるか テンプレート [given]の状態で[when]をすると[then] given - when – then
  16. 16. 16Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. まさに仕様
  17. 17. 17Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. この人ご存知? http://www.startrek.com/database_article/spock
  18. 18. 18Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. • JUnitみたいなもん • given - when - then でテストが書ける素晴らし いもの e.g. Spock def test(){ given: "カートにアイテムがある" 商品一覧を開く() カートにいれるby商品ID(1) when: "カートを開く" 商品一覧でカートリンクをクリックする() then: カート画面が表示されている() and: 購入ボタンがクリッカブルである() }
  19. 19. 19Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. プログラマはプログラムを書くのが仕事 我々はプログラマである https://www.lifehacker.jp/2014/12/141210programmer_signs.html
  20. 20. 20Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. プログラムで表現することができれば ドキュメントと違い動かして検証をすることが容易 自動テストを書けば繰り返しの検証もできる 自動テストもまたプログラム 自動テストのプログラムは、もはやテストが目的で はなく、「動く仕様」としての位置づけを求められ る 自動テストは動く仕様である
  21. 21. 21Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 出来事
  22. 22. 22Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. @Test public void test_success1(){…} @Test public void test_success2(){…} 延々と続く・・・ 前みたJUnit
  23. 23. 23Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. @Test public void test(){ load(“xxxData.xls”); actual = sut(); assertWithExcel(actual, “expected.xlsx”); } 前みたJUnit
  24. 24. 24Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 仕様?
  25. 25. 25Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. まずはテストメソッドの名前を given - when - then で書くことをしてみよう JUnitでは? @Test public void カートにアイテムがある状態でカートを開くと購入可能である(){ //given 商品一覧でカートにいれるby商品ID(1); //when 商品一覧でカートリンクをクリックする(); //then カート画面が表示されている(); 購入ボタンがクリッカブルである(); }
  26. 26. 26Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. もう少しUnit Testみたいな例 @Test public void 商品がある状態でカートに追加すると購入可能である(){ //given assertThat(itemService.findAll().size(), graterThan(0)); //when Item item = itemService.findById(1); cartService.add(item); //then assertThat(cartService.isPurchasable(), is(true)); }
  27. 27. 27Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. テストで確認したい部分が仕様レベルの話 それをどう実現するか(指定がないならば)の話は隠蔽しても構わない むしろプログラムレベルの話(前述の例ならばDOMの操作など)は積極 的に隠蔽した方がいい 仕様レベルとそれ以外のレベル @Test public void カートにアイテムがある状態でカートを開くと購入可能である(){ //given // 商品一覧ページを開きIDが商品IDの親のtrタグの中の // classがaddCartのリンクをクリックする(プログラムレベルの話) 商品一覧でカートにいれるby商品ID(1); //when // 「カートを開く」とあるが、開き方の指定はなし(操作レベルの話) 商品一覧でカートリンクをクリックする(); //then カート画面が表示されている(); 購入ボタンがクリッカブルである(); }
  28. 28. 28Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 仕様レベルの話を残しそれ以外は他所に委譲する 結果テストのしやすさにつながってくる e.g. プロダクションコードにおける仕様と構造 public CartService{ //購入可能な状態で購入するとカートからアイテムがなくなり購入処理を行う public void purchase(){ if( ! this.isPurchasable()){ throw new IllegalStateException("is not purchasable"); } List<Item> items = this.findAll(); items.stream() .map(i -> toPurchased(i)) .forEach(p -> purchaseService.purchase(p))); this.deleteAll(items); } ・・・
  29. 29. 29Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. つづき // カートにアイテムがあるならば購買処理の購買可能判定を行う public boolean isPurchasable(){ if( this.findAll().isEmpty() ){ return false; } return purchaseService.isPurchasable(); } public List<Item> findAll(){ return cartRepository.findAll(); } public void deleteAll(List<Item> items){ cartRepository.deleteAll(items); } private PurchasedItem toPurchased(Item item){ //snip 商品の特性によってなにやら難しい処理 }
  30. 30. 30Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. Spring
  31. 31. 31Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. Spring Ecosystem http://springtutorials.com/
  32. 32. 32Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. DI Container
  33. 33. 33Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 自動テストの際にテスト観点以外の依存した部分をMock やStubなどに差し替えることがやりやすくなった • Frameworkなどの親クラスみたいな縛りから解放され た • 依存関係があった場合でも依存性の注入という形で解決 される DI Container がもたらしたもの
  34. 34. 34Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 前述の例 ホワイトボックステスト //購入可能な状態で購入するとカートからアイテムがなくなり購入処理を行う if( ! this.isPurchasable()){ //モックにしてtrue or false を返す throw new IllegalStateException("is not purchasable"); } List<Item> items = this.findAll(); //モックにしてアイテムを2個返す items.stream() .map(i -> toPurchased(i)) // 複雑なことをしていてテストしづらいなら // モックに変えてシンプルにする .forEach(p -> purchaseService.purchase(p))); //モックにして // 2度呼ばれたことを検証する this.deleteAll(items); //モックにして呼ばれたことを検証する
  35. 35. 35Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 状態中心のテスト テストしたい対象の処理前後での状態の変化を検証すること でテストを行う 相互作用中心のテスト テストしたい対象のオブジェクトの相互作用(メッセージの やりとり)を検証することでテストを行う 平たく言うとどのメソッドがどのように何回呼び出されるか 状態中心のテストと相互作用中心のテスト
  36. 36. 36Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 依存部分はモックに変えていくことでテスト観点(仕様)に フォーカスしたテストになる モックに変えた部分はそれぞれ「仕様」があるはずなのでそ れは個別にテストを行う 最終的には依存しないテスト対象はモックに変えずにテスト を行うのでホワイトボックステストとしては充分となる (前述の例だと repository や toPurchased() がその例) 相互作用中心のテスト(私見)
  37. 37. 37Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 前述の例 再掲:ホワイトボックステスト //購入可能な状態で購入するとカートからアイテムがなくなり購入処理を行う if( ! this.isPurchasable()){ //モックにしてtrue or false を返す throw new IllegalStateException("is not purchasable"); } List<Item> items = this.findAll(); //モックにしてアイテムを2個返す items.stream() .map(i -> toPurchased(i)) // 複雑なことをしていてテストしづらいなら // モックに変えてシンプルにする .forEach(p -> purchaseService.purchase(p))); //モックにして // 2度呼ばれたことを検証する this.deleteAll(items); //モックにして呼ばれたことを検証する
  38. 38. 38Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. E2Eのテストやもっと広いシナリオテストのように粒度の 大きい話しから1つのメソッドに対しての粒度の小さい話 しのいずれでも今日の話しは適用できる ただし、仕様の粒度を間違えるとぐちゃぐちゃになるので 要注意(特に粒度の小さい部分) 今日の仕様の話は ・・・
  39. 39. 39Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 粒度の大小に関係なく、テスト対象の使い方をテ ストする (仕様をテストする) 使い方をテストする ・・・
  40. 40. 40Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. e.g. • 北緯なん度、経度なん度の場所に向かい エレベータで何階に行き鍵を取り出しド アを開け靴を脱ぎ冷蔵庫から缶ビールを 取り出してベッドに横になる 粒度の違い
  41. 41. 41Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. • プログラマはプログラム書くときの言葉に慣れすぎてい る • 最初に話したテスト仕様書の話しはすごくビジネスから 遠い用語で書かれていた • 特に粒度の小さいテストの場合は要注意 XXフラグみたいなもの
  42. 42. 42Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. • ビジネスで使っている言葉で表現しましょう • 難しかったらせめて対象となるものの操作方法(画面と か)で表現しましょう • ただ抽象度の低いホワイトボックステストだとこれも難 しい コツ
  43. 43. 43Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 課題と今後
  44. 44. 44Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. テスト仕様書はgiven-when-thenのテストで書くように した 結果 • トータルコストは下がった(手戻りが減った) • プログラマの心理的安全が高まった 課題 • メンバによって理解度のバラツキが大きい • 品質は大差ない • テスト工数があがった 実際にやってみた(自プロジェクト)
  45. 45. 45Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. Sound only 自動テストに対する取り組み
  46. 46. 46Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. テスト仕様としていろいろなところに 散らばった仕様を一元管理してトレー ス可能に 今考えてること
  47. 47. 47Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. • spockを使って自動テストを記載するプロ ジェクトがちらほらと増えてきた • E2Eの自動テストをうまく活用しているプ ロジェクト • 今後は社内外で今日のような話を通して増 やしていく予定 会社としての取り組み
  48. 48. 48Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. まとめ
  49. 49. 49Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. • given - when - then • 仕様はビジネスで使う用語で表わそう • 粒度に気をつけて表わそう • プログラムは構造に気をつけよう • 積極的に自動テストに落とそう まとめ
  50. 50. 50Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. 最後に
  51. 51. 51Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. • ドキュメンテーションや口伝だとうまく伝わらないもの をどう伝えるかは永遠にテーマだと思う • BDD,ATDDのように検証の方向からのアプローチした りDDDのように設計・実装からアプローチしたりいろい ろな方向から取り組んでいくべき課題と捉えている • なにはともあれプログラムはリーダブルであることが 大前提だと自分は思う • アプローチの一環として今までにはないサービスや開発 形態が今後どんどんでてくるだろうからそういう面でも 注目したいと思っている 所感
  52. 52. 52Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. ってことで API編へ
  53. 53. 53Copyright © 2018 Bigtree Technology&Consulting Ltd. All Rights Reserved. の前に 10分休憩

×