はじめに
Railsを始め、フレームワークを利用すると良くも悪くも「プログラムの構造」に対して縛りが発生してきます。
しかしながら、Railsが好まれ・利用されている背景などを考えてみると、この構造が縛られる
ということがむしろ好意的に受け取られているのではないかと考えてます。
つまり、何を言いたいかと言うと。。。
プログラムの構造を1から考えることは難しい
プログラムの構造を考えるにあたり、役割
を意識することが多いと考えてます。
その際に大きな問題になるのが抽象化と共通化の問題。
よく言われるのは、共通化するな抽象化しろということかなと思います。
では、どこまでが共通化で、どこからが抽象化なのか。
今回はテスト
に焦点を当てることで、該当箇所が抽象化できているのか?を考えていくアプローチについて書いていければと思っています。
なぜテストに焦点を当てたのか
答えは単純明快
テスト時に自分考えた構造がおかしいことに気づいたから
これだけでは説明不十分なので、少し掘り下げて考えていきます。
よくできたプログラムは、テストしやすい
自動テストを書くようになり、神話のような感覚で聞いていたこの言葉の意味が最近良くわかるようになってきました。
スパゲッティコードというような表現をされるようなコードは、とにかくテストが書きづらい。
これはもう、紛れもない事実であると言い切れます。
例えば、下記のメソッドのプログラムのテストを書くことを考えてみてください
class SampleClass
def add(x, y)
x + y
end
end
1 と 2 を渡して、3 が返ってきているか?のテストをしようかな…
と大半の方が考えたのではないかと思います。
では、次はどうでしょう?
class SampleClass
include SampleModule
def add(x, y)
round(x + y)
end
end
Module SampleModule
def round(x)
x > 100 ? 100 : x
end
end
SampleClassのadd
をテストしたいはずなのに…
計算結果が100を超える場合と超えない場合
を意識したテストが必要になりそうじゃないでしょうか?
round
という役割をあえて分けたにもかかわらず、結果的にadd
がround
の動作に依存していることになっている。
すごい極端な例を上げましたが、個人的なテストしやすさはこういうことなのかと考えています。
結論
抽象化したつもりが、分離したコードの結果を意識したテストを書かないといけないという状態に陥ったとすると、それはおそらく適切に構造化ができていないサインだと思います。
今回、自分自身が恥ずかしながらこういうケースに遭遇し、改めてテストコードを書くことの大切さと、コードを構造化することの難しさを感じたので戒めもこめて記事に残しました。
構造化に悩むプログラマーの方々、自動テストの導入になかなか踏み切れないプログラマーの方々の一助になればと思います。