msfukuiの日記

おおまさのみみはそらのみみ。

「TDD の導入とエンドツーエンドテスト自動化の実践」というイベントに参加しました。

早く着きすぎて、しまった、と思ったけど、会場に早めに入れていただてよかったです。

以下、自分用のメモ。
()内は話をお聞きしながら考えてたことです。

はじめに(主旨)

永和マネジメントの一谷さんから。
DevLove: 開発現場のためのコミュニティ。
157回目(!)
開発現場のハブになる。
2008/6/21 から活動を開始。
現在のメンバー、doorkeeper の登録者で1,800人。

永和マネジメントの家永さんのお話

コードのシンプルさ:ビジネス上のアジリティの相関関係について
(これは ROI の話と関係しているかも。)
TDD をやることへのモチベート:新人の時からの開発経験で TDD のうれしさを実感。
Turnip, cucumber はビジネスと開発の間のコミュニケーションツール。
家永さんの考える TDD の範囲:頻繁なデモ、Acceptance Testing, Unit Testing を含む。
自動化はフィードバックループを加速させるための手段。

  • 導入ポイント

1: 小さく成功。1,2名で自動化対象を絞って実施。
2: 受け入れテストから始める。
3: スクラム導入→デモから始める。

  • 何故 TDD?

メンテナンス可能なコードを作るため。
読みやすいコードとは?→最終的には人間が判断する。

  • TDD でどんな困りごとを解消したい?

(誰も知らない仕様。誰も知らない機能。ドキュメントと実際のコードの差異。)
泥沼化したコード。
緊急対応・割り込み。
テスト自動化とカバレッジの落とし穴。
目標がカバレッジになっている。
→コードのきれいさ、シンプルさがおざなりに。
→テストが邪魔になる。Green にすることがおざなりに。
客観的なよい指標がなかなか出せないないのも原因の一つなのかも。

  • TDD の目標

開発者は楽しくコードを書ける。
利用者は楽しくサービスを享受できる。

  • 導入のコツ

TDDBC に参加する。→経験者から共有してもらえる。
素振り(写経): railstutorial, TDD 入門など。
(よいかも。みんなやった方がいいのはわかってる。でも何からやるとよいのかわからない。それを解決したい。)

  • 既存システムありきの場合...

新機能は TDD。既存機能のビジネス的に重要な部分を End-End のテストで補強。
中長期的な観点でリファクタリングに取り組む。
リーン開発の現場の本を読もう。
レガシーコード改善ガイドの 24 章を読もう。

  • TDD をどう広めるのか。

アジャイルに効くアイデアを組織に広めるための 48 のパターンを読む。
個人的な接触: 困っているギャップとなる点を個別に引き出す。
普段から常にテストコード、プロダクトコードをきれいに保つことをチームで話し合う。
語彙は xUnit Test Pattern を頼る。
TDD は自動化だけではなく学習フィードバックループを回すことが重要では。
小さな回転を回し続ける様に。
年単位で見据えて導入していく必要がある。

iRubySystems 社の福井さんのお話

Gherkin + Capybara + Turnip の組み合わせの紹介。
テスト自動化ピラミッドの話。
テストのレイヤーの話。
高信頼化ソフトウェアのための開発手法ハンドブック: pdf で公開されている。
(テストの呼び名は混乱してると思った。
回帰テストシステムテスト、受け入れテスト、機能テスト、、、
話をしているテストの種類の軸がそれぞれに違う気がする。)

  • 開発→検証→運用のサイクル。

回帰テストシステムテスト、受け入れテスト、e2e テストは検証(Verification)にあたる。
検証工程はフォーマルなテスト。
e2e のテストの自動化はユニットテストとは質が異なる。
(これはどう異なるのか?ちょっとピンと来なかった。)
(経験上 Gherkin でテストを書くこともビジネスサイドからは難しい。
論理的に抜けがない、矛盾がない形でテストを書く必要があるのは同じだから。
ここが一番ハードルが高いと思っている。
もしそうだとすると、RSpec のみで受け入れテストも書く方が、開発者にとっては楽かも?脳みそ切り替えコストが高いし。)
Geb との比較あるとうれしい。考えてみる。JQuery 互換なところは Geb の方がうれしいかも。ここは Capybara の学習コストにもよるかもしれない。)
(PageObject パターンとの関係も気になる。)

  • 悩み

構成する各要素のバージョンが頻繁に変わるのはちょっと悩み。

  • テストコンテンツをどう管理するか?

無限に増えていく feature ファイルをどう管理するか。
WebDB を使ってシナリオを管理するのがいいのでは?という話。
RtestDeck というツールを作っている。
feature をグループ化できる。
jenkins の job がグループ単位になっていて自動実行をサポートしている。
Google さんの Test Analytics と連携すると面白いかも、と何となく思いました。)

  • RSpec だけでも feature テストはできる。けど...。

発表の後で Gherkin をビジネスサイドで書くことについての難しさについてみなさんはどうクリアされているのか、という質問をさせていただいたのですが、家永さんがおっしゃられていたペアプロという話はいいいなーと思いました。
そもそもビジネスサイドと開発サイドがペアプロできる関係性を築いていくところが本質かなとも思ったり。

ビジネスロジックの論理矛盾をどう事前に検出するか、という話は、以前全く別の講師の方にもお聞きしたことがあったけど、よい解はなかったので、引き続き考えたい..。

よいお話がたくさん聞けて良かった。
何よりとても久しぶりに、外で話を聞いたり少しでも発言できる場に参加できたのがよかった。
ありがとうございました!

会社の PC で 2 時間ほど悶々と悩んでたこと。

Windows7(32bit) + Cygwin(32bit) + ruby 1.9.3p484 + gem 2.2.2 です。

gem がエラーに..。

$ gem install selenium-webdriver test-unit
ERROR: While executing gem ... (ArgumentError)
invalid byte sequence in UTF-8

うーん..。と悩んで以下の記事を読みました。

Cygwin - Ruby-1.9.3p327 - win32/registry - PIB

とても詳しく書かれていてすっきり理解できました!
でも個別パッチになってしまうのですね..。
記事を参考に win32/registry.rb を直接編集して修正するとうまくいきました!

追記(12/29)

毎回編集内容を忘れるのでパッチ内容を追記します。
該当箇所は167行目から174行目にかけてです。
コメントアウトしているのが変更前です。


#FormatMessageA = Kernel32.extern "int FormatMessageA(int, void *, int, int, void *, int, void *)", :stdcall
FormatMessageW = Kernel32.extern "int FormatMessageW(int, void *, int, int, void *, int, void *)", :stdcall
def initialize(code)
@code = code
#msg = "\0".force_encoding(Encoding::ASCII_8BIT) * 1024
msg = "\0\0".force_encoding(Encoding::UTF_16LE) * 1024
#len = FormatMessageA.call(0x1200, 0, code, 0, msg, 1024, 0)
len = FormatMessageW.call(0x1200, 0, code, 0, msg, msg.size, 0)
#msg = msg[0, len].force_encoding(Encoding.find(Encoding.locale_charmap))
msg = msg[0, len].encode(Encoding.find(Encoding.locale_charmap))
#super msg.tr("\r", '').chomp
super msg.tr("\r".encode(msg.encoding), '').chomp
end

selenium-webdriver がエラーに..。

test-unit(2.5.5) と selenium-webdriver(2.39.0) で、あるサイト向けの簡単な回帰テストのコードを書いていまして。

$ rake test
Loaded suite /usr/lib/ruby/gems/rake-10.1.1/lib/rake/rake_test_loader
Started
E
===================================================================
Error: test_sample(Sample)
Selenium::WebDriver::Error::WebDriverError: unexpected response, code=502, content-type="text/html"

...

うーん..。と悩んで以下の記事を見ました。

windows 7 - Watir-webdriver 64bit windows7 cannot open any browser with error unexpected response, code = 502, content-type = "text/html" - Stack Overflow

えっまさか、と思って、設定していた http_proxy の環境変数を unset して再実行すると..動くではありませんか!
普段の開発では proxy 使ってないので、気が付かなかった..。
なぜだー、という気持ちはあるのですが、今日は深堀する気力はもうないです。