タグ別アーカイブ: TDD

tdd-in-net-1-638

テスト駆動開発(TDD) in .NET #ngtnet by @masaru_b_cl

はじめに

このエントリは2016/5/7に開催したNiigata.NET 2.0で行ったセッションを再構成したものです。

 

ライセンス

クリエイティブ・コモンズ・ライセンス
この 作品 は クリエイティブ・コモンズ 表示 – 継承 4.0 国際 ライセンスの下に提供されています。

 

Agenda

 

テスト駆動開発(TDD)とは

テスト駆動開発とは、Kent Beck(ケント・ベック)が提唱した開発手法です。彼の著書であり、「原典」とも呼ばれる「テスト駆動開発入門」(http://www.amazon.co.jp/dp/4894717115)(残念ながら絶版。再販望む!)にはこのように書いてあります。

「動作するきれいなコード」、ロン・ジェフリーズのこの簡潔な言葉は、TDD(テスト駆動開発)の目標である。動作するきれいなコードは、あらゆる理由で価値がある。

それでは、どのように「動作するきれいなコード」を目指していくのでしょう?

 

TDDの進み方

まず、「動作するきれいなコード」にたどり着くには2つの道があります。一つはきれいなコードを書きながら動作するように直していくもの。もう一つは動作するコードを書きながらきれいに直していくものです。

(図は日本におけるTDDの第一人者である「和田 卓人(@t_wada)」さんのスライド「TDDのこころ」より拝借しています。)

TDDはこのうち後者の「着実に一歩ずつ進む道」をとります。つまりまず動くようにしてからきれいにしていきます。なぜこの道かというと、何はともあれ「動作」していなければ、製品としての価値はないということが一つです。

他に、この「動かない」→「動く」の線を超えるときに多くの「気づき」が得られるということもあります。フィードバックは早ければ早いほど修正が容易ですので、まずは動くように書き、フィードバックを得て素早く修正していくのがTDDということになります。

 

TDDのサイクル

TDDはこの着実な道を次のようなサイクルで進んでいきます。

  1. 次の目標を考える
  2. その目標を示すテストを書く(テストファースト)
  3. そのテストを実行して失敗させる(Red)
  4. 目的のコードを書く
  5. 2で書いたテストを成功させる(Green)
  6. テストが通るままでリファクタリングを行う(Refactoring)
  7. 1~6を繰り返す

そしてこの手順を小さく回すことで、素早いフィードバックを得ることができます。

これをTDDの界隈では「黄金の回転」と呼んでいます。これはくるくると回りながらどんどんと高みを目指していくイメージから、荒木飛呂彦先生の「スティール・ボール・ラン」に出てくる「黄金の回転」が連想されるため、このように呼ぶようになったそうです。

(スティールボールラン、荒木飛呂彦著より)

 

動作するきれいなコード

では、「動作するきれいなコード」とは何でしょう?それは原典の該当箇所の原文を見ればわかります。

「動作するきれいなコード」は「Clean code that works」であり「Beautiful」ではないのです。つまりは整頓されたコードがきれいなコードであるということになります。

とはいえ、もう少し具体的な指針が欲しいところです。そこで、「きれい」なコードとは何かを知ることのできる書籍をいくつか紹介します。

まずは「リーダブルコード」です。サンプルコードはC#など.NET言語ではありませんが、「リーダブル≒読みやすい」コードを書くためのテクニックに「名前」を付けて完結にまとめているため、最初に読む1冊としては最適です。

次に「リファクタリング」です。コードの挙動を変えずに構成を直す「リファクタリング」のテクニックについて網羅的にまとまっています。「きれいなコード」にどのように直せばよいのかを学ぶのによいでしょう。なお、この本もTDD入門と同じく一度絶版になりましたが、オーム社により再販されています。

これまでの2冊は実際のコードに近い話でしたが、「きれいな」コードは「きれいな」設計から生まれます。そのため、オブジェクト指向プログラミング言語を使ったアプリケーションの「設計」に関する原則を学ぶことも重要です。それを学ぶための書籍を2つ紹介します。

まずは「C#実践開発手法」です。これはその名の通り、C#を使っていわゆる「SOLID原則」と呼ばれるような設計原則を、実際にどのように使えばよいのか実例とともに紹介しています。こういった分野の書籍には「アジャイルソフトウェア開発の奥義」がありましたが、コードがJava(もしくはC++、Smalltalk)だったので、C#でコードが読めるというだけでも本書はありがたいです。もちろん、内容もより新しいものになっています。

そして、オブジェクト指向プログラミング言語の設計原則について学ぶなら「Head First デザインパターン」がおすすめです。本書のタイトルは「デザインパターン」となっていますが、実際はSOLID原則やハリウッド原則といった基本原則を学ぶのに最適な本だと私は思っています。サンプルコードはJavaですが、C#を知っていればそれほど苦も無く翻訳して読めるでしょう。

また、きれいなコードは既存のライブラリ等との統一感も重要です。特に.NET Frameworkは標準ライブラリが巨大なので、勝手なルールでライブラリを作ってしまうと、利用者が混乱してしまいます。

そこで、標準ライブラリの設計ガイドラインを知るために、「.NETのクラスライブラリ設計」も強くお勧めします。この本は単にライブラリ設計のガイドラインが書いてあるだけでなく、過去の失敗についての.NETの中の人の議論が掲載されていることもおすすめポイントの一つです。

 

TDDの目的

さて、こういった書籍などを参考にしつつも「きれいなコード」を目指すことがTDDの目標であることはすでに述べたとおりです。では、目標のさらに先にある「TDDの目的」はなんでしょうか。それは、一言でいうと「健康」です。

TDDはテストを書きますが、それは大きな目的を実現するための手段でしかありません。TDDで目標とするのは「動作するきれいなコード」は、すなわち「変化に対応」しやすいコードであるともいえます。

変化に対応しやすいコードは、言い換えれば不安が少ないコードだともいえます。ユーザーの要望をかなえるためには、コードを変化させなければいけませんが、「動作するきれいなコード」ならば、安心して変更することができます。

そして、この「不安が少ない」状態を一言で表せば、それが「健康」であるということです。

そして、「健康」なコードは不安が少ないため、開発者自身の「健康」にもつながります。一人一人の開発者が健康なら、チーム全体も「健康」であり、ひいては開発、運用している製品、サービスとその開発者、ユーザーなど関係者全員の健康にもつながります。

この大きな目的のために、まずは目標として「動作するきれいなコード」を維持するよう、TDDを行っていきます。

 

.NETにおけるTDD

TDDがどういうものかわかりましたが、.NET開発においてTDDをどのように進めていけばよいのでしょうか?次の4つの項目に焦点を当て、順に説明していきます。

  • テスティングフレームワークおよびサポートツール
  • ソリューション構成
  • テストコード
  • テスト実行

 

テスティングフレームワーク

まずは、.NETで使える主なテスティングフレームワークをいくつか紹介します。

まず最初は「MSTest」です。MSTestはVisual Studioに標準搭載されたテスティングフレームワークで、現在はExpress Editionでも使用できるため、お手軽さはNo.1です。

次は「NUnit」です。JUnitをはじめとした、いわゆるxUnit系列の正統派オープンソーステスティングフレームワークで、MSTestがVSの下位エディションに搭載されるまでは、デファクトスタンダードでした。

最後は「xUnit.net」です。上記2つより新しく、テストコードの書き方等を一から見直したテスティングフレームワークで、MSのASP.NETチームなどでは、最近のオープンソースプロダクトのテストに使用されています。

ではどのテスティングワークを選べばよいのでしょうか?個人的にはMSTestかNUnitをお勧めします。

MSTestは何といってもVSを入れれば入っているというお手軽さが一番で、必要最小限の機能はあるので、入門には最適だといえるでしょう。また、NUnitは歴史があることもあり、Web上の日本語情報も多く、MSTestよりは高機能(パラメタライズド・テストなど)です。

サポートツール

次にサポートツールについて見ていきましょう。まずは「テストアダプター」です。

MSTestは標準でVS上からテストを実行することができますが、その他のテスティングフレームワークは、専用のテストランナーを使う必要がありました。それを改善し、VSからテストを実行できるようにするのが、「テストアダプター」です。

テストアダプターを導入すれば、NUnitやxUnit.netのテストコードも、VS上から実行して結果を確認できるようになります。

また、テストコードの書き味を改善するため、「Chaining Assertion」というライブラリもお勧めです。

Chaining Assertionはテストコードの書き方を、A.Is(B)の形式で書けるようにします。MSTestの他、NUnitやxUnit.netにも対応しています。後で実例を出すときに、Chaining Assertionを使ったコード例を使って説明します。

 

ソリューション構成

次にTDDを行うソリューションの構成を見ていきましょう。.NETでTDDする場合、テスト対象プロジェクトとテストプロジェクトの複数プロジェクト構成にするのが一般的です。

まずテスト対象プロジェクトは*.exe形式の実行ファイルや*.dllのクラスライブラリどちらでも大丈夫です。ただ、クラスライブラリにする方が一般的ではあります。

そして、テストプロジェクトが別になるため、テスト対象の型は原則publicとします。internalな型についても、テスト対象プロジェクトにアセンブリ属性InternalsVisibleToを使い、テストプロジェクトに対してのみ公開することもできます。

次にテストプロジェクトですが、MSTestを使う場合は「単体テストプロジェクト」を選択します。他のOSSテスティングフレームワークを使う場合は、クラスライブラリプロジェクトを作成した後、使用するテスティングフレームワークへの参照を追加します。

 

テストコード

次にテストコードの構成を見てみましょう。今回はMSTest+前述のChaining Assertionを使ったテストコードについて説明します。

まず、MSTestのテストクラスであることを示すため、TestClass属性をクラスに付けます。テストクラスはpublic出なければならないことに注意してください。

次に、実際のテストを行うメソッドにはTestMethod属性を付けます。テストメソッドもpublicとし、戻り値はvoid、引数はなしとします。テストメソッドは必要な数だけ複数個作ってかまいません。テストメソッド内では、実際の値と期待値が等しいことを、Isメソッドを使い検証します。

この他、それぞれのテストメソッドが実行される前に毎回実行したい処理、例えばテスト対象オブジェクトの初期化などは、TestInitialize属性のついた、いわゆるSetUpメソッドに書きます。同様に、テストメソッド実行後に毎回実行したい後処理は、TestCleanup属性のついた、いわゆるTearDownメソッドに書きます。

 

テスト実行

こうして作成したテストコードは、Visual Studio上から実行すると、「テストエクスプローラー」にテストメソッドごとに成功、失敗、そして失敗ならその失敗した箇所の情報が表示されます。

このようにして、VS上でテストを行っていきます。

 

TDDの実例

それでは、実際にTDDを行っている様子の実例を見せましょう。今回はFizzBuzzを題材として使用します。作成したコードは、GitHubにアップしているので、併せて参照してみてください。

 

設計

まず最初に行うのは「設計」です。作成するプログラムの仕様を元に、ざっと設計して必要と思われるタスクをToDoリストとして作成します。最初にこの工程を行うことで、事前の目標付けとともに、仕様であいまいな部分やどのようにテストを行うのかといった不安要素をなるべくなくします。

 

最初のテスト作成

ToDoリストを作成したら、その中から一つ選び最初の「失敗する」テストを作成します。今回は「正の整数の場合、その数値を文字列で返す」を選び、このことをテストするために「引数が1の場合、”1″を返す」ことを確認するテストコードを書きます。

この時、自分が「最初のユーザー」となり、使いやすいAPI設計を考えることが重要です。それには、型名やメソッド名、引数の名前や型、戻り値の型など、様々な観点があります。

今回はまずテスト対象プロジェクトFizzBuzzとテストプロジェクトFizzBuzz.Testを作成し、FizzBuzz.TestプロジェクトにFizzBuzzTest.csを追加してFizzBuzzTestクラスを作成しました。なお、テスティングフレームワークにはMSTestを使い、Chaining AssertionをNuGet経由でインストールしています。

PM> Install-Package ChainingAssertion

(https://github.com/masaru-b-cl/ngtnet2-fizzbuzz/blob/af2891d63f95b2ea60c88e643b335d0ca14159bd/FizzBuzz.Test/FizzBuzzTest.cs)

.NET開発で最初のテストコードを書く時のポイントは以下の通りです。

  • 戻り値の型を明示する
  • 引数の型を明示する
  • 名前付き引数で引数名を明示する

こうしておくことで、次のフェーズを行う際、VSの機能を使ってコードを自動生成できます。

またこの他、テストコードは適宜日本語で書くことで、その意図がわかりやすくなることもあります。特にC#はメソッド名に使える文字が限られているため、日本語の表現力に頼るのは理にかなっています。

 

最初のテスト失敗

テストコードを作成したら、テストを実行して失敗することを確認します。ここではテストの役割のうち「正しく失敗する」ことを確認することが重要です。

なお、「最初の失敗するテスト」の失敗にはコンパイルエラーも含めてよいです。この段階ではFizzBuzzerクラスは無いのでコンパイルエラーになるはずです。

 

仮実装(Fake It)

テストが正常に失敗することを確認したら、いよいよテスト対象コードの実装に入ります。まず最初に行うのは、「仮実装(Fake It)」です。仮実装とは「テストが成功する最速の実装」のことで、リテラル定数を使ってテストが成功するように書いてしまいます。最初に作成したテストコードであれば、戻り値として”1″を返せば、テストが成功するはずです。

一見意味がないようにも見えますが、この手順には失敗しようのない状態で「テストが正しく成功する」ことで、テストの妥当性を担保するという目的があります。もし仮実装でもテストが失敗するようなら、その後本当の実装にしてもテストが成功するわけはないのですから。

VSで仮実装を行う際、まずはテストコードからテスト対象クラスを生成します。コンパイルエラーとなっているFizzBuzzerクラスの箇所でCtrl+.キーを押し、「新しい型の生成…」を選択します。

generate-class

そして、表示された「型の生成」ダイアログにて、「種類」にclass、「場所」にFizzBuzzプロジェクト、そして「ファイル名」に”FizzBuzzer.cs”を指定して「OK」ボタンをクリックします。

generate-class-02

すると指定した通り、FizzBuzzerクラスがFizzBuzzプロジェクトのFizzBuzzer.csファイルに作成されます。

次に、FizzBuzzTest.csに戻り、コンパイルエラーとなっているSayメソッドの生成を行います。Ctrl+.を押し、「メソッド ‘FizzBuzzer.Say’ を生成します」を選択します。

generate-method

すると、未実装のメソッドSayが生成されます。

テストクラスで引数名、型、戻り値の型を明示していたことで、それに合わせたシグネチャでメソッドが生成されます。

最後に、Sayメソッドが1を返すように仮実装すれば終了です。

(https://github.com/masaru-b-cl/ngtnet2-fizzbuzz/blob/b89706c18621ab0302e3fe524539281e0a4cdd39/FizzBuzz/FizzBuzzer.cs)

この時、FizzBuzzTest.csファイルのSayメソッド呼び出しか所でAlt+F12を押すことで、「定義をここに表示」すると便利です。

peek-definition.jpg

 

最初のテストの成功

 

テストを実行し、成功することを確認します。Ctrl+R, Aキーを押すことで、すべてのテストを実行できます。

success-first-test.jpg

無事テストが成功しました。

 

リファクタリング

テストが成功したので、今度はリファクタリングです。テストが成功する状態を保ったまま、コードを整理します。言い換えれば、挙動を変えずに構造を改善するということです。

なお、テストコードを整えるのもリファクタリングの一つです。ここでは、テストコード内で明示した型や引数名を取り除いてみましょう。

(https://github.com/masaru-b-cl/ngtnet2-fizzbuzz/blob/42483eb7eaa217d80440a026572ffd211bb3ddab/FizzBuzz.Test/FizzBuzzTest.cs)

コードを変更したら、テストを実行して成功することを確認しておきましょう。

 

次の失敗するテストを追加する

先に進むため、「小さな一歩」となるような新たなテストを追加します。この時、先ほど仮実装したメソッドにて、同じ仕様を満たすもう一つのテストコードを追加することで、実装1点に対してテスト2点の「三角」で進めることを「三角測量」と呼びます。今回の例でいえば、「正の整数の場合、その整数を文字列にして返す」という仕様に対して、最初に作った1を”1″にして返すテストに加え、2を”2″にして返すかどうかを確認するテストを追加することで、三角測量を行います。

 

(https://github.com/masaru-b-cl/ngtnet2-fizzbuzz/blob/f21f34237754464babe6e6746a7f52df94295f4b/FizzBuzz.Test/FizzBuzzTest.cs)

 

すべてのテストを実行

テストを追加したらすべてのテストを再実行し、追加したテストだけが失敗することを確認します。もしこの時複数のテストが失敗するようであれば、それは良くない設計であることを示す臭いです。「良くない」とは仕様でなく内部実装に対してテストしている、責務分割が不十分で一つの変更があちこちに影響するような作りになっている可能性が高いのです。

failure-second-test

無事2つ目のテストだけが失敗しました。

 

テストが成功するまで修正

あとは、失敗した2つ目のテストについて、テストが成功するまで実装を行います。このとき、仮実装で使用した定数、リテラルを、引数や変数を使うように直します。サンプルでは、Sayメソッドの引数numberを文字列にして返すようにします。

(https://github.com/masaru-b-cl/ngtnet2-fizzbuzz/blob/f21f34237754464babe6e6746a7f52df94295f4b/FizzBuzz/FizzBuzzer.cs)

 

修正後にテストを実行し、2つのテスト両方が成功することを確認します。

success-second-test

 

再びリファクタリング

2つのテストで共通で使っているfizzBuzz変数をフィールドにしてSetUpメソッドで初期化したり、整数が整数の文字列を返すテストは一つあれば十分なので、一方を消したりします。

(https://github.com/masaru-b-cl/ngtnet2-fizzbuzz/blob/f3ffd123918d51a20a2e6cb8b4892097a9adccbe/FizzBuzz.Test/FizzBuzzTest.cs)

テストを実行し、成功することを確認します。

 

ToDoリストを更新する

ここまでで事前に作成したToDoリストの最初の仕様の実装が終わったので、完了したタスクを消してしまいます。

 

次のテストを追加する

今度は別の仕様について実装していこうと思うので、次のテストを作成し、追加します。3の倍数のテストを追加してみます。

(https://github.com/masaru-b-cl/ngtnet2-fizzbuzz/blob/f4b7c5a74d3ccada1787a583b96ab66d613705e4/FizzBuzz.Test/FizzBuzzTest.cs)

 

明白な実装

実装が自明である場合、仮実装をスキップしてしまっても構いません。これを「明白な実装」と呼び、イメージとしては開発スピードアップのため、ギアをあげるイメージです。今回は引数を3で割った余が0の時に”Fizz”を返すよう実装します。

(https://github.com/masaru-b-cl/ngtnet2-fizzbuzz/blob/da6c8c0288634b67789fcfa17965bf4ff761910c/FizzBuzz/FizzBuzzer.cs)

 

以上のような手順を繰り返して、ToDoリストの項目を全部消したら、実装が完了したということになります。

 

TDDの指針

最後に、TDDを行う上でのいくつかの指針を紹介します。

 

いつTDDを行うか

まず、「いつ」TDDを行えばよいのかというと、それは「不安」を感じたとき、ということになります。例えば、ライブラリの使い方に自信がなかったり、第三者の実装が信用できない時など、開発に関連する不安があれば、それをテストで保護してあげるのです。

ただし、今作成しているのが「使い捨て」のコードであれば、TDDを行わない方が良いこともあります。テストコードを作成しても、そのテストが数回しか実行されないようであれば、テストはただのコストでしかありません。

その他、GUIのコードについてはTDDを行いません。GUIの自動化テストを作成するには非常に手間がかかり高コストな作業です。しかし、GUIは一番ユーザーに近いところであることから、変更が頻繁に起こります。そうすると、せっかく作ったテストもすぐに変更しないといけなくなってしまいます。

また、トライ&エラーであれこれ試すような時もTDDは向いていません。ただし、あれこれ試した結果、確定した実装に対してテストを書いても問題ありません。「テストファースト」にはこだわらなくても大丈夫です。

 

どんなテストが良いテスト?

一般的に「良い」とされるテストの特徴に「F.I.R.S.T」と呼ばれるものがあります。

  • Fast(高速)
    テストの実行がすぐ終わること
  • Independent(独立している)
    他のテストへの影響がなく、任意のテストメソッド単体でも実行可能であること
  • Repeatable(繰り返し実行可能)
    何度実行しても同じ結果となること
  • Self-Validationg(手動での検証がない)
    テストコードのみでテストが完結していること。
  • Timely(テストファースト)
    最初にテストを書いていること

これら5つの特徴には優先度があり、特に重要なのはIとR、続いてF、S、Tです。少なくともIとRだけは考慮したテストを書きましょう。

 

どのようにテストを行うか

ToDoリストを元にどのようなテストを行えばよいのかについては、各種のテスト技法を参考としましょう。基本的なテスト技法として、同値クラス、境界値分析くらいは考慮したテストを書きましょう。

 

既存コードがある場合

「テストがないコードはレガシーコードだ!」のキャッチコピーでおなじみの「レガシーコード改善ガイド」を参考に、小さく初めて少しずつ範囲を広げていきましょう。

 

最後に

最後に大事なことですが、TDDはあくまで「センス」ではなく「スキル」です。訓練次第で誰でも習得画家のなものなのです。たまに「テストが書けるようになったらTDDをやってみよう」みたいなことを聞くことがありますが、「できるようになったら始める」というのは永遠に始めることはできません。まずは始めてみて、うまくいかなければ直せばよいのですから。

また、本来はチームを巻き込んだ形TDDができるのが理想ですが、まずはあなた一人でも始めることができます。やってみて、良いものであれば他の人に勧めて、徐々にTDD人口を増やしていきましょう。

そして、TDDによって安心を得て、「健康になりましょう」

 

参考資料

 

Xamarin向けC#+NUnitのスケルトンを作りました #tddbc

TDDBC for C# with NUnit on Xamarin Studio

MSTest用のスケルトンはすでに作ってありましたが、NUnitのスケルトンはまだ作ってなかったので作りました。対象はXamarin Studioです。

MonoDevelopでもたぶん動くんだとは思いますが、環境がないので未検証です。

XamarinでTDDBCに参加される奇特な方は、是非ご利用ください。

Quick Test SwitcherをVS2013に対応させました

Quick Test SwitcherをVS2012に対応させました

に引き続き、VS上でテストコードとプロダクトコードを一発で切り替えたり、テストを簡単に実行したりするVS拡張「Quick Test Switcher」をVS2013にも対応させました。なお、このパッケージもちろんVS2012にも対応します。

GitHubのDownload機能は使えなくなっちゃったので、SkyDriveに置いておきます。

QuickTestSwitcher – SkyDrive

コードは例によってGitHubです。

masaru-b-cl/QuickTestSwitcher

VS2013でも快適なTDDライフを!

#tddbc 長岡 1.0を開催しました – @masaru_b_cl

TDD Boot Camp 長岡 1.0 – TDDBC

TDD Boot Camp(TDDBC) – TDDBC長岡1.0

TDD Boot Camp(TDDBC) – TDDBC長岡1.0/演習

TDD Boot Camp(TDDBC) – TDDBC長岡1.0/KPT

 

5/18(土)に「TDDBC 長岡 1.0」を開催しました。

お集まりいただいた参加者の皆様を始めとして、講師として駆けつけてくださった@t_wada、TAとしてお手伝いいただいた@kenchan@setoazusa@ktz_alias@megascus@a_suenami、並びにスタッフとしてご協力いただいた@civic@dictav@ishiduca@yu_hori@hiro55bs、本当にありがとうございました。

 

TDDBCとしてのふりかえりは、TDDBC Wikiを見てもらうとして、このエントリでは「イベント主催者」としての感想を述べていきたいと思います。

 

  • スタッフの協力もありつつがなく終えることができて非常に良かった
    • イベント主催は、「コンダクター」としての立ち振る舞いが求められると感じた
    • 自分でガンガンやるよりは、タスクの明確化、適度なサイズへの分割、振り分けがメインだった
      • 他の人に委譲可能なタスクを見出すのは難しい
    • 当たり前だが、動かないと先に進まない
      • 動けば付随して何かしらタスクが発生する
      • TDD黄金の回転の、動かない→動くの象限への移動と同じく「気付き」がある
      • イベント発案したら、とにかく動くの大事
      • 必要なタスクが分かれば、人に任せることもできる
  • みんな生き生きとTDD、ペアプロを楽しんでもらえたようで何より
  • 緑川が思いのほか好評で面食らった
  • 地味にうれしかったのが、@t_wadaのサインをもらった人が、非常にうれしそうだったこと

    (きのこ本Tシャツを着て、きのこ本にサインを書く@t_wada)
    • 距離、時間の関係でそういう機会がなかった人に、その機会を提供できた
      • これは事前に想定していなかった
      • イベントを開いた甲斐があるというもの
  • スタッフはNDSで築いたネットワークをフル活用
    • 非開発者含め
    • 助かった反面、参加者として参加して欲しかったというのもある

 

色々とありましたが、まぁ成功と言っていいのではないかと思います。

この調子で、TDDBC 新潟、上越などが開かれるととっても嬉しいですね。もちろん長岡も継続開催の方向で!

 

でも、次は主催は他の人に任せたいなー。キーノートくらいやりますので、誰か燗酒がおいしい季節に企画してくださいw

TDD Boot Camp 長岡 1.0 参加者募集を開始しました #tddbc

TDD Boot Camp 長岡 1.0 – TDDBC

日時
2013/05/18 (土) 10:00 – 17:30

申込期限
2013/05/18 (土) 10:00

参加費

会場払い2,000円

開催場所
まちなかキャンパス長岡 5F交流ルーム
〒940-0062 新潟県長岡市大手通2-6 フェニックス大手イースト4F

参加者
0 / 20人

というわけで、遅くなりましたが参加者募集を開始しました。ふるってご参加ください。

また、TAなどのスタッフも引き続き募集しています。何かしらお手伝いしていただける方は、ご一報願います。

#tddbc Tyokyo 2013-03に参加してきました

3/16(土)に開催されたTDD Boot Camp Tokyo 2013-03 – TDDBCに参加してきましたので、レポートです。

 

ランチミーティング

今回のTDDBCは今年開催予定の福岡、長岡の主催者のサポートという意味合いがありました。そこで、イベント開始前にランチミーティングという形で、TDDBC開催に向けての相談をしてきました。

出席者は今回の主催者である@katzchangをはじめ、@t_wada、横浜の@grimerose、福岡を開催予定の@Spring_MT、そして私といった感じ。内容についてはまたTDDBC-MLTDDBC Wikiで共有しますので、そちらをご覧下さい。

 

キーノート

そして参加者が集まったところで、TDDBC開始です。すっかりおなじみとなったt_wadaのキーノートセッションです。

t_wadaのキーノートはスライドは何度も読んでいましたが、実際に観るのは初めてでした。もちろんスライドには乗っていないことが実際には多く、これはやはりセッションを観ないとわからないことが多いなと感じました。

メモから起こしてみます。

  • TDDBCのメインは、実はTDDではなく「ペアプロ」
    • ペアプロは楽しい、そして疲れるw
  • コードレビューもポイント
    • 普段の仕事では同じ問題を複数人で同時に解くことはまずない。
    • 他の人、言語のコードと比較することができる。
  • ふりかえりもポイント
    • KPT(Keep、Probrem、Try)でふりかえる
  • ソフトウェア開発の三本柱
    • バージョン管理(一番大事!)
    • テスティング
    • 自動化
  • バージョン管理
    • 人間は忘れる
      • いかに記憶を専用ツールに任せるか
    • メンテナンスと新機能の並行開発
      • VCSなしでは困難
        • セーブなしでRPGをやるようなもの
    • Before DVCS時代
      • CVSの貧弱なマージ機能を補完するため、人間が工夫していた
        • 手でブランチ図を描いて、マージポイントなどを管理していた
        • ただ、開発が進むと管理しきれなくなる
  • テスティング(Test-“ing”)
    • 名詞ではなく進行形
      • 書き”ながら”開発を進める
  • 自動化
    • 人間は
      • 飽きる
      • 疲れる
      • 繰り返しが苦手
      • 創造性がある
    • 機械は人間の逆
      • 飽きない
      • 疲れない
      • 繰り返しが得意
      • 指示したことしかできない
    • 機械と人間でコラボレーション
      • お互いの得意なところで、不得意なところを補完する
      • たとえば
        • コミット:人間
        • ビルド:機械
        • レポート:機械
        • 判断:人間
    • 人間→機械より、機械→人間の通知の割合を大きく
      • 人間は非同期に作業するのが得意
      • Jenkinsなどを活用し、機械の割合を増やす
  • 三本柱以外のメタファー
    • 三種の神器
      • レベルを上げて物理で殴れば、なくても何とかなりそう感あり
      • メタファーとしてはやはりどうかと
    • 三脚椅子
      • 今のところ一番しっくり
      • 先日論破された
        • 「足が一本もなければ安定するじゃん」
        • もっとも
  • テスト
    • コンテキストを合わせる
    • だれが何のために行うか
      • 開発者(TDDはこれ)
      • 顧客(ユーザー)
      • 品証(QA)
  • TDDとは
    • 原典(TDD入門)の書き出しがすべて
      • 「動作するきれいなコードを書き続ける」
  • 2つの道
    • きれいだけど動かないコードから動くコードへ
    • 汚いけど動くコードからきれいなコードへ
  • 動かないコード→動くコードに移るときに「気付き」がある
    • TDDは汚いコードでもまず動くようにする
    • この段階を小さく早く繰り返すことで、「気付き」のタイミングが多い
  • Red→Green→Refactoring
    • 黄金の回転
      • JoJo第7部 Steel Ball Runより
  • 汚いコード→きれいなコード
    • 実現するには「強い意志の力」が必要
    • 「汚さ」に敏感になる
    • 「リーダブルコード」がその助けとなる
    • 汚いコードはいずれ自分が嫌いになる
  • TDDのこころ
    • 一つずつ、少しずつ、段を小さく
      • 問題をBreakDownする
    • 複数を相手にしない、一人ずつ対処する
      • 1対1の連続にする
        • 思ったこと:ただ、疲れはする
      • TODOを先にリストアップ
        • やりやすいところから片付ける
    • 素早く回す
      • 回転が遅い、ということは何か問題がある証拠
    • 自分が最初のユーザー
      • 作る→使ってもらう→フィードバックでは遅いし漏れる
      • 作りやすい<->使いやすいのバランスを見極める
        • トレードオフになるものも多い
        • TDDが導く
    • 不安をテストに
    • 祈るのではだめ
      • テスト、VCS、自動化に守られた状態なら、祈る必要はない
    • 命綱を編む
      • 必要になってから編んでも、もう遅い
      • 日々の習慣に組み込むのがTDD
        • 編んだ命綱を自動化で回す
  • TDDの最大のメリット
    • 心理的なもの
  • TDD=バグ0ではない
    • バグをテストで保護して対処
    • バグのたびに強くなる
  • TDDのテストは目的でなく手段
  • TDDの目的は「健康」
    • コードの健康
    • チームの健康
  • TDD導入事例
    • IBM、MSの論文
      • バグは6割から最大9割削減
      • 実装時間は3から3割増
    • エリクソンの論文(アンケート結果の分析)
      • デバッグ時間の減少
      • コードの品質(外部/内部)の上昇
      • 実装時間は増えるが、トータルコストはむしろ減る
        • デバッグ時間の減少が大きい
  • デバッグ時間現象の意味
    • デバッグ→想定外の作業
    • デバッグを減らす→想定外の時間が減る
    • 計画した時間とのブレが少なくなる

 

TDDのペアプロデモ

キーノートセッション後は、@grimrose、@yattomによるペアプロデモです。FizzBuzzを題材にこんな感じでTDDを進めていました。

  1. TODOリストの作成
    インターフェースの検討もここで行っていました。たとえば、引数、戻り値の型、など。また、例外パターンの考慮も行い、「具体的な例外の型」については後回しにすることも決めていました。
    2以降でも途中で出てきた問題、課題は都度TODOリストに追加して忘れないようにする。
  2. 最初のテスト
    数字を入れたら数字を返すテストを作成し、コンパイルが通るようにしてテストが失敗することを確認するまで行いました。
  3. 仮実装
    テストを通す最短のコードを書くことを「仮実装」といい、「テストコードのテスト」の代わりとなるため、省かずに行ったほうがよい。
  4. 三角測量
    最初のテストに加えてもう一つテストケースを追加し、仮実装から本来あるべき実相を導きます。
  5. リファクタリング
    テストが通ったままの状態を維持しつつ、コードを整理します。
  6. 次のテスト
    Buzzを返すケースのテストなどを書いていきます。
  7. 明白な実装
    Buzzを返すケースができていればFizzを返すケースの実装も明白なので、三角測量はせずに一気に加速して実装してしまう。ただし、最小限のテストは書く。

個人的には、テストコードのリファクタリングのところも見たかったなぁ。

また、デモの途中で次のような質問が出ました。

Q:TDDはどのタイミングでコミットすればよいのか?

A:基本はGreenのタイミングで。ただ、GitなどのDVCSならば、Red、Green、Refactoringのそれぞれでコミットすることもある。ただ、この時もPushはGreenのタイミングで。

 

ペアプロ実習

デモが終わったところで部屋を移動し、ペアプロ実習タイムです。ペアの割合はPHP、Ruby、Javaの3強+他言語(C#含む)といった感じでした。

私は@aetos382と組み、VS2012、C#、MSTest with Chaining Assertionで臨みました。

 

お題

少し前にはやった「LTSV」ライブラリを少し改変したもので、@sue445さんがsue445/tddbc_tokyo_20130316 · GitHubにまとめてくれました。オリジナルのLTSVライブラリとの違いは、setterが変更前の値を返すこと、setした順番で中身をダンプすること、あたりです。

 

ペアプロの様子

まずTODOを2人で洗い出し、例外パターンなどの抜けがないかクロスチェックしました。ちょっとここで全部をやろうとしてしまったことは失敗だったかなと思っています。

そして実装開始です。我々はSet→Get→Dumpと進めていくことにしました。途中Setの値置き換えのテストを、Getを作成する前に行おうとしたところ、Getがないとテストできず、道を誤ったので一度戻り、今度はGetを実装する、といった進め方になりました。

また、最初はDictionary<string, string>をデータストアとしていたのですが、setした順序を保持するといった要件を実現するのに、うまくいかず途中でList<Tuple<string, string>>に切り替えることになってしまいました。

 

結果

LINQを活用したり、Chaining-Assertionを活用したりと、C#らしいコードになったこともあり、最後のコードレビューで採り上げられてしまいました。

 

クロージングセッション

最後にt_wadaによるクロージングセッションで、TDDの応用について話がありました。一言でまとめると、レガシーコード改善ガイドなどの本から他の本、他の本とたどり、スキルを高めていってほしい、といった内容でした。

 

まとめ

私の初めてのTDDBC参加は、こんな感じでした。今回の打合せ結果、イベント参加結果をもとに、5/18(土)に予定しているTDDBC長岡1.0に活かしていくつもりです。

あと、「お題」はまた改めてやり直してGitHubにあげてみようと思います。若干不本意な実装で終わってしまったので。

TDD Boot Camp Tyokyo 2013-03 参加します

TDD Boot Camp Tokyo 2013-03 – TDDBC

 

TDD Boot Camp Tokyo 2013-03

TDD Boot Camp Tokyoを、2013年3月16日に開催します!!!!

開催概要

  • 日時 … 2013-03-16(土曜日)
  • 会場 … 東京都渋谷区神泉町8-16 渋谷ファーストプレイス 8F 株式会社 VOYAGE GROUP 社内バー AJITO
  • 定員 … 30名
  • 参加費 … 2,000円
  • Wi-Fi接続環境 … 会場にて提供できます

参加費用については、今後全国で開催を予定しているTDD Boot Campの運営費として使わせて頂きます。ご協力感謝いたします!

 

結構「TDD!TDD!」言ってる上、5月に長岡で主催しようってのに、実はこれまでTDDBCに参加したことがなかったりします。

んで、「主催するけど参加もしたいなー」というような話をしていたら、@katzchangが開いてくれました!

 

 

というわけで、初出陣。当日は「プログラマが知るべき97のこと」を今更持ち出して、@t_wadaにサインもらおうと思います!