【翻訳】TDD is Fun

@solnicが、DHHの例の記事へのカウンター的な記事をポストしてまして、自分のために読んでみたらよい内容だと思ったので、翻訳してみました。翻訳ミスとかあると思いますが、、、すみませんです。。。

TDD is Fun

Posted by solnic on Apr 23 2014

著 solnic 2014年4月23日

Today DHH published a blog post about TDD being dead (to him at least). It’s really not that surprising since from what I know (please correct me if I’m wrong) David’s experience is mostly based on building web apps with Rails. I get that, I really do. For me practicing TDD in a rails environment is much harder than when I work on my OSS libraries. There are many reasons why TDD in Rails is just a bit harder than it could be but that’s a big, separate subject. In this post I want to explain that TDD can be fun!

今日、DHHは (少なくとも彼にとっては) TDDが終わったことについてブログ記事を発表しました。私の知っているところでは (もし私が間違っていたら指摘してください)、Davidの経験のほとんどがRailsでのウェブアプリ構築に基づいているので、これは全く驚くようなことではありません。私にはよくわかりますし、本当にそうだと思います。私にとって、Rails環境でTDDを実践することは、自分のOSSライブラリで実践する時よりずっと大変です。RailsでのTDDがあるべきより少しばかり大変なのには多くの理由がありますが、それは大きな別の議題なのです。この記事では、TDDは面白いということを説明しましょう!

it’s not as strict as you think

There are many guidelines in TDD. That you should focus mostly on unit testing. That you should be using mocks and stubs in isolated unit tests. That you should have contract tests. And so on. That list can be pretty long.

あなたが考えているほど厳格ではない

TDDには多くのガイドラインがあります。「主に単体テストにフォーカスすべきだ」や「独立した単体テストではモックやスタブが使われるべきだ」とか、「contract testsを利用するべきだ」などです。そのリストはかなり長いです。

Those are guidelines, they make a lot of sense and personally I found them to be useful but for me, when it comes to the core of TDD…it’s this:

それらはガイドラインであり、それらは大いに意味があり、個人的には有用であると理解していますが、TDDのコアというのは…以下だと思います。

Write a test that describes expected behavior of your system and make it pass.

Yes, that’s it. That’s how your journey begins. It doesn’t have to be a unit test. It can be an integration test. It can be an acceptance test (which is great when building web apps!). You simply know what kind of test you are able to write at a given point in time based on your current knowledge. This knowledge will be expanding as you go through red/green/refactor cycles. You will see missing interfaces, you will be able to introduce new objects and test-drive them from the start because after few refactorings you will know, trust me, you will know how they should look like.

自分のシステムにおいて期待する振る舞いを記述するテストを書き、それをパスさせなさい

そう、これなんです。これが出発点ということなのです。単体テストである必要もありません。承認テストかもしれませんし、受け入れテストでもかまいません (それは、ウェブアプリを作る場合には、とても有効です!)。その時の知識に基づいて、その時点でどんなテストを作成できるかをあなたはよく分かっているはずです。その知識はred/green/refactorサイクルを通して、拡大していくでしょう。そして、足りないインターフェースを理解し、最初から新しいオブジェクトやテスト駆動を導入するでしょう。というのも、数回のリファクタリングの後に、あなたは分かるように、いや本当に、あなたはテストがどのようにあるべきか分かるようになるからなのです。

That’s how tests are guiding you, that’s how you’re designing your system based on the feedback of your tests. It’s a process, a journey that involves many small refactorings. You don’t stop after making your first test pass. You move on and discover missing pieces of the puzzle. It’s a lot of fun and it gives you great confidence that the code you just wrote works exactly like you want.

そのようにして、テストはあなたを導き、あなたはテストの結果に従って自分のシステムを設計するでしょう。それは、多くの小さなリファクタリングを伴うプロセスであり、長い工程なのです。最初のテストをパスしたからといって、止まってはなりません。どんどん進んで、パズルの足りないピースを探してください。それはとても面白く、あなたが書いたコードがまさに思いどおりに動く大きな自信を与えてくれます。

Unit testing

It seems like DHH confuses unit testing with TDD. Unit testing is part of TDD and it’s a very crucial part. Most of the nastiest, hardest to fix bugs exist because of a poor unit test coverage. That’s a fact.

単体テスト

DHHは単体テストとTDDを混同しているようです。単体テストはTDDの一部、極めて重要な一部です。たいていのバグフィックスが不快で大変なのは、単体テストカバレッジが不十分だからです。これは真実です。

Some people are afraid of unit testing though and this is also not that surprising. It’s mostly because the cost of maintaining a big unit test suite is high. It’s very easy to spend a lot of time writing many small, focused unit tests that soon turn out to be obsolete and that hurts a lot.

一部の人が単体テストをいやがっているが、それもまたやはり驚くようなことではありません。というのも、大抵、大規模な単体テスト一式をメンテナンスするにはコストがかかるからです。すぐに使い物にならなくなり、苦痛うを伴う小さくて焦点の合わさった単体テストを書くことに多くの時間が簡単にかかってしまいます。

I think this happens because of two reasons:

  • Writing unit tests too early
  • Using mocks and stubs prematurely

私はこれには2つ理由があると思います。

  • 単体テストをあまりに早くに書いている
  • モックやスタブを使う段階ではないのに使っている

We’ve been told that a unit test excercises a unit in complete isolation from the surrounding environment especially its dependencies. That’s a really nice concept and it works very well. But…you really need to feel confident about what you’re doing before you introduce unit tests. This can be achieved rather quickly after 1 maybe 2 red/green/refactor cycles after making some higher level test pass. You will see missing abstractions and you will know what kind of an interface you want to have. That’s a great moment to start writing unit tests.

単体テストは、取り巻く環境、特にその依存性から完全に独立して用いるものだと教えられてきました。それはとてもよい概念で、とてもうまく働きます。しかし、単体テストを導入する前に、あなたが行おうとしていることに自信を持つことが必ず必要なのです。これは、上位レベルのテストが通った後、red/green/refactorサイクルを1,2回実施した後、かなりすばやく達成できます。足りないアブストラクションを理解し、どういう種類のインターフェースをもつべきか理解できるでしょう。そのときが、単体テストを書くべき時なのです。

There are also cases where you’re just prototyping something. This is really a bad moment for unit testing.

何かをただプロトタイピングしている場合があります。こういう時に単体テストを書くことは最悪です。

Another pain-point in unit testing that probably discouraged DHH is using mocks and stubs. If you do things “by the book” you would immediately start mocking dependencies and stubbing various method calls. For me it never works like that. Sometimes I would mock an interface as soon as I discover it. Another time I would just wait with mocking until I feel really confident that a given collaborator object shouldn’t be treated as an internal implementation detail. There are many guidelines here as well, learn about them and keep them in mind but don’t follow them strictly all the time.

たぶん、DHHのやる気を失わせたユニットテストの中での問題点は、おそらくモックとスタブを使うことでしょう。もしあなたが「型通り」に行おうとすれば、すぐに依存性をモックし始め、さまざまなメソッドの呼び出しをスタブすることでしょう。私は、これはうまく働かないと考えます。時々、私はインターフェースを見つけるとすぐに、それをモックします。別の場合には、ある共同して動くオブジェクトを内部の実装詳細として取り扱うべきでないということに、本当に自信が持てるまでずっと、モックを使うのを待つでしょう。多くのガイドラインがあり、それは学ぶべきですし、心に留めておくべきですが、それらに常に厳密に従う必要はありません。

It’s fun but it takes time to learn

You can’t buy a book about TDD and learn it in a month. It takes a lot of time and that’s why trying to be very strict about various TDD guidelines (especially the ones about unit testing) will be frustrating.

面白いが学ぶのに時間はかかります

TDDに関する本を買って、それを1か月で習得することはできません。長い時間がかかり、そのため、様々なTDDガイドライン (特に単体テストに関するものは) にあまり厳密であろうとすると、いらいらすることになるでしょう。

This doesn’t change the fact TDD is a lot of fun. Just be cool with it. If you manage to teach yourself to write tests first, you already gain a lot. Break the rules whenever you feel they are blocking you or slowing you down. If you broke a rule and ended up with problematic code you’ll at least learn why following that rule in a given context is a good idea.

TDDがとても面白いことを変えるわけではありません。ただ冷静であるべきなのです。とにかくテストがうまく書けるようになれば、あなたは多くを得ます。テストがあなたを妨げたり、遅らせたりすると感じたらいつでも、ルールを破るべきです。ルールを破って問題を持つコードになってしまっても、その文脈ではルールに従うことは良いことであると、すくなくとも学べるでしょう。

Chill out, doesn’t matter if you get things right during first or fifth attempt, the process is all that counts. Write a test, make it pass, look at the code and take it from there.

冷静になりましょう。最初か5回目かの試みの間で正しさを得るかは問題ではありません。プロセスがそのすべての論点なのです。テストを書き、それをパスし、コードを見て、そこからそれを続ければいいのです。