イベント概要
https://distributed-agile-team.connpass.com/event/202637/
以下、イベントページから引用。
1990年代に広まりはじめたTDD。その中でも、受け入れテスト駆動開発(ATDD)をキーワードに捉えなおしてみるとおもしろいのではないのかということで、東口さん(@hgsgtk)ときょんさん(@kyon_mm)が、ATDD を中心に雑談してみようというイベントです。
発端は東口さんがATDDを実践しはじめており、そこで システムテスト自動化カンファレンス 2013 のツイート群からきょんさんのATDDのプレゼンをしったところになります。
TDD、アジャイル、クリストファーアレグザンダー、15の幾何学的特性、自動テスト、オブジェクト指向などがキーワードになります。
東口さんがATDDに興味を持つようになったきっかけ
- アジャイル開発を進める中で、イテレーションごとの外部品質に課題感を感じた。外部品質の向上をソフトウェアテスティングの側面から考えた結果、GOOS(実践テスト駆動開発)のATDDが思い出されたので、興味を持つようになった。
- 目的感を持って取り組む重要性を考えると、2~3年前にATDDの存在を知った時に取り組まなくて良かったとふりかえっている。
2013年, 2014年のATDDに対する温度感
- 自動テストの誤解とアンチパターン : https://www.slideshare.net/KyonMm/in-tech-talk の発表を2013年, 2014年にきょんさんはしていた。
- RSpec, Spock, JavaScriptなどのテスティングフレームワークがもてはやされた。テストを如何に綺麗に書くか、のムーブメントが起きていた。BDDのスタイルが取られることで、ATDDのスタイルに近づいていった。
- アジャイル開発が浸透していく中で、ハイクオリティーにするために自動テストの範囲を広げよう、自動テストをTDDでやろう、という話が出てきた。
- GOOSで言われているようなテストダブルを使ったテスト駆動開発というよりは、ハイレイヤーな部分でテスト駆動開発ができないか、という話が出てきた。
- JUnit4で止まっていたので、RSpec, Spock, JavaScriptなどのテスティングフレームワークが台頭するというツールのムーブメントも出てきていた。
- 一方できょんさんは、フレームワーク(パラメータがめちゃくちゃ多い)を開発する過程で、GOOSの定義にあるような元来のATDDを使っていた。バージョンアップが激しいIDEに対応するために、IDEを自動起動するコード等の自動テストを最初に書いて開発を進める、みたいなことをやっていた。
ATDD by exampleについて
- ATDDについてある程度知識があったきょんさんからすると、正直今一つな本だと当時は思った。
- テストのレベルを上げただけ、という印象
- 読んでも読んでもWebで言われていることが非体系的に書かれているだけ
- ATDDを30分とかで説明できない人が読むのはいいと思う
- 本書だけでATDD理解できるかというと、それはない
- ATDDとして例がチープ(ソリューションドメインとアプリケーションドメインが1対1だった)
- 東口さん的には、信号機の例がどういうことだろう?と思った。外部向けにATDDの資料として信号機の例を出すことは厳しいな、という感想だった。
TDDの事前設計をきょんさんが考えた文脈
- 「何をすることでTDDしているのか」ということをはっきりとさせようとした際に出てきた話
- Red->Green->Refactoringをしているかどうか?
- 事前設計をしているかどうか?
- 60秒以内に、Red->Green->Refactoringをしているかどうか?
- 事前設計とは、プロダクトの事前設計(ドメインモデリングなど)のイメージだった。
- TDDでは、TODOリストを作ることが一般的だが、この時にプロダクトコードの設計がノーイメージの状態でやらないよね?と思っていた(大体どういう構造にしていくかの妄想はあるはず)
- インタフェースの存在
- クラス名
- メソッド名
- ATDDという文脈だと、テストクラス名、テストメソッド名等も事前設計にあたる。
- プロダクトコードに限らず、テストコード側にも同じことが言える
- TDDの自殺 : https://www.slideshare.net/KyonMm/tdd-tddexchangeにおける、「テストコードこそがアプリケーションドメインなのではないか?」という話にあるように、テストコードとして何を表現しようとしているのかを、テストコードを書く時点で考えている。
- どんなテストコードを書こうとしているの?というのを事前に考えている。
- クラスを使うデベロッパーやエンドユーザーのドメインがテストコードには表現されるが、これはどこまで事前に考えているのか、という話を考えたかった。
良いBDDのメタファーについて
- @ITできょんさんがしていた話 https://www.atmarkit.co.jp/ait/articles/1404/30/news022.html
- 自分にとって大切な人物(以下、メアリーという人物を例に挙げる)を実装しようとした時、恋人を説明するように説明的にテストを書くと、ふるまいにフォーカスしやすくなるよね、という話。
- メアリーは手を振る、メアリーは歩く...はふるまいを充分に表せていない。
- メアリーはこんな時によく笑って、その時はこういうコンテキストがあって...と書くことでふるまいを表せる
ATDDとBDDとTDDの違いについて
- きょんさん的には、違いはあまりないように感じる(ブロッコリーさんも同意見でした)
- ATDDは、プロダクトを提供する相手へのアクセプタンステストであるか、という意味
- BDDは、TDDに対するカウンターカルチャーが出発点。BDDはTDDと実質的な違いはない。TDDとBDDだと、BDDの方がフォーカスしたい対象がはっきりとしている違いはある。ただし、TDDはレイヤーを限定して話をしていないので、厳密にはそこまで違いはない。
- 分類した言い方を意図的にすると違いが出てくるかな、という話。狭義のBDD/TDDはユニットテスト向けだが、ATDDはアクセプタンス寄りになる、位の違いだときょんさんは考えている。
- フィットがATDDのルーツになっているので、ルーツとしてはBDDとATDDは違うというのはある。
きょんさんは、最近NOOをシステムにどう生かしていこうとしているのか
- NOO : https://www.amazon.co.jp/-/en/dp/4306045935
- システムが自ら変容していく(システムアーキテクチャがシステムを生成していく)ようなシステムが大切。
- 例えば開発者がPRを送りにくいシステムは変容していきにくい。美しすぎるシステムもPRを送るハードルが上がるし、汚いシステムも愛着が持てず、PRは送りにくい。
- 開発者に限らず、システムに係る全ての人がシステムを変化させて生きた、と思うような生き生きとしたシステムを作っていくことが大切だと思っている。
QA
t_wadaさんが訳したテスト駆動開発ではTDD->ATDD->BDDという順に言葉が生まれ、BDD=TDD(内側のループ, 内部品質)+ATDD(外側のループ, 外部品質)という理解をしているが、この見解はどう思うか?
狭義に分ければこの解釈になると思う。
TDDのやり始めとして研修だけではなく伴走してくれるコーチは必要か?
現場による。
チームでTDDをやってみようという話になった時、過半数位の人が「いいからTDDやってみよう」となったら、研修だけでいい。
チームの中に一人しか「いいからTDDやってみよう」とならない場合は伴走が必要。また、テクノロジー的にTDDがやりにくいドメインの場合も、伴走が必要。
これはTDDに拠らない話。
何をすることでTDDしたと言える?
- 東口さん的には、Red->GReen->Refactoringを一つの規律として、無意識にふるまえるのであればTDDしているのかな、と思う。
- きょんさん的には、システムが開発しやすいように徐々に成長できているかどうかが重要だと思っている。超個体の文脈だと、頻繁な正のフィードバックループ(ものを作っていく)と緩い負のフィードバックループ(refactoringをすることで一旦手を止める)が回ることで上手く成長していき、一つの生命体になる。
その他あった話
- 2013年頃はきょんさんはアレグザンダーを殆ど意識していなかった。
- きょんさんは、2017年~デンソーと仕事をしていた。(marsの自動運転技術のPOC)この時、アーキテクチャや概念モデルの選定に苦労した。その中でデザインの勉強をしたいと考えて改めて学んだのがアレグザンダーだった。変わらないものを決めて決定を遅延させたい、という課題感を持ったのもこの頃。
- 数理的システム設計 (https://speakerdeck.com/kyonmm/shu-li-de-sisutemushe-ji-bizinesutoji-shu-zhi-yue-wotunagushou-fa-number-ooc-2020-number-ooc-a) は、上記背景があり、NOOを読んでいく中で生み出されたものだった。
- ふりかえりとかは、自然とやろうとするけどTDDは時間がないとやらない(時間があってもやらない)現場が多いような気はする。
- TDDにおいてテスト起点であることに拘らなくてもいい。TDDはループなので、refactoringから始まってもいい。