データベースをテストするUnit test

このレッスンでは「ユニットテスト」について学んでいきましょう。ユニットテストとは、モデルの為のテストの事です。

吉田先生

ユニットテストでは主に、データベース関連のテストを行います。


Unit testとは

このレッスンでは「ユニットテスト」について学んでいきましょう。ユニットテストとは、モデルの為のテストの事です。ユニットテストでは主に、データベース関連のテストを行います。

たとえば、ある属性が空だったり、値が長すぎたり、重複した値である場合には、レコードとして無効であると指定したとします。

その場合に、きちんと動作し無効なレコードが保存されてしまわないかなどのテストを行います。では、実際にテストを行ってみましょう。以下を参考に、アプリの作成を行ってください。

Railsアプリの作成を行うと、テストファイルを置くためのディレクトリなども作成されます。このように、テストの為の最低限の準備はRails側で行ってくれます。

これにより、容易にテストを行う事が可能となるのです。では、モデルを作成します。以下を参考に作成してください。

上記の様にモデルの作成時、テストの為のファイルも一緒に作成されます。モデルのテスト用ファイルは、モデルごとに作成されます。また「article_test.rb」というのが、行いたいテストを書くファイルです。

「articles.yml」というのは、フィクスチャの為のファイルです。では、データベースの構成を行います。以下コマンドを実行してください。

$ rails db:migrate

モデルの為のテストは、以下ディレクトリに作られています。では「article_test.rb」を開いてください。

test/models/article_test.rb

以下は、生成されたファイル内容です。ここに、テストを追加していきます。

まず、1行目で「test_helper」を読み込んでいます。これは、全てのテストの為の設定が書かれたファイルです。このファイルでは、テストはテスト環境を使用して行う、などの設定がされています。

このファイルは全てのテストファイルに読み込まれているので、このファイル内で設定したメソッドは全てのテストファイルで使用できます。

テストの追加

では、テストの追加をしていきましょう。ここまでで、タイトルと本文というカラムを持つArticleモデルを作成しました。このモデルは、記事の投稿などが行える機能の為に作成したとういう想定です。

このモデルの他に、コントローラを作成してアクションなどを追加すれば記事の投稿が行えるようになります。

しかし、モデルにバリデーションを追加していなければ、タイトル・本文ともに空であっても、記事は投稿できてしまいます。ですので、空の記事が作成されないよう、タイトルには値が必須であると定義することにしましょう。

まず、空の記事でも投稿出来てしまうことを確認してみます。以下を参考にテストを追加してください。

まず、上記部分ですが「setup」というメソッドが使われています。これは、テストの実行前に行っておきたい処理がある場合に使用するメソッドです。

今回は、インスタンス変数を定義しています。作成されてはならない、空の記事です。これにより、以降に記述されたテスト内で、このインスタンス変数を使用する事が出来るようになります。次に、テストを追加しています。

test "title should be present" do
    assert_not @article.save
end

テストを書くときは「test "テストの内容" do」という形で書き始め、このブロック内に期待する動作を記述します。今回の場合は、タイトルには値が含まれている必要があるという内容のテストです。

期待する動作の部分には、@articleは保存できない(有効なレコードではない為)と記述しています。つまり、@articleが無効なレコードだと判断され保存に失敗すれば成功というテストになっています。

この「assert_not」という部分はアサ―ションと呼ばれるものです。アサ―ションとは、記述された条件から結果を判断する為のものです。アサ―ションには様々な種類があり、ここでは「条件が偽であれば成功」という意味の「assert_not」を使用しています。

では、このテストを実行してみましょう。以下を参考にターミナルでテストを実行してください。

ここで、実行しているコマンドはモデルのテストのみを行う為のコマンドです。「:models」を省略すると、テスト全てを実行します。次に、テストの結果部分です。まず、テストに失敗した場合は赤文字で内容が表示されます。この赤文字部分の「F」は「Failure(テストの失敗)」という意味です。

そして、失敗したテスト名とそのテストが記述されている場所が表示されています。更に「Expected true to be nil or false」では、条件判断の結果は偽であることが期待される、と失敗した理由が表示されています。

このテストを行ったことで、現状のアプリの状態では、期待する動作が行われないことが分かりました。空の記事が投稿出来てしまうという事です。では、このテストが成功するように、モデルにバリデーションを追加しましょう。

これは、タイトルに値があれば有効なレコードと判断するという意味です。値がなければ無効なレコードと判断されます。では、テストをもう1度実行してみます。

この緑色の点は、テストの成功を意味します。先ほど、テストが失敗した際には最後の行で「1 failures」となっていました。しかし、テストは成功したので「0 failures」となっていますね。

文字列の長さのテスト

では、もう一つテストを追加してみましょう。今度は、文字列の長さをテストします。現時点のアプリの状態では、タイトル・本文ともに文字数制限がありません。

あまり長いタイトルで投稿されてしまうのはよくありません。ですので、タイトルに文字数制限を設けることとします。まず、文字数制限がかかっていないことを確認してみます。

まず、setup内で定義したタイトルが空の記事のタイトルを変更します。「sample text」という文字列 × 1000と指定しています。とても長い文字列ですので、このようなタイトルのまま投稿出来てしまうと問題ですね。では、テストを実行してみます。

まず、「.F」の部分です。これは、実行したテストの数だけ「.」か「F」が表示されます。今、Articleモデルのテストファイルには2つのテストが書かれています。

その内、成功したのは空タイトルのテストです。失敗したのが、文字列の長さのテストです。つまり、とても長い文字列のタイトルであっても保存できてしまうという事です。

では、モデルにタイトルの長さのバリデーションを追加します。今回は、30文字以内という定義にします。以下を参考に、バリデーションの追加を行ってください。

これで、30字以上のタイトルでは投稿する事が出来なくなったはずです。もう1度、テストを実行してみます。

テストは成功です。これで、タイトルは1文字以上30文字以下の文字列でないと投稿できないようになりました。

Commentモデル

では次に、記事にコメントを付けられる機能を追加する為、Commentモデルを作成します。そして、Commentモデルに対するテストも行います。まずは、モデルを生成しましょう。

Commentモデル用の、テストファイルなども生成されていますね。では次に、ArticleとCommentモデルの関連付けについての記述を追加します。

Commentモデルには、先ほどのコマンド実行時に「article:references」としたので、すでに「belongs_to:article」という記述はされています。ですので、以下のように「article.rb」の編集を行ってください。そして、ルーティングも設定しておきます。

次に、データベースの構成を行いましょう。そして、これまでに作成したArticleの為のテストには影響がないことを確認します。

そして、バリデーションを指定します。今回は、本文とコメンターともに、空ではいけないと定めます。

では、テストを書きましょう。フィクスチャも使用します。テスト内容は、本文とコメンターともに空のコメントを作成しようとしても、無効なレコードだと判断されて、保存に失敗するはずだというテストです。

では、テストを実行します。

テストは成功です。また、テストファイル・テストの実行により、この制約がきちんと効いている事が保証されている状態です。

そして、このテストファイルを見れば、アプリの仕様が理解しやすいでしょう。チームで作業している場合や、複雑な構造のアプリを制作している場合にはとても便利ですね。

まとめ

ユニットテストとは、モデルの為のテストの事です。ユニットテストでは主に、データベース関連のテストを行います。

モデルの作成時、テストの為のファイルも一緒に作成されます。モデルのテスト用ファイルは、モデルごとに作成されます。

「setup」というメソッドはテストの実行前に行っておきたい処理がある場合に使用するメソッドです。テストに失敗した場合は赤文字で内容が表示されます。

無料ビデオ講座のお知らせ

Skillhub [スキルハブ]では無料の動画講座を多数公開しています。他校だと数万円するような講座が無料で受講できます。

無料講座一覧を見る

×