Loading...

TDD Boot Camp Sapporo

和田 卓人 (a.k.a id:t-wada or @t_wada)

Press key to advance.

Slides controls, press:

  • and to move around.
  • Ctrl/Command and + or - to zoom in and out if slides don’t fit.
  • T to change the theme.
  • H to toggle syntax highlight.

TDDBCへようこそ

優しくTDDを教えます

TDD Boot Camp 東京

TDD Boot Camp 北陸

TDD Boot Camp 名古屋

自己紹介

自己紹介

  • 名前 : 和田 卓人(わだ たくと)
  • ブログ : id:t-wada
  • メール : takuto.wada@gmail.com
  • Twitter : @t_wada
  • タワーズ・クエスト株式会社 取締役社長

./../../images/TQ_LOGO_SMALL.png

これまで書いたもの

  • WEB+DB PRESS vol.35
  • WEB+DB PRESS vol.37
  • WEB+DB PRESS vol.42
  • WEB+DB PRESS vol.49
  • 『プログラマが知るべき97のこと』

プログラマが知るべき97のこと

gihyo.jpの連載

  • 「動画で解説」和田卓人の"テスト駆動開発"講座
  • http://gihyo.jp/dev/serial/01/tdd
  • 全20回すべて動画付き解説
  • ニコニコ動画でも見れます

./../../images/gihyo-tdd-icon.png

イベントや参加団体等

  • Developers Summit (通称デブサミ)
  • java-ja
  • asakusa.rb
  • xUnit Test Patterns 読書会
  • TDD Boot Camp

普段やっていること

  • 商用 Rails プラグイン(自社製品)の開発
  • コンサルティング
  • TDD の啓蒙
  • Twitter, facebook

よろしくお願いします

プログラマが知るべき97のこと

49/107

97きのこ本でのテスト言及率

  • 45 / 97 (原文)
  • 4 / 10 (日本人寄稿)
(/ 49 107.0)
0.45794392523364486

実に全エッセイの 45.7% がテストに言及している

テストに関連したエッセイ

  • 34.API設計の黄金律
  • 77.偶然の仕様ではなく本物の仕様のためのテストを書く
  • 79.テストのないソフトウェア開発はあり得ない
  • 89.関数の「サイズ」を小さくする
  • 90.コードを見る人のためにテストを書く
  • 96.テストは正確に、具体的に

34.API設計の黄金律

./../../images/044_Michael_Feathers.jpg

「APIを提供するときは、API自身のテストだけでなく、必ずそのAPIを利用するコードのユニットテストも書く」APIの設計者は、これを黄金律にして欲しいと思います。この黄金律を守れば、APIの利用者がユニットテストに際してどのような問題に直面するかを事前に察知できます。

77.偶然の仕様ではなく本物の仕様のためのテストを書く

./../../images/037_Kevlin_Henney.jpg

ソフトウェアをテストする際の典型的な落とし穴は、現状の実装コードのやっていることを、あまりに細部にいたるまで厳密にテストしてしまうことです。

79.テストのないソフトウェア開発はあり得ない

./../../images/048_Neal_Ford.jpg

橋の構造解析に時間がかかるように、テストにもやはり時間がかかります。しかし、どちらも最終的な成果物の質を一定以上に保つためにすることです。ソフトウェアを開発する者にとって、テストをするということは、作るものに責任を持つということなのです。テストをしさえすればそれで十分ということはないですが、まずテストをしないことには話になりません。テストは、ソフトウェア開発の中でも特に難しく、そして重要な部分と言っていいでしょう。

89.関数の「サイズ」を小さくする

./../../images/036_Keith_Braithwaite.jpg

こういう場合は、いくらテストをしたとしても、確かにバグがないという証明はできないでしょう。テストは、持つべき機能を持っていることを確かめるのに役立つだけです。サイズが大きいことは、そういう点で問題だと言えます。

ネイティブ型の代わりに、問題領域固有の型を使うのは、こういう意味でも良いことだと言えるでしょう。問題領域固有の型を使うと、関数のサイズを大幅に小さくすることができます。どういう型を使うのがいいかは、関数を書く前に、問題領域についての知識を基に考えるべきでしょう。確認すべき例の数をどこまで減らせるか考えるのです。

90.コードを見る人のためにテストを書く

./../../images/021_Gerard_Meszaros.jpg

では一体誰のためにテストを書けばいいというのでしょうか。それは、「コードを見る人のため」です。

良いテストは「ドキュメント」のようなはたらきをします。テスト対象となるコードについて知るのに役立つのです。「このコードはどう動くのか」それを教えてくれるのが良いテストです。良いテストの条件を簡単にまとめると次のようになるでしょう。

  • コンテキスト、出発点、満たすべき事前条件がわかる。
  • ソフトウェアがどのように起動されるかがわかる。
  • 期待される結果と、確認すべき事後条件がわかる。

96.テストは正確に、具体的に

./../../images/037_Kevlin_Henney.jpg

良いテストというのは、まず読みやすく、理解しやすいものである必要があります。かつシンプルで、正しいか間違っているかが即わかるものでなくてはなりません。

テストコードが複雑になると、誤りも起きやすくなります。複雑にならないようにするには、具体的な例を使うという方法が有効です。

05.美はシンプルさに宿る

./../../images/033_Jrn_lmheim.jpg

美しいコードとは、突き詰めれば、シンプルなコードのことです。システムを構成する各部分がすべてシンプルで、個々の部分が担う責務も最小限に抑えられていて、部分どうしの関連もシンプル、そんなコードです。シンプルできれいなコードになっていればテストもしやすく、開発速度を落とさずに長期間にわたる保守が可能になります。

53.正しい使い方を簡単に、誤った使い方を困難に

./../../images/063_Scott_Meyers.jpg

簡単に正しく使え、ミスをしにくいインタフェースを作るには、「作る前に使ってみる」という方法が有効です。

64.プロのプログラマとは?

./../../images/057_Uncle_Bob.jpg

プロのプログラマは、自分の書いたコードに責任を持ちます。

間違いなく正しく動くと確認できるまではリリースをしません。正しく動くかどうか確信のないコードをリリースしてしまう人をプロとは呼べません。 当然のことです。プロのプログラマは品質保証(QA)チームに問題を見つけてもらおうとは考えません。 徹底的にテストをし、「絶対にもう問題など見つかるはずはない」と思えるまで、コードをQAには回さない のです。 もちろん人間のすることなので、それでもQAでは何か問題が見つかることになりますが、それは仕方のないことです。重要なのは、何も問題が見つからないよう努力する姿勢です。まさにそれがプロの姿勢なのです。

j07.不具合にテストを書いて立ち向かう

./../../images/twada.jpg

私はテスト駆動開発を数年間実践してくる中で、心がけているひとつの「掟」があります。それは、「不具合の修正時には必ず先に不具合を再現する自動テストを書いてから修正する」というものです。

  1. 手元で不具合を再現させる
  2. コードを注意深く調べ、不具合を発生させている最小の部分を絞り込む
  3. 最小レベルで不具合を再現させ、不具合が修正されたら通るような自動テストコードを書く
  4. 書いたテストコードを実行し、落ちることを確認する
  5. 不具合を修正する
  6. 書いたテストコードが通ることを確認する
  7. 全てのテストを実行し、不具合修正が他の部分を壊していないことを確認する

ひたすら引用してみると

01.分別のある行動

技術的負債は、その名のとおり、借金のようなものです。短期的には利益になりますが、完済するまで利息を払い続けなくてはなりません。早くできるからと手を抜いてコードを書くと、機能追加やコードのリファクタリングが難しくなります。新たな不具合を生む温床となり、テストケースの価値を損なう原因にもなります。

02.関数型プログラミングを学ぶことの重要性

しかし、適切なテスト駆動設計をすれば、特に「オブジェクトではなく、ロールのモックを作成すること(http://www.jmock.org/oopsla2004.pdf)」を心がけるようにすれば、不要な可変性は、設計から排除できるでしょう。

04.コーディング規約を自動化する

テストカバレッジを計測するだけでなく、計測結果のチェックも自動的に行われるようにする。テストカバレッジが低すぎる場合も、やはりビルドを中止する。

05.美はシンプルさに宿る

美しいコードとは、突き詰めれば、シンプルなコードのことです。システムを構成する各部分がすべてシンプルで、個々の部分が担う責務も最小限に抑えられていて、部分どうしの関連もシンプル、そんなコードです。シンプルできれいなコードになっていればテストもしやすく、開発速度を落とさずに長期間にわたる保守が可能になります。

06.リファクタリングの際に注意すべきこと

一度に大幅な変更を加えるよりも、少しずつの変更(インクリメンタルな変更)を数多くするべきです。インクリメンタルな変更ならば、テストからのフィードバックを得ることで、変更がシステムへ及ぼす影響を容易に知ることができます。変更を加えたらテストが百個以上も失敗する、というのは非常に辛いものです。いらだちと焦りから、誤った意思決定をしてしまう恐れもあります。失敗するテストが2つや3つならば、冷静に確実な対処ができるでしょう。

09.他人よりまず自分を疑う

マルチスレッドがらみの問題も厄介なバグの原因になりやすく、マシンの前で叫び声をあげたまま白髪になりかねません。「コードはできるだけシンプルにすべき」と常に言われますが、マルチスレッド環境においてこの言葉は何倍も重要です。スレッド間の整合性に関わるバグを、一般的なデバッグ作業や単体テストで見つけ出すことは困難です。設計をシンプルにするということが何より大切になるのです。

12.コードは設計である

建設の世界では「模型」を作りますが、これはソフトウェア開発における「自動テスト」にあたると考えます。多数の過酷なテストに耐えるものであると証明されない限り、設計が完了したとはみなさないようにするのです。テストをより有効なものにするためには、大規模システムの巨大な状態空間に圧倒されないような方法を考える必要がありますが、言語や設計手法の改善を図れば、きっと希望が見えてくるでしょう。決して忘れてはならないのは、優れた設計には優れた設計のできる「人間」が要る、ということです。

20.すばやくデプロイ、こまめにデプロイ

早い段階からプロセスのテストやリファクタリングに取り組み、プロジェクトの進行と連動して作業を進めていくべきです。私たちプログラマはコードのテストとリファクタリングを常に行いますが、インストールやデプロイのプロセス自体もその例外ではないのです。

24.変更を恐れない

改良はゆっくり少しずつ加えていき、改良の都度テストをします。一度に大幅な変更を加えるのは危険です。それが元で大変な問題が起きてしまい、結局、せっかく途中まで進めた改良を全部やめてしまおうということになりやすいからです。

25.見られて恥ずかしいデータは使わないこと

要するには、コードに何かテキストを入力する時は——コメントであれ、あるいはログ、ダイアログ、テストデータであれ——常に「これがもし公になったとして問題にならないか」と自問せよ、ということです。そうすれば、突然、卑猥な言葉が大写しになり、その場にいる全員が赤面するというような事態は防げます。

29.DRY原則

テストは同じ作業の繰り返しになることが多いですが、手作業でそれをやっていては手間も時間もかかり、しかも誤りも起きやすくなります。したがって、可能な限り、テストは自動化すべきなのです。

30.そのコードに触れてはならない!

 Webシステム開発プロジェクトの環境は、次のようにアーキテクチャ分割されているのが普通です。

  • 開発者のマシン上の、ローカル開発/単体テスト環境
  • 統合テストを手動、あるいは自動で行う開発サーバ
  • 品質保証(QA)チームや顧客が受け入れテストを行うステージングサーバ
  • 本番環境

33.オープンソースプロジェクトで夢を実現する

プロジェクトにテストコードを書くことで貢献を始めるという方法もあります。テストコードを書くというと、あまり楽しそうには思えないかもしれません。しかし実際は、他人の作ったソフトウェアについて学ぶのに、テストコードを書くほど効果的な方法は無いのです。

34.API設計の黄金律

「APIを提供するときは、API自身のテストだけでなく、必ずそのAPIを利用するコードのユニットテストも書く」APIの設計者は、これを黄金律にして欲しいと思います。この黄金律を守れば、APIの利用者がユニットテストに際してどのような問題に直面するかを事前に察知できます。

38.余分なコードは決して書かない

この時は、不要と思われるコードを削ることで、実行速度を上げることに成功しました。余分な機能をなくすことで、コードベース全体の「エントロピー」を下げた、と言うこともできます。作業の間に何も壊していないことは、ユニットテストが教えてくれました。

42.コマンドラインツールを使う

スクリプトを書けるのもコマンドラインツールの強みです。スクリプト化することでツールによる作業を簡単に自動化できます。たとえば、1日1回決まった時間にビルドを実行する、1つのプロジェクトのバージョンを複数作る、テストスイートを実行する、といった作業を簡単に自動化できるのです。

51.プロジェクト自身にしゃべらせる

現在のソフトウェア開発プロジェクトの多くには、バージョン管理システムが導入されています。そしてバージョン管理システムの多くは、自動テストでコードの妥当性を定期的に確認するCI(Continuous Integration: 継続的結合)サーバに接続されています。素晴らしいことです。

通知の手段が問題です。手段としては、eメールやインスタントメッセージなどが使えるでしょう。たとえば、テストカバレッジが低下した時や改善した時に、それを即座にメールやメッセージで伝えるようにするのです。しかし、それよりもさらに効果的なのは、XFD(eXtreme Feedback Device)です。

53.正しい使い方を簡単に、誤った使い方を困難に

簡単に正しく使え、ミスをしにくいインタフェースを作るには、「作る前に使ってみる」という方法が有効です。

54.見えないものを見えるように

ユニットテストを書くことによって、対象コードのテストが容易か困難かがはっきりと目に見えるようになります。また、開発中のコードが持つべき特性(「疎結合性」「高凝集性」など)を実際に持っているか否かが明確になります。

ユニットテストを実行すれば、コードの動きが目に見えるようになります。実行した時の品質が自分の期待したとおりになっているかが明らかになります。定められた仕様通りに動くかどうか、エラーや例外などによって暴走しない「堅牢性」を備えているか、といったことが目で確かめられるようになります。

58.テスト担当者はプログラマの友人

会社によってQA(Quality Assurance = 品質保証)と呼ばれたりQC(Quality Control = 品質管理)と呼ばれたりしますが、いずれにしろその仕事を担当している人たちのことを、プログラマの多くは「悩みの種」だと思っています。私の直接知っている範囲でも、テスト担当者たちと敵対的な関係に陥っているプログラマは多くいます。「小うるさい」「完璧主義すぎる」という愚痴もよく聞きます。読者の中にも同じような人は多いのではないでしょうか。

些細な問題を社内で見つけてくれ、顧客の目に触れないようにしてくれるテスト担当者は、プログラマにとって「友人」と言えるのです。なかなか納得はできないかもしれませんが、それは本当です。

60.真実を語るはコードのみ

読んでわかりやすいコードを書くにはどういうことをすればいいでしょうか。まず重要なのは、名前のつけ方です。システムを構成する各部分に、見てすぐに機能がわかるような名前をつけるのです。そのためには、コードの構成を「各部分の機能が非常に明確で、言葉で簡単に説明できる」というものにすべきです。コードをわかりやすくするには、部分同士ができるだけ依存関係を持たないようにすること、直交性(orthogonality)を高めることが大切です。自動テストを書いて「プログラムがどのような挙動をするはずか」を説明し、インタフェースのチェックをするというのも有効な方法です。その他、コードを少しでもシンプルにする方法がわかった時や、現状より少しでも良いソリューションが見つかった時には、即座にリファクタリングをすべきでしょう。可能な限り、プログラムを読みやすく、わかりやすくするのです。

61.ビルドをおろそかにしない

以前はコードのテストというと、品質管理(QA)チームに任せておけばよいものとされていました。しかし今日では「質の高いコードを確実に提供するためには、コーディングとテストを並行して行うべき」という考え方が常識になってきています。それと同じように、ビルドプロセスも、これからは開発チームの仕事と考えるべきではないでしょうか。

62.プリミティブ型よりドメイン固有の型を

この種のアプローチは、静的な型付けの言語でも、動的な型付けの言語でも同様に有効です。両者の違いは、静的な型付けの言語では、コンパイラが型のチェックをしてくれるのに対し、動的な型付けの言語では、単体テストで型のチェックをせざるを得ないということくらいでしょう。ただ、型チェックの手段は違っても、ドメイン固有の型を使う目的や、その使い方は基本的に同じです。

64.プロのプログラマとは?

プロのプログラマは、自分の書いたコードに責任を持ちます。間違いなく正しく動くと確認できるまではリリースをしません。正しく動くかどうか確信のないコードをリリースしてしまう人をプロとは呼べません。当然のことです。プロのプログラマは品質保証(QA)チームに問題を見つけてもらおうとは考えません。徹底的にテストをし、「絶対にもう問題など見つかるはずはない」と思えるまで、コードをQAには回さないのです。もちろん人間のすることなので、それでもQAでは何か問題が見つかることになりますが、それは仕方のないことです。重要なのは、何も問題が見つからないよう努力する姿勢です。まさにそれがプロの姿勢なのです。

65.バージョン管理システムを有効に使う

プロジェクトを構成する要素は、とにかく何でもバージョン管理の対象にすべきでしょう。ソースコードだけでなく、ドキュメントやツール、ビルドスクリプト、テストケース、画像ファイル、ライブラリなど、ありとあらゆるものをバージョン管理の対象とするのです。

66.いったんコンピュータから離れてみる

冗長でわかりにくいコードだと思った人も多いと思います。確かにそのとおりです。私もそう思ったので、改修することにしました。メソッドをリファクタリングし、ユニットテストをいくつか書いて、正しく機能することを確認しました。

69.車輪の再発明の効用

「車輪の再発明」はどうしてそんなに忌み嫌われるのでしょうか。それはまず、新たにコードを書くより、既存のコードを流用する方が安全でコストが少なくて済むからです。既存のコードは、その多くが「正しく動作することを既に確認されたコード」です。厳しいテストによって品質を高められ、製品としても役立ってきた実績のあるコードが多いのです。

70.シングルトンパターンの誘惑に負けない

問題の存在がはっきりするのは、ユニットテストの時です。ユニットテストは疎結合が前提となっていて、また「本物の」実装コードの代わりに、適宜モック(テスト用の偽者)実装に差し替えられることも重要だからです。シングルトンパターンはその妨げになるのです。

ユニットテストは、どのような順序でもテストが実行できるために、互いに独立でなければなりません。そしてどのテストにおいても、実行前には必ず、プログラムを既知の状態に設定できるはずなのです。不変でない状態を伴うシングルトンを導入してしまうと、それが難しくなります。加えて、グローバルにアクセス可能で、かつ永続化された状態があると、コードの推論が困難になります。特に、マルチスレッド環境でそれは顕著です。

75.面倒でも自動化できることは自動化する

テストを自動化すると便利なのは確かです。しかし、なぜテストだけと決める必要があるのでしょうか。同じことの繰り返し、という作業はプロジェクトのあちこちに見つかるはずです。バージョン管理、コンパイル、JARファイルのビルド、ドキュメント生成、デプロイ、レポート生成などはその例でしょう。

76.コード分析ツールを利用する

プログラマの中には、「テストがいかに重要か」を、プログラミングを始めた頃から頭にたたき込まれてきた人が多いでしょう。近年では、単体テストやテスト駆動開発、アジャイル開発などが広く行われるようになり、開発サイクルのあらゆるフェーズでテストを最大限活用するという考え方を受け入れる人も増えました。しかし、テストがいかに重要と言っても、それがコードの品質を高める唯一の方法というわけではありません。他にも方法は数多くあるのです。

コードの品質向上にあたっては、テストだけに頼るのではなく、解析ツールも積極的に利用すべきでしょう。自らツールを作ることにも、恐れることなくぜひ挑戦してみてください。

77.偶然の仕様ではなく本物の仕様のためのテストを書く

ソフトウェアをテストする際の典型的な落とし穴は、現状の実装コードのやっていることを、あまりに細部にいたるまで厳密にテストしてしまうことです。

78.テストは夜間と週末に

罪の意識は感じながらも、テストをすべて実行する前に変更をコミットしたことはありませんか。プログラマがテストスイートを実行したがらないのは、実行にどうしても長い時間がかかるからです。納期が近づき、ゆとりがなくなってくると、人間はどうしても細かいところで手を抜き始めます。大規模なテストスイートを2つ以上のプロファイルに分割する、というのも対策の1つでしょう。重要度の高い方のテストプロファイルを小さくし、短時間で実行できるようにすれば、コミット前に実行しやすくなります。そして、すべてのテストプロファイル(念のため、重要度の高いプロファイルも含めておく)を、夜間に自動的に実行できるようにしておくのです。翌朝には、結果のレポートが見られます。

79.テストのないソフトウェア開発はあり得ない

橋の構造解析に時間がかかるように、テストにもやはり時間がかかります。しかし、どちらも最終的な成果物の質を一定以上に保つためにすることです。ソフトウェアを開発する者にとって、テストをするということは、作るものに責任を持つということなのです。テストをしさえすればそれで十分ということはないですが、まずテストをしないことには話になりません。テストは、ソフトウェア開発の中でも特に難しく、そして重要な部分と言っていいでしょう。

81.エラーがエラーを相殺してしまう

表面上起きている問題は1つなのに、それに関わっているコードは2箇所ある場合、1つ1つ不良を修正していくという方法で対処していくと問題が解決しない恐れがあります。

表面上1つに見える問題が、実は2つのコードの相互作用で生じている、という場合は、このように不良箇所の特定が難しく、袋小路に入ってしまうことが珍しくないのです。実は早い段階で不良箇所を見つけてはいるのですが、2つが同時に関与しているとはなかなか気づきません。

87.プログラマとテスターが協力してできること

テスターは、ソフトウェアを破壊し、プログラマの書いたコードからバグを見つけ出すことだけが自分の仕事である、という考え方をやめるべきです。そしてプログラマは、テスターのことを「自分たちの邪魔をする敵」となどと考えるべきではありません。そういう考えをやめれば、協調できる可能性が高まります。プログラマが、品質向上も自分の仕事の一部であると考え、テストしやすいコードを書くことも当然の責務であると考えるようになれば、回帰テストの自動化をテスターと共同で進めることなども簡単にできるようになるでしょう。プログラマとテスターのチームワークで、プロジェクトはまるで奇跡のようにうまくいくはずです。

88.コードは生涯サポートするつもりで書く

いつも「このコードは生涯、自分がサポートし続けなくてはならない」と思ってコードを書く。ということです。それだけで、「良い製品を作らねば」という気になります。「生涯サポートしなくてはならない」と考えながら仕事をするようになれば、素晴らしいことが起きるでしょう。

コメントもまめに書くようになり、テストも逐一実施するようになります。リファクタリングも頻繁に行うようになるでしょう。自分の書いたすべてのコードを生涯サポートするというのは、サポートするコードが時間が経つほど増えていくということを意味します。つまり、知識と知力、そして技術力を磨き、仕事の効率も上げていかないと対応しきれなくなってしまうことは明らかだということです。

89.関数の「サイズ」を小さくする

こういう場合は、いくらテストをしたとしても、確かにバグがないという証明はできないでしょう。テストは、持つべき機能を持っていることを確かめるのに役立つだけです。サイズが大きいことは、そういう点で問題だと言えます。

ネイティブ型の代わりに、問題領域固有の型を使うのは、こういう意味でも良いことだと言えるでしょう。問題領域固有の型を使うと、関数のサイズを大幅に小さくすることができます。どういう型を使うのがいいかは、関数を書く前に、問題領域についての知識を基に考えるべきでしょう。確認すべき例の数をどこまで減らせるか考えるのです。

90.コードを見る人のためにテストを書く

では一体誰のためにテストを書けばいいというのでしょうか。それは、「コードを見る人のため」です。

良いテストは「ドキュメント」のようなはたらきをします。テスト対象となるコードについて知るのに役立つのです。「このコードはどう動くのか」それを教えてくれるのが良いテストです。良いテストの条件を簡単にまとめると次のようになるでしょう。

  • コンテキスト、出発点、満たすべき事前条件がわかる。
  • ソフトウェアがどのように起動されるかがわかる。
  • 期待される結果と、確認すべき事後条件がわかる。

91.良いプログラマになるには

どんな場合でも、「とりあえず動く」というだけのコードは決して書かない。誰が見ても間違いなく正しいとわかる、美しいコードを書くよう常に心がける(コードの正しさを確実に証明できるテストも書く)。

96.テストは正確に、具体的に

良いテストというのは、まず読みやすく、理解しやすいものである必要があります。かつシンプルで、正しいか間違っているかが即わかるものでなくてはなりません。

テストコードが複雑になると、誤りも起きやすくなります。複雑にならないようにするには、具体的な例を使うという方法が有効です。

97.ステートに注目する

コードを書くときには、テスト駆動開発で個々の操作に適合するステート、適合しないステート、ステート間の遷移の適切さを確かめながら開発し、実行時に常にステートが正しく保たれるようにしましょう。

j03.ルーチンワークをフローのきっかけに 宮川達彦

2年ほど前の話ですが、私の参加するプロジェクトでは、常時2本以上の開発ブランチが走り、また2週間に一度はそれをマージしてプロダクション環境にリリースする、という開発形態をとっていました。それぞれのブランチで複数人が日々多数のコミットを行っており、2週間に1度だけのマージでは発生するコンフリクトの数が多すぎるという問題がありました。そこで、次回リリース用のブランチを用意し、開発ブランチから毎日マージすることで、コンフリクトの影響を最小にし、また継続インテグレーションによるテストを容易にしよう、ということになりました。

j04.プログラマが持つべき3つのスキル 吉岡弘隆

プログラマが持っておくべきスキルというのはいろいろありますが、あえて3つあげるとすれば、(1)コードを読むスキル、(2)テストをするスキル、(3)デバッグをするスキル、だと考えます。

j05.快適な環境を追求する 舘野祐一

たとえばテストを実行することを考えてみましょう。あなたのプロジェクトはすべてのテストを実行するのに20分かかります。あなたはこの時間を何に使いますか?同僚とチャットする・トイレに行く・ドキュメントを読む、ということはできますが結局は20分の待ち時間が発生します。しかしながらテスト自体をより高速に実行させる手法を調べて、並列にテストを実行できる環境を整えて待ち時間が半分になったとすると、残り半分の10分の時間をより有効に使えるでしょう。

j07.不具合にテストを書いて立ち向かう

私はテスト駆動開発を数年間実践してくる中で、心がけているひとつの「掟」があります。それは、「不具合の修正時には必ず先に不具合を再現する自動テストを書いてから修正する」というものです。これはもちろん私の発案ではなく、XP(eXtreme Programming)やTDDの先達から学び、それを実践するうちに私にも身についてきたものです。不具合修正時のテストは、次のような手順で行います。

  1. 手元で不具合を再現させる
  2. コードを注意深く調べ、不具合を発生させている最小の部分を絞り込む
  3. 最小レベルで不具合を再現させ、不具合が修正されたら通るような自動テストコードを書く
  4. 書いたテストコードを実行し、落ちることを確認する
  5. 不具合を修正する
  6. 書いたテストコードが通ることを確認する
  7. 全てのテストを実行し、不具合修正が他の部分を壊していないことを確認する

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

レガシーコード改善デモ

「66.いったんコンピュータから離れてみる」を参考に

try {
    Integer.parseInt(time.substring(0, 2));
} catch (Exception x) {
    return false;
}
if (Integer.parseInt(time.substring(0, 2)) > 12) {
    return false;
}

if (!time.substring(9, 11).equals("AM") &
    !time.substring(9, 11).equals("PM")) {
    return false;
}
public static boolean validateTime(String time) {
    return time.matches("(0[1-9]|1[0-2]):[0-5][0-9]:[0-5][0-9] ([AP]M)");
}

Fowler は JUnit をこう評した

"Never in the field of software development was so much owed by so many to so few lines of code."

「ソフトウェア工学の記録の中で、これほど多くの恩恵を、これほど多くの人が、これほど少ないコードに対して、受けていることはない」

ドメインのデータ型へのリファクタリング

  • 28 時などの表現を可能にする
  • ドメインクラスを作る
  • ドメイン型どうしの加減算
  • 現在時刻から作る
  • 現在時刻から作る + 28 時などの表現

今回のお題

package tddbc;

public class TimeValidator {
    public static boolean validateTime(String time) {
        try {
            Integer.parseInt(time.substring(0, 2));
        } catch (Exception x) {
            return false;
        }
        if (Integer.parseInt(time.substring(0, 2)) > 12) {
            return false;
        }

        try {
            Integer.parseInt(time.substring(3, 5));
        } catch (Exception x) {
            return false;
        }
        if (Integer.parseInt(time.substring(3, 5)) > 60) {
            return false;
        }

        try {
            Integer.parseInt(time.substring(6, 8));
        } catch (Exception x) {
            return false;
        }
        if (Integer.parseInt(time.substring(6, 8)) > 60) {
            return false;
        }

        if (!time.substring(9, 11).equals("AM") &
            !time.substring(9, 11).equals("PM")) {
            return false;
        }
        
        return true;
    }
    
    public static void main(String[] args) {
        System.out.println(TimeValidator.validateTime(null));
        System.out.println(TimeValidator.validateTime("12:45:28 PM"));
    }
}

テストの文化を探る

feedback

  • プロトタイピング開発との相性はどうか
  • mock の使いどころやバランス
  • 品質指標のようなものはあるか
  • 自分のためのカバレッジと、ひとのためのカバレッジは違う

todo

  • きのこアイコン
  • ロング巻物
  • 四象限モデルを自前で
  • Web Fonts
  • 技術書の「写経」の方法 http://twitter.com/t_wada/status/9000231741
  • QUnit を組み込む
  • Twitter Streaming API と websocket を使う
  • ボトムアッププログラミング, Lisp, Smalltalk
  • Right-BICEP
  • A-TRIP
  • テスト技法ドリル
  • Kent Beck の Stack のやつ
  • Neal Ford の Stack のやつ
  • js test driver
  • きのこ本のテストのこと

テストとその実践、テスター

  • 02.関数型プログラミングを学ぶことの重要性
  • 12.コードは設計である
  • 25.見られて恥ずかしいデータは使わないこと
  • 34.API設計の黄金律
  • 53.正しい使い方を簡単に、誤った使い方を困難に
  • 54.見えないものを見えるように
  • 58.テスト担当者はプログラマの友人
  • 77.偶然の仕様ではなく本物の仕様のためのテストを書く
  • 78.テストは夜間と週末に
  • 79.テストのないソフトウェア開発はあり得ない
  • 87.プログラマとテスターが協力してできること
  • 89.関数の「サイズ」を小さくする
  • 90.コードを見る人のためにテストを書く
  • 96.テストは正確に、具体的に