この記事はSLP KBITアドベントカレンダー18日目の記事です。
昨日はラブライバーがKotlinについて熱く語っていました。
今日の午前6時に嫁が世界改変を起こす*1ので、それ以降私はパラレルワールドに飛ばされていると思います。
言い訳から始まりますが、雑誌の原稿や英語論文と格闘していたので何もネタができていません。
そんなわけで、最近読んでいる本とかその周りをたらたらと書こうかと思います。
ソフトウェアテストとは
うちの大学だと、「ソフトウェア工学1」とかで説明されると思いますが、ソフトウェアテストです。
どういうもんかというと、こんな感じです(丸投げ)
Rubyでのテスト
Rubyには有名なテストツールが2つあります。
- Minitest
- Rspec
それぞれ記法がだいぶ違いますが。
例えば、以下のようなコードがあったとします。
def add(a, b) return a + b end def sub(a, b) return a - b end
このとき、Minitestだとこんな書き方になります。
require '上の関数をまとめたファイル' class FunctionsTest < Test::Unit::TestCase def test_add assert_equal(add(3, 4), 7) end def test_sub assert_equal(sub(4, 3), 1) end end
Rspecだとこんな感じ
require '上の関数をまとめたファイル' Rspec.describe '~~.rbのテスト' do describe '#addの引数が' do it '3と4のとき、7が返却される' do expect(add(3, 4)).to eq 7 end end describe '#subの引数が' do it '4と3のとき、1が返却される' do expect(sub)4, 3)).to eq 1 end end end
それぞれspec記法かxUnit記法化は違うと思いますが、どちらもほぼおなじことができると思います。
こういったテストを書くことで、関数やクラスの あるべき姿 を記述することができます。
テスト駆動開発
テスト駆動開発という言葉を聞いたことがある人がSLPにも多いと思います。
テスト駆動開発とは、
プログラムに必要な各機能について、最初にテストを書き(これをテストファーストと言う)、そのテストが動作する必要最低限な実装をとりあえず行った後、コードを洗練させる、という短い工程を繰り返すスタイル (wikipedia)
です。
順序としては、
- テストを書く
- 機能を実装する
これらを繰り返し、その後、コードを洗練させる(リファクタリング)という流れですね。
これの何がいいかって、テストを書く段階で仕様がちゃんと明確になる点ですね。
あと、何を実装するのかが明確になる点だとおもいます*2。
とはいえ、研究室とかだと色々と闇深いものがあったりします。
実際現場(研究システム)で色々と発生することとテストによる解決
ある日、研究室のボスからとあるシステムを渡されて「これを改良して」と言われたとします。
このとき、この改良をするには結構中身をいじったり、今ある関数を直したり、関数を生やしたりしないといけないとなったとします。
さて、どうしたもんでしょうか。ちなみに、テストは書かれていません。
まず、このようなときに最初に思うことは、「新機能だけ追加した」とき、システムがバグらないかというところです。
これを思ったら最後、エンバグするのが恐ろしくてなにもすることができなくなります。
じゃあどうするかというと、テストを書きます。
これは、実装する機能の仕様を明確にするテストではなく、今ある姿の仕様を明確にするテストです。
これをすることで、中の関数を変えても、改良前の機能が壊れていたらテストが落ちるようになります。素晴らしいですね。
このテストを書いてから、新しく機能を追加していけば、エンバグの心配もなくなります*3。
まとめ
みんなテストかこう!
ちなみにこの話は、t_wadaさんのテスト駆動開発、そして実際に直接話を聞いて感じたことです。
テスト駆動開発はいい本なので皆さんにとてもおすすめします。
別件ですが、Kbitのページをもっと気楽にできるような何かがほしいなと感じています。
GithubにPushしたら記事が更新されるような、そんな感じにしたい気持ちがあります。
年末ハッカソンとか年始ハッカソンとかでガッとできるような気もするので、誰か企画してくれ〜〜〜。