@ledsun blog

無味の味は佳境に入らざればすなわち知れず

#TestingFrameworkMeeting に参加しました(1) - テスティングフレームワークの歴史

参加した時のメモです。

t-wadaさん

Testing Framwork Meeting

テスティングフレームワークの歴史

http://www.slideshare.net/everzet/bdd-in-symfony2/42 のスライドがベース。

有史以前

make checkのように、テストを自動化する風習はあった。 開発者はそれぞれ秘伝の手法でテストコードを書いていた。

JUnit

Kent BeckJUnitを書いた。

プロダクトコード書いてから、テストコードを書くまでの時間が短いほうが、 プロダクトコードに対する気づきが得られ、それをプロダクトコードに反映できることがわかった。

テストコードをさらに早く、プロダクトコードより早く書いた。 テストファーストが生まれ、ユーザーの視点でプロダクトコードを設計できるようになった。

自動テストがあれば、設計して実装してから、実装だけを直せる。 サイクルをもっと短くし、テストファーストリファクタリングを繰り返すテスト駆動開発(TDD)が生まれた。 *1

JUnitの語彙assertEqualsがテストコードを支配した。

JUnit Pocket Guide - O'Reilly Media がテスティングフレームワーク作者ののバイブルになった。

BDD

テストコードが表しているのは、テストではなく仕様であると考える者達が居た。 Dan Northは、それにbehavior driven development(BDD)と名付けた。

RSpecが生まれ、振る舞いを記述するための語彙、should, expect ... 、が増えた。 各プログラミング言語にXSpecが生まれ、語彙が乱れていった。

また、自然言語のように書けテストコードをのように動く仕様で、 お客さんと一緒に仕様を書くことを考える者達が居た。 Fitが生まれ、cucumberが生まれた。

BDD派は、前者がSpec BDD派へ、後者がScenario BDD派へ分派していった。

power-assert

RSpec3が生まれた。テストコードの語彙がさらに増え、いろいろな書き方ができるようになった。 テストコードを書くのに学ぶべきことが増えた。

多くのRuby on Rails使用者は、Rails本体とRSpec、両方の変化の速さについて行くために苦しんだ。

テストが失敗した原因をわかりやすくするために、 語彙を増やす以外にテスティングフレームワークができることはないか考えた者が居た。 Groovyにspockが生まれた。 そこにはPowerAssertと呼ばれる力があった。

Condition not satisfied:

name.size() == length
|    |      |  |
|    6      |  7
Scotty      false
魅惑的(Fascinating)なテスティングフレームワーク Spock - A Memorandum

エラーに失敗した時だけ饒舌なassertが生まれた。 ASTをごにょごにょして、t-wadaさんがJavaScript版のpower-assertを作った。

evolve slowly

テスティングフレームワークは、直接的にプロダクトコードを改善しない。 10年くらいのペースで変わるのが望ましい。

議論

語彙と階層
  • RSpecの語彙の多さは、目的が仕様記述言語を目指しているから。 多くのユーザーは階層化と語彙の多さは分離して欲しいが、わけて使えない。 それで批判に繋がっているのでは?
  • RSpec以降のライブラリは階層と語彙を分けれるようになっている。(例えば)mochaは階層化だけを提供していて、assertライブラリは別に組み合わせて使う。
学習コスト
  • RSpecのシェアが大きすぎるので、学習コストの批判が目立っているのでは?
  • 政治的な理由でRSpecを選択していることもある。それで批判されやすいのかもしれない。
日本語でシナリオBDD
  • cucumberは正規表現で実装されている。日本語で使える可能性や価値はあるのか?
  • 過去に、「なでしこUnit」を作った。日本語の語順と制御の順が合わないので、そんなに嬉しくなかった。
テストコードのレイヤーが増えること
  • (プロダクトコードと異なるプログラミング言語で描かれている)cucumberを使った、テストは落ちたときに原因を探すレイヤーが増えて辛かった。
  • JavaのテストコードをGroovyで書く人たちがいる。テストコードを書く効率はあがる。
Reads like as spoken language
  • RSpecには読みやすさを提供する目的があったのでは?
  • JUnit4でisが入って読みやすくなった。覚えるコストは増えた。これは二律背反、当分解消できそうにない。
Expamleとしてのテストコード
  • Expamleとしてのテストコードを考えると、TDDではプロダクトコードに近く例としてわかりやすい。 BDDで仕様記述に近いと、例として使えなくなっていく。
  • Exampleとしてのテストコードは一部なので分けて考えた方がよさそう。 Haskellにはdoctestという、公開するAPIにExampleとしてのテストコードをつける文化が生まれている。公開しない部分はhspecで書く。
  • Goでは、Exampleとしてのテストコードを書くツールがある。

simple vs easy

power-assertの設計思想について。

で、衝撃を受けたという話。

  • Simple 客観的
  • Easy 主観的

SimpleとEasyは混同しやすいけど、分けて考えた方が良い。 原則はSimpleを目指し、EasyはEasyを提供する別レイヤーを提供すると良い設計になる。

実際にソフトウェアを作る時は、怠惰・短気・傲慢の怠惰を元に、 簡単さを求めて作り始めて、複数の簡単さの競合に気づいて、「シンプル」と「簡単」に分けるようになることが多い 。

qunit-tapの開発では、当初Easyを求めて「自動的にQUnitを探す」設計にしていた。 多様な環境に対応できなかったので、Simpleな「QUnti引数で受け取る」設計に変えた。 結果、より多くの人に使いやすくなってユーザーが増えた。

リンク

つづき

は、書かないかもしれません。

*1:詳しくはわからないがXP本の1版と2版の間の、どこか