テスト駆動開発の本読んだ

テスト駆動開発という本を読んだので、自分なりに学んだことをまとめておく。

最近、ちゃんとテストを書くように意識するようになったので、
自分にたりない知識を得ることができた。

まず、テストするためには、テストできる構造でないと行けない。
実装コードをなにも変えずに、テストだけ追加するのは結構しんどい。
そのために動いているコードを改修する必要もででくる。

品質を上げるためにテストを書こうとしているのに、テストを書くための改修でバグを仕込んでしまうリスクもある。

そのあたりを、うまいことテストできるように改修していくには、
それなりに技術と設計力が必要となる。

ということで、最近いろんなテスト開発関係の本を読みあさっています。

テスト駆動開発

テスト駆動開発によって目指すゴールとは、
”動作するきれいなコード”である。

テスト駆動開発の基本サイクル

  • テストから書く(まず失敗するテスト)
  • テストが通る状態まで最速で実装する
  • リファクタリングにより重複を除去する

基本このサイクルの繰り返し。

テストから書くことで、実装都合に寄らない本当にあるべき自然な表現へとつながる。
どのように実装しようか?ではなく、どのようにテストを書こうか?という視点で進める。
つまりは、プログラムがどのように挙動してくれればよいか、という仕様を明らかにすることになる。
仕様(挙動)を正しく評価できれば、実装方法はどうでもよくなる。
この視点を持つことが大事。

重複を除去する過程でより良い設計へと駆動する。
テストにより仕様が明確になっているので、コードの重複を除去する作業、リファクタリングが自由にできる。
仕様が満たされているかどうかはテストを動かすことで容易に確認することができるからだ。

テストを書く上で依存性を除去する必要がある、そこには技術力が求められるが、
結果として結合度の低いコンポーネント設計ができるようになり、
使い回しがよく保守性に優れたプログラムができあがる事になる。

TODOリスト

目の前の作業に集中するために、積極的にTODOリストを使おう。

作業をしていると得てしてアイデアが浮かんだり、気になる事を発見してしまうものだ。
だが元の作業から脱線しそうなものは一旦置いておいて、忘れないようにTODOリストに追加しておこう。

あまり深追いしすぎると元の作業が置き去りになり、やるべき事から遠ざかってしまう。

また、リスト化していると、
どのくらい仕事が終わったかどうかも明確にできる。

私の会社では毎日、日報をつけているので一日を振り返ってどういった作業をしていたのかが確認することができる。
残った作業は明日やることとして整理をしている。

依存性と重複

コード重複を取り除くことは、結果として依存性の除去にもつながる。

特定の環境に依存したコードは、ロジックのあちこちに環境依存のコードが散在している。
抽象化することで重複は除去でき、依存性は除去される。

逆説的に、
依存性の問題がある場合、それはコードの重複として出現する。

三角測量

三角形の2点間の距離がわかっていれば、最後1点の方角がわかるだけで、そこまでの距離が計算できる。
無線信号の発信源を特定する方法でも同様に三角法を使って測量出来る。

この三角測量を真似て、テストケースを書く際は2つ以上の視点で記述すると良い。

変更を試しやすい環境

検討に時間がかかる改修案でも、テストケースが揃っていると、簡単に試す事が出来る。
影響範囲も失敗したテストを見ていけば想像も可能だ。

悩んでいるよりも、さっさっとテストケースを作って試してみる方が早い場合もある。
そういう選択肢が増える事もテスト駆動開発で網羅できていることのメリットだ。

テストによる作業量

テスト駆動開発をしていると、実装コードと同じくらいの行数だけ、テストコードを書くことになる。
実際、自分で試してみても、そのくらいのコード量にはなった。

まぁテストコード自体は単純なアサーションばかりのコードなので、
量の割に作業量が増えているかというとそうではないが。

それでも普段よりも実装時間はかかってしまうので、
デバック工数、今後の改修のしやすさ保守性も含めて、
総合的に生産性があがるかどうか考慮して導入する必要がある。

今後だれも触れないようなコードの箇所だったとして、
それに対してテストが必要だったのか?という事も思うかもしれない。

ただ将来どのような仕様変更がくるのか想像するのは難しい。
今後触れない箇所か、または触れない箇所であっても、今後ほかのコンポーネントが改修された事によって影響が及ぶ可能性もある。

因果ループ

テストなんて書いてる時間がない。というのは
どんどん時間が無くなる、負のスパイラルである。

スパイラルから抜け出すために、
まずはテストを書かなくてはならない。

テストがない場合

コードを書くたびに、上手く動作するだろうか、他に影響を及ぼしていないだろうかとストレスがかかる。

考慮やデバックに時間をつかうことになる。

エラーや、修正作業が増え、時間が無くなり
ストレスがかかる。

結果ストレスがどんどん増えていき、
仕様変更もしにくい保守性も下がった触りたくもないレガシーコードとなってしまう。

テストがある場合

テストがあるので、コードを書いてちゃんと動く事がすぐわかる。
影響範囲も明確になり、修正できたかどうかも判断が出来る。

実装時間は増えたが、
考慮やデバックの時間が減り、ストレスが無くなる。

結果的にテストが出来るコードになってるので、
仕様変更や保守しやすいソフトウェアになり、品質が上がる。

所感

テスト駆動開発を読んでみて、
またちょっと自分でも実践してみて思ったのは、やはり最初は実装に結構時間がかかります・・。

良いテストケースを書くことにも経験が必要ですし、
それを実現するための依存性の除去にも設計力が必要になります。
正直ハードルが高いと感じてしまいます。

テストで書いた通りの実装にできないとか、既存コードにどう手を加えて行くのかー、とか。
もともとの開発スタイルと違って、モタモタした作業になってるような気分になります。

ただ、そこを乗り越えて行くと、テストがあることでの安心感がすごいです。
ちゃんと動いているという安心感があります。
(そりゃ動いてるでしょうと思うけど・・、細部まで正しく動いているという感覚です)
デバック作業に時間を取られる事もなくなるでしょう。

テスト駆動開発したときのクラス設計は、今までのものとはちょっと違った雰囲気になりました。
インターフェイスを積極的に使う事にもなりますし、
これが依存性が除去されたコードなのか〜とか、
なんかテストのためだけに用意されたメソッドもできちゃうんだけどな・・、という感じ。

テスト技法の習得はスキルUPにはなるな〜と思いました。
オープンソース開発なんかでは、テストケースがないだけでリジェクトされたりもするので、
今後テストがちゃんとかけるプログラマーになってはおかないとー!

1件のコメント

コメントを残す