新人SEに向けて~はじめてのrspec編~③

f:id:piyo_yeah:20181202190633j:plain

現場に入ってRSpecをいじることになったけど、何をすればいいかよくわからない、そんな人に向けた記事。
※この記事ではRSpecをspecと略します。現場の人も大体スペックって呼ぶし。

前回の続き。
今回は「テストと開発の違い」を解説する。
やや理念的な話だが、なんとなくテストを作るのは効率が悪いし、テスト本来の良さも発揮できないと思うので、ここは抑えておく。

開発とテストの共通点

開発とテストのどちらとも、現場で既に稼働しているプログラムについて把握することが求められる。
流石にわかりづらいと思うので、具体例を出そう。
先ずは開発工程を考え、次にテスト工程を考える。
何故なら、結論から先に言ってしまうと、開発よりもテストをする方が難しいからだ。

※尚、以下の例には乱暴なところが多々含まれるが御容赦願う。

実装の具体例ー概要

現場のプログラムには「一般ユーザ」「管理ユーザ」の二つの権限が用意されており、「一般ユーザ」は自分の所有するファイルのみ、「管理ユーザ」は全ファイルを自由に扱えるものとする。

ここで、あなたは「管理ユーザの権限を一部行使できる準管理ユーザ」を新たに開発することになったとしよう。
既に「一般ユーザ」「管理ユーザ」の二つが定義されている以上、その書式を真似すれば難しくはなさそうだ。

そうなると、次に行うべきは「一般ユーザ及び管理ユーザが定義されているファイルを探す」ことになるだろう。
そこに「準管理ユーザ」を定義すれば、開発は大きく進展しそうだ。

具体的な実装例ーユーザ特定の仕様

今回は、ログイン時に入力したID及びパスワードから、ユーザの権限が「一般ユーザ」なのか「管理ユーザ」なのかを把握する仕様だと仮定する。

そうなると、新たに定義した「準管理ユーザ」もそこで判断される形にするのが好ましいだろう。

開発時の意識

以上から浮かび上がったタスクは主に二つ。
1. 「準管理ユーザ」を定義するためのファイルを探す
2. ユーザ権限の識別をしているファイルを探す
後は、先駆者の書き方を真似ればいい。コード内に不明な箇所があれば随時調べたり、先輩方に質問したりすれば良さそうだ。

テストすべきこと(ざっくりと)

さて、やっと本題だ。
先ずは結論から述べると、今回意識すべきことは、ざっと挙げるだけで以下のようになる。
1. 権限の識別を疑う → ユーザ権限の識別が失敗するようなケースはないか?例えば、どの権限にも当てはまらないような不正な値が入力されることは有り得るのか?
2. 操作の不正を判断する仕組みを疑う → 準管理ユーザとして識別された後に不正な操作を行うと、ちゃんと失敗するようになっているのか?
3. DBを疑う → 準管理ユーザの情報は正しくDBに格納されているか?どのテーブル(表)を用いているのか?

開発初心者の落とし穴

開発時には敢えて話題に上げなかったが、ユーザの情報はほぼ間違いなくDBに格納されているだろう。
そうなると、新たにテーブルを作成する必要があるし、テーブルを構成するカラム(column = 列)を決める必要もあるし、テーブルの関係性を考える必要もあることに気づくだろう。

「開発」となると、処理の流れを考えて「こうすればええんやろ」と考えがちだ。(事実、自分がそうだった……)
しかし、処理の流れがあるということは、それを裏で支える仕組みについても理解する必要があるということだ。

テストに必要な姿勢

先程ざっくばらんに列挙したテスト項目を見て頂きたい。
テストに求められる姿勢は、本当にこれで大丈夫なの?という「疑う姿勢」なのだ。
開発した一つ一つの処理に対して、本当にこれで動くのかを確かめていけば、テスト能力はどんどん高まっていくだろう。

テストの難しさ

そうは言っても、何でもかんでもテストするわけには行かない。プログラムを疑いだしたらキリがないし、明らかにこれ以上疑っても時間の無駄だ、ということもあるだろう。
テスト能力を高めるには、「ここは疑っておくべき」「これはわざわざテストしなくていい」という判断力が重要になってくる。
ここだけで果てしなく議論ができるものではあるが、筆者もよくわかってないし最初は気にするべきではないので割愛する。
興味がある人はTDD(テスト駆動開発)とかで調べてみてね(調べたら筆者にも教えてね)

疑いまくって経験を積もう

何を疑うべきか、という判断力は、プログラムを沢山書いたり疑いまくることで少しずつ向上していくものである。
例えば、文字列を取得して、その長さで処理を分けるメソッドがあるとする。

# 雑な例だけど許してちょ
def hoge str
  if str.length > 1
    return true
  end
end

もし引数strがnilだった場合は、lengthメソッドが存在しないよ、とエラーが返ってくることになる。

これを知っていれば、文字列の長さを扱う時には返り値がnilじゃないことを確かめる必要があることが分かる。
上記はショボイ例に思えるだろうが、書いてエラー出しまくったり、疑ってrails consoleなどで値を調べながら処理を進めてみたりすれば、テストに関する判断力も向上していくものだと筆者は考えている。

おわりんりん

今回はここまで。
次回は、「実際にテストデータを用意するときの考え方」 を扱います。
簡単に言うと、モデル間の関係性を把握しなさいよ、改装を把握して上から作るのよ、という話をする予定です。
前回の次回予告とズレまくっていたのは御容赦。次回こそ予告通りに出来たらいいなぁ……←

コメントで感想や指摘いただけると助かります!
それでは!(`・ω・´)