タイトルにJavaと書いておきながら、ここまであんまりJavaのコードを書くことがありませんでしたが、テキストファイルの読み書きあたりからやっとJavaプログラミングらしくなってきました。
あまりプログラミングをしたことがない方は、プログラマは一気に何十行ものコードをばりばりと打ち込んでいるようなイメージを持っているかもしれません。実際にそういう方もいらっしゃるのですが、こういう方は特殊であり、普通はちょっと書いてはあっているかどうか動かして確認をし、思った通りに動作していることが確認できてはじめて、続きを書いていきます。1行書いて実行・・・どころか、1行書く間に何度も実行することもあるでしょう。 そのような動作の確認をしているときに、いちいちアプリケーション全体を起動していては大変です。なにしろ今私たちが作ろうとしているのはWebアプリケーションですから、起動するとWebサーバが立ち上がります。動作を確認するにはブラウザが必要です。けっこう面倒くさいですよね。ブラウザを立ち上げると、ついうっかり関係ないサイトを見てしまったりしますし。それは私だけか。ともあれ、今作っている部分だけを動かして、そこだけの動きを確認したいと考えるのは自然だと思います。
さて、プログラムの一部だけ動かしたいと考えたとして、それはどこからどこまででしょう。その範囲が決められないと困ります。素直な発想として、その単位は特定のメソッドだと考えていいでしょう。しかし、Javaのメソッドは必ずどれかのクラスに属しています。そして、クラスメソッドではない普通のメソッド(インスタンスメソッド)は、クラスをインスタンス化、つまりnewしてやらないと実行出来ません。
そこで、単体テストとはこのようなものだということが出来ます。アプリケーションの中の特定のクラスを通常のアプリケーションの流れとは別に、それだけをいきなりインスタンス化して、そのインスタンスのメソッドを動作させ、動きを確認する。アプリケーション全体を動かす必要がないのでラクチンです。
ということは、テストをするためには
であることが必要です。そんなの当たり前じゃないかと思われるかもしれませんが、インスタンス化したら初期化プロセスでネットワーク先のサービスにアクセスに行ったり、メソッドを実行したら別の様々なクラスを呼び出したりするのはいただけません。テストの準備が大変になったり、あちこちに処理が飛んで結局何をテストしたかったのかわからなくなったりします。
これは実際にテストを作っていけばわかりますが、できるだけ他のものに依存せずにある入力をパラメータで渡したら、決まった出力が出てくるようなメソッドはテストがしやすいです。そのようにテストしやすいものを組み合わせていくと、アプリケーション全体の構造もわかりやすくなる傾向にあります。しかし、実際に書いてみないとよくイメージ出来ませんよね。とりあえず、試してみたい部分を上手く1つのクラスの1つのメソッドに入れられたとして、話を進めましょう。
さて、テストしたい対象がうまく分離できたとして、これをどうやって動作させればよいのでしょうか。それにはテストプログラムという別のアプリケーションを作ることになります。そのテストプログラムの中から、テストしたい部分を呼び出すわけです。つまり、「単体テストをする」ということは「テストしてくれる別のアプリケーションを作る」ということを意味します。そう聞くと、ちょっとビックリしますね。
しかし、別のアプリケーションと言っても、単にテストしたいアプリの一部を取り出して実行するだけなので構える必要はありませんし、それを簡単につくるためのフレームワークも準備されています。一般にテストフレームワークと呼ばれます。イマドキのプログラミング言語だと言語の組み込みの機能としてテストフレームワークを持っていたりするのですが、Javaは歴史ある言語なのでそうではありません。むしろ、テストフレームワークという技術自体が生まれたときに真っ先に作られたのがJava用のテストフレームワークでした。さすが、メジャーな言語です。それがJUnitです。由緒正しいのです。名前は聞いたことがあると思います。
しかし、今回はあえて別のフレームワークを採用します。JUnitは非常に有名なフレームワークなので、ぜひ、一度触ってみて欲しいのですが、今回採用するのはちょっとマイナーなフレームワーク、Spockです
テストフレームワークには、最初に作られた系譜であるxUnit系と後に現れたxSpec系の大きな2種類のグループがあるのですが、名前から推測できる通りSpockはxSpec系のフレームワークです(スペックとスポック、似てますよね)。xSpecはBDDスタイルという書き方をするんですが、ここではJUnitとは書き方のお作法がだいぶ違うよということだけ覚えておいてください。
もうひとつ、非常に大きな特徴がプログラムをGroovyというJavaとは別の言語で記述するということです。GroovyはJavaと同じくJVMの上で動くプログラムを作るための言語で、名前から推測出来るとおりスクリプト言語のRubyに影響を受けています(グルービーとルビー、似てますよね)。GroovyはJavaと一緒に使うことを重視している言語で、要は「Jくだけた表現で書いても良いお気楽なJavaの方言」だと思ってもらってOKです。
equals
じゃなくて==
を使うassert
があるなど、テストプログラムを簡潔に書くのに非常に向いた性格を持っています。
「テストを書くために新しい言語を1つ覚えるのは面倒だなあ」と思われるかもしれませんが、まあ、そう言わずに試してみてください。「上手い具合にJavaをサボって書けるようにしてあるんだなあ」と感心すると思います。
さて、まず最初に読むべきドキュメントですが、Groovyのチュートリアルを日本語に訳してくれている人がいます。だいぶバージョンが古いのですが、Groovyの基礎を知る上ではこれで十分です。
このドキュメントの以下の章を読んで下さい
13章はSpockの説明なので、これだけ読むとひとまずGroovyも書けてSpockも使えるようになります。
上の6章のリストの説明でも紹介されていますが、GroovyではJavaのクラスにGroovy用のメソッドが追加されています。 どのようなものがあるのかは、Groovyの公式ドキュメントの The Groovy Development Kitで 紹介されています。このページは何度も見ることになるでしょう。
Spockの公式ドキュメントもざっと読めれば良いのですが、英語ですし、書いている途中でより知りたいと思ったときに 拾い読みすれば十分です。時間があるなら、3章 Spock Primerだけを 通して読んで下さい。
では、Spockを使うためのセットアップです。
といっても、いつものようにbuild.gradleに追加の設定を書けばダウンロードして、使えるようにGradleがしてくれます。 もうおなじみですね。
(書きかけ)
(サンプルを載せる。普通のとSpring bootのやつと。)
(Kent Beckを読め!というようなことを書く)