テスト駆動開発読み進め(第1回)

最初から第2章まで
くそSIerの企画職がテスト駆動開発を苦労しながら読み進めます。(発信が大事らしいしね)
Amazon「テスト駆動開発」
私は業務ではCOBOLとか(PL/1)とかしか書いたことがないので、学びながらやっていきたいと思います。

まえがき

テスト駆動開発とは、プログラミング時の"不安"をなくすため。
プログラグ書いてるとき、あってるかわからんとかバグがないかなとか根拠もなく不安になるのは結構あった。(特に仕事だと)
テストという判断基準を作ることで、はっきりさせ"不安"という状態をなくせる、それによって色々いいことがあるよーって感じ

はじめに

「自動テストコードをコードを書く前に書く」「重複を排除する」の2つのるルールを守れば、天才でない人間もシステム開発できるよ。って感じのことが書いてありました。

第1章前

書きながらやると理解がすすむかもよって前書きに書いてあったので、実際に動かしながらやってみようと思った。
書いてある通りJavaでやるのもあれかなと思ったのでKotlinをお勉強しながらやってみます。

第1章 仮実装

class MoneyTest {
   @Test
   fun testMultiplication() {
       var five = Dollar(5)
       five.times(2)
       Assertions.assertEquals(10,five.amount)
   }
}

とりあえず、テストをクリアしてみる。5*2がテストケースだったら、答えの10をコードにべた書きしてもかまわない。そこからリファクタリングを行ってきれいなコードへの近づけていく。このリファクタリングを重複の削除と本の中では言っている。10は5*2だし、5*2はtimesメソッドと重複してるからtimesでやってしまおうみたいな感じ。すると以下のようなコードが出来上がった。

package money
class Dollar(var amount: Int) {
   fun times(multiplier: Int) {
       amount *= multiplier
   }
}

実際この程度のコードだったら最初から思いついて実装できるわけだけど(そういう場合が第2章の明白な実装)、実装方法を思いつかない場合もあるわけでその場合には使えるのかなーって

第2章 明白な実装

class MoneyTest {
   @Test
   fun testMultiplication() {
       var five = Dollar(5)
       five.times(2)
       Assertions.assertEquals(10,five.amount)
       five.times(3)
       Assertions.assertEquals(15,five.amount)
   }
}

今度の通すべきテストはこいつ!
第1章のテストではDollarに副作用(amountの更新)が発生していたけどそいつが起こらないことをテストに組み込むために直後に3倍しても5*3が返ってくることをテストに組み込んだ。
でもこれちょっと考えれば、無理のあるテストだってのはわかる。一回目のfive.amountですでに10になっているのにそれを3倍したら15になるなんて意味わからんもん。five.amountを更新してるのが解決すべき副作用なんだしそこでEqualとるのがおかしいよ。(第1章の設計・テストがいまいちだったってことだね)
だからテスト書き換えました!

class MoneyTest {
   @Test
   fun testMultiplication() {
       var five = Dollar(5)
       var product = five.times(2)
       Assertions.assertEquals(10,product.amount)
       product = five.times(3)
       Assertions.assertEquals(15, product.amount)
   }
}

ってことでこの章の対象のテストはこの子です。このテストコードを書いた時点でproductはDollarクラスだと思ってるわけで、timesメソッドはDollarを返す必要があるってわかる。ってことで、実装も思いついたのでほいって実装します。

package money
class Dollar(var amount: Int) {
   fun times(multiplier: Int):Dollar {
       return Dollar(amount * multiplier)
   }
}

一発でテストも通る完璧なコードの出来上がりです。
こんな感じで頭に神様が降り立った時はぽいぽい実装してテストを通してもOKってことね。(明白な実装)
というよりも、いかにテストを書くかってとこのほうが難しいね。「こういうふうにしたいー」っていうものをうまーくテストっていうコードの中に落とさなきゃいけないわけで、そこは繰り返しやって鍛えていきたい!

この記事が気に入ったらサポートをしてみませんか?