Slide 1

Slide 1 text

E2Eテスト駆動開発 実践記 〜真のTDDを目指して〜

Slide 2

Slide 2 text

自己紹介 ● 林 尚之(はやし たかゆき) ● Agile(XP)、TDD、DDDとかが好き ○ 最近はDart(Web)、Kotlin(Server Side)を書くことが多い。ClojureやOCaml勉強中 ● 株式会社ユーザベース ○ SPEEDA日本事業 CTO ● twitter:@t_hyssh

Slide 3

Slide 3 text

約10年くらいE2Eテストを書きつつプロジェクトを進めてきた 中で得られたいろんな事を共有できればと思ってます。

Slide 4

Slide 4 text

10年間大事にしているサイクル 着手するストーリー を決める E2Eテストを書く ユニットテストを書く ユニットテストを通す リファクタリング E2Eテストを通す

Slide 5

Slide 5 text

Java + JUnit + Selenium 2009年〜 Scala + Specs2 + Selenium 2012年〜 Scala + Specs2 + Selenium + Docker 2013年〜 Kotlin + Gauge + Selenide + Docker + kubernetes 2017年〜 個人的10年間の変遷

Slide 6

Slide 6 text

● とある金融系の大規模プロジェクト(期間は 2年ちょっと) ● 最大で50人前後のメンバーで常時ペアプロしながら E2Eも書いていた ● E2E実行用のPCを10台くらい並べて文字通り並列実行 ● それでも全部のケースを実行するのに 10時間くらいかかっていた Java + JUnit + Seleniumの時代 (2009年〜)

Slide 7

Slide 7 text

教訓・感想 ● リリースが終わったらチームは解散し、その後は保守・運用チームがメンテナンス。ただ、その 後E2Eはメンテも実行もされなくなったらしい・・・。「文化」って大事。 ● その一方であれだけの実行時間が掛かってしまっていたり、不安定なテストケースも少なくな かったテストをいきなりメンテしろとか言われても難しい。 ● なのでテスト実行に対する心理的障壁(実行時間、安定性)の大事さを改めて実感しました。 ● テストケースが不安定になってしまう大きな要因として「テストの独立性」が担保できていなかっ た。DBのデータの「独立性」が高くなかったため、タイミングによって落ちたり落ちなかったりと いう問題が出てしまっていた。 ● JUnitオンリーで書いていたので仕様の表現力を上げるのが難しかった。 Java + JUnit + Seleniumの時代 (2009年〜)

Slide 8

Slide 8 text

概要 ● とある金融系のR&Dプロジェクト ● JUnitだと仕様の表現に限界があるため Specs2のUAT記法で記述 ● 仕様としての表現力の大切さを実感 Scala + Specs2 + Seleniumの時代 (2012年〜)

Slide 9

Slide 9 text

教訓・感想 ● ヒアドキュメントで仕様(テスト)を書いた場合の読みやすさ、理解しやすさを 実感。 ● R&DのプロジェクトだったのでE2Eはそんなに書かなかった。 Scala + Specs2 + Seleniumの時代 (2012年〜)

Slide 10

Slide 10 text

仕様書としての表現力(JUnit) ● メソッドの部分に概要しか書けない ● コメントでいろいろ書こうと思えば書けるけど・・・・

Slide 11

Slide 11 text

仕様書としての表現力(Scala + Specs2) ● ヒアドキュメントで記述可能 ● 特に大事なアサーションの部分も仕様としてきちんと 記述が可能に

Slide 12

Slide 12 text

概要 ● 現在所属しているユーザベースでの SPEEDAというサービスにおける1プロ ジェクト ● 再現性を求めてDockerを使いはじめる ○ DB、APサーバー、ElasticSearch等 ● 既存の機能にはE2Eは存在しなかったため、そこに対する E2Eの追加をオフ ショアに出す Scala + Specs2 + Selenium + Dockerの時代 (2013年〜)

Slide 13

Slide 13 text

教訓・感想 ● Dockerによって再現性が格段にアップ ● 画面側はほとんどが参照系なので「テストの独立性」を担保する上でのデー タ作成はそんなに難しくなかった。 ● こちら側の準備不足もあり、オフショアに出した結果は「動かない」 or 「通らな い」テストが大量に納品されて大変でした・・・。既存機能の E2Eをオフショアに 出して失敗した事で、E2Eの難しさ、最初にE2Eを書くことの重要性などを再 認識 Scala + Specs2 + Selenium + Dockerの時代 (2013年〜)

Slide 14

Slide 14 text

概要 ● 現在所属しているユーザベースでの SPEEDAというサービスにおける1プロ ジェクト ● Microservices / Micro frontendsの部分で適用 ● Gaugeを導入する事で「テストとして実行可能な仕様書」を実現が可能に ● kubernetesの導入により開発から運用まで全ての環境を揃える事が可能に Kotlin + Gauge + Selenide + Docker + k8s の時代(2017年〜)

Slide 15

Slide 15 text

教訓・感想 ● 「テストとして実行可能な仕様書」という意味で Gaugeはとても良い ● フルk8s化した事で開発から本番までの環境の差がなくなったのでテストが 落ちた時の問題解決までの時間が大幅に短縮 ● k8sのおかげでMicroservices / Micro frontendsの部分もきちんとテストが 出来ている ● SelenideでSelniumの煩雑さが簡略化された(特にWaitが必要な部分) Kotlin + Gauge + Selenide + Docker + k8s の時代(2017年〜)

Slide 16

Slide 16 text

仕様書としての表現力(Gauge) ● 誰が見ても読める(Markdown) ● IDEの支援も受けれる ● 「テストとして実行可能な仕様書」

Slide 17

Slide 17 text

Microservices Kotlin + Gauge + Selenide + Docker + k8s の時代(2017年〜) 〜教訓・感想とか〜

Slide 18

Slide 18 text

Kotlin + Gauge + Selenide + Docker + k8s の時代(2017年〜) 〜教訓・感想とか〜 Service A Service B Service C BFF Front End サービス毎にE2E作成 他サービスとの連携部分はMock化 サービス単体のE2Eは GETであればJSONを アサーション、POSTの 場合はDB、KVSのア サーション Front EndのE2Eがシステムとして の振る舞い(仕様) ユーザーが直接操作する Front Endの E2Eで関連する全てのサービスを連携さ せる サービス毎にE2E作成 他サービスとの連携部分はMock化

Slide 19

Slide 19 text

10年前に比べたらSelenium(WebDriver)やGaugeなどのテストフレームワーク の進化・登場と、間接的にE2Eに寄与するDocker、Kubernetes等の登場により E2Eテストの難易度はかなり下がってきている印象。ただし、ストレージ周り (RDB、KVS、全文検索エンジン)のE2Eに関する進歩はあまり感じられない。 10年を振り返って①

Slide 20

Slide 20 text

実行速度、再現性、ドキュメントとしての表現力等はツール、フレームワーク、コン テナ、マシン性能等で改善してきたが、テストの独立性はツールや FWなどよりもテ ストを記述する人のスキルに依存しやすい。 10年を振り返って②

Slide 21

Slide 21 text

個人的にペアプロの効果は絶大だと思ってます。 10年を振り返って③

Slide 22

Slide 22 text

E2Eを最初に書く事で仕様がより明確になるし、対象のストーリーのゴールが明確 になる。これはやはり大きい。 10年を振り返って④

Slide 23

Slide 23 text

E2Eテストもユニットテストも同じ「テスト」という点で本質的な部分は同じ なのでは?? 10年を振り返って⑤

Slide 24

Slide 24 text

・次の作業のための受け入れ基準が明確になる。私たちは、どうなったら完了した と言えるのかを自問しなければならないのだ ・テストが、コードが何をするかについての実行可能な説明となる 『実践テスト駆動開発』 Steve Freeman・Nat Pryce, P6 ・テストは、システムドキュメントとして最高の形式だ。というのは、テストほどリリー ス可能なコードの作成に集中させてくれる形式はないからだ。 『XPエクストリーム・プログラミング 適用編』 Ken Auer・Roy Miller, P185 本からの抜粋

Slide 25

Slide 25 text

● テストとして実行可能なドキュメント ● 最初にゴールを定義する事で、作業が明確化する ● デグレの検知 ● フィードバックループ ● より良い設計 TDDで得られる恩恵・価値

Slide 26

Slide 26 text

● テストの独立性 ● 再現性 ● 実行速度 TDDで重要視しなければいけないこと

Slide 27

Slide 27 text

E2Eかユニットテストかは単にスコープが違うだけ

Slide 28

Slide 28 text

良いユニットテストを書ける人は 良いE2Eを書けるし その逆も然り

Slide 29

Slide 29 text

振り返って思うことはそんな当たり前の事でした

Slide 30

Slide 30 text

ご清聴ありがとうございました