プログラミング未経験おじさんの備忘録

本ブログはプログラミング未経験者の拙い学習の記録です。

学習[77]日目

本日の学習内容

 

テストとは?

プログラムが意図した通りに動くことを確かめることです。

railsnにおけるテストとは基本的にはモデルとコントローラのファイルに対してテストコードを作成します。その際はRSpecという独自の言語を利用します。

RSpecは、Rubyを元に作成されたテストに特化した言語です。 「rspec-rails」というGemをインストールすると、RSpecを利用できます。

テストコード無しで実装した場合、つまりプログラムが意図した通りに動くことを確かめずに記述していったコードには、思いもよらない原因で発生するバグが潜んでいる可能性があります。テストは、こういった事態を防ぐために必要です。
あらゆるケースを想定し、「バグがないことを確かめてから」本番に適用するようにするのがテストコードを書く意義です。

基本的に、ひとつのプロダクションコードに対してはひとつのテストコードが必要です。
例えばRuby on Railsにおいては、モデルクラスやコントローラークラスひとつにつきひとつのテストコードを書かなければいけません。

テストを書くメリット

 

仕様漏れを減らすことができる

テストをするにあたっては、対象のメソッドがどのような目的で作成されどんな挙動をしなければいけないのかということを全て洗い出します。結果的に仕様を良く確認することになり、バグを引き起こす仕様漏れを少なくすることができます。

リファクタリングや機能追加をしやすくなる

リファクタリングとは、コードをより綺麗なかたちに修正する作業のことです。一度テストを通過してしまえば、最終的な結果を維持しリファクタリングをするのが簡単になります。また、新たな機能を追加する際も、従来の箇所は間違いなく動いていることを確認できているので、その結果を崩さないようにするだけで安全に実装することができます。

楽しくコードを書ける

テストを通過するという快適な体験を重ねることで、コードを書く作業が楽しくなります。注意力が必要で神経をすり減らしやすいプログラミングという作業において、楽しくコードが書ける、ということは非常に重要です。

テストコードを書く際の心がけとしては、スピードは求めないことやDRYを意識し過ぎないことです。

テストの種類について

テストは、主に単体テストと統合テストという2種類に分類されます。単体テストとは、単体で動くプログラムが正常に動作するか確かめるテストのことです。統合テストとは、複数のプログラムが組み合わさった機能が正常に動作するか確かめるテストのことです。

また、テストを行うにあたって便利なジェムがあるので下記に記載します。

RspecRailsテスト駆動開発で使われてきたTest::Unitを代替するフレームワーク

#rspec導入
rails g rspec: install
#.rspecに --format documentationを記述すると表示を綺麗にしてくれる

factorybot:テストデータの作成を行う

faker:ダミーデータを生成する

#以下のように記述することでfactorybotをインスタンス生成時に記述を省略出来る
#また、fakerを使用する為には以下のように記述するが、様々なメソッドを用意されている
FactoryBot.define do
  factory :user do
    password = Faker::Internet.password(min_length: 8)
    name {Faker::Name.last_name}
    email {Faker::Internet.free_email}
    password {password}
  end
end
 
#通常のインスタンス生成
user = User.new(nickname: "aaa"email: "aaa@aaa"password: "00000000")
#factorybotで作成する場合(createはデータベースにデータを保存するがbuildは一時的に作成する違いがある)
Factorybot.build(:user)
#factorybotで作成する場合(factorybotの記述省略)
 この場合には、rails_helper.rbに特定の記述をすることで省略可能
build(:user)
単体テスト

ひとつのプログラムのまとまりに関して、それ単体が正常に動くか確かめるテストのことです。Railsであれば、モデルクラスひとつ、コントローラークラスひとつにつきそれぞれテストコードを書きます。下記がその一つの例です。

 

require 'rails_helper'
describe User do
  describe '#create' do
    it "is invalid without a email" do
     user = User.new(nickname: "aaa"email: ""password: "00000000"
             , password_confirmation: "00000000")
     user.valid?
     expect(user.errors[:email]).to include("can't be blank")
    end
  end
end

1行目のrequire 'rails_helper'は、rails_helper.rb内の記述を読み込むことで共通の設定を有効にしています。この1行目の記述は、全てのspecファイルに書き込みます。

3, 4行目に連続してdescribeが登場しています。describeは、ネストにすることができます。この場合には、Userクラスにあるcreateメソッドをテストするまとまりであることを示しています。(describeとdoの間にメソッド名を書く際は#をつける)

5行目は「emailが空である場合登録できないこと」を確かめるテストコードを作成したいのでemailの値を空にし、それ以外は適当な値をセットした状態でuserクラスのインスタンスを作成しています。

6行目では新規作成したuserクラスのインスタンスがバリデーションに引っかかるかどうかを確かめるvalid?メソッドを利用します。

errorsではvalidによってtrueを返した場合にどうして生じたかを確認可能

また、上記の記述に関しては、以下の項目から成り立っています。

describe:do ~ endまでのテストのまとまりのことです。

it:exampleと呼ばれる実際に動作するテストコードのまとまりのことです。

 

expect(X).to マッチャ Y:エクスペクテーションと呼ばれる実際に評価される式です。

マッチャ:エクスペクテーションの中で、テストが成功する条件のことです。

 

統合テスト

複数のプログラムが連動して行われる処理が意図した通りに行われるかを確かめるテストのことです。Railsであれば、ユーザーの新規登録における一連の処理をテストすることが考えられます。ユーザーの新規登録用画面から値を入力、送信して、データベースにレコードが追加されるまでの一連の流れをシミュレートするテストコードを書きます。Rspecを用いて統合テストを書く手段として、フィーチャスペックを利用できます。

フィーチャスペックは、Rspecを使って統合テストを行うためのスペックです。テスト環境用の仮装ブラウザを操作して、「特定のa要素をクリックする」「ボタンと対応するコントローラのアクションが動く」といった複雑なテストを書くことができます。アプリケーションの肝となる動作を総合的にテストしたい場合に用いられます。

フィーチャスペックを書くためにCapybaraというgemを導入して、フィーチャスペックを書いていきます。

Capybaraは、ブラウザの操作を再現するのに必要なgemです。特定の要素をクリックしたり、フォームに値を入力したり、特定の要素が画面に表示されているかなど、様々なブラウザ上の動きをテストすることができます。Capybaraを導入すると、テストを記述するためのヘルパーメソッドが複数追加され、これらを活用してフィーチャスペックを記述していくことになります。

また、フィーチャスペックでは、単体テストとは異なる記述を行います。

例)

it→scenario before→background describe→feature let→given

 

調べた英語

fixtures:設備

replacement:交代

straightforward: わかりやすい

inheritance:継承

transitioning:変遷

alias:別名、通称

populate:(データを)入れる

usage:慣例

typo:打ち間違え

 

実際に記述と試行を繰り返さないとなれないと感じました。

以降、練習も実施していきたいと思います。

 

参照:https://qiita.com/jnchito/items/42193d066bd61c740612#subject-%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%86%E3%82%B9%E3%83%88%E5%AF%BE%E8%B1%A1%E3%81%AE%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%921%E7%AE%87%E6%89%80%E3%81%AB%E3%81%BE%E3%81%A8%E3%82%81%E3%82%8B

  :https://qiita.com/jnchito/items/cdd9eef2ed193267c651

  :https://blog.naichilab.com/entry/2016/01/19/011514

  :https://kossy-web-engineer.hatenablog.com/entry/2018/11/30/083719

  :https://github.com/faker-ruby/faker