suzy1031 / everyday-study-app

0 stars 0 forks source link

RSpecテスト #10

Open suzy1031 opened 3 years ago

suzy1031 commented 3 years ago

Rspecテスト項目

modelテスト

study

user

controllerテスト

users_contoller

sessions_controller

refresh_controller

studies_controller

goals_controller

routingテスト

study

goal

systemテスト(system/studies_spec.rb)

参考 FactoryBotとRSpecでAPIテスト APIテスト(create_list) modelテスト RSpec導入 RSpecでAPIテスト(include()でエラーになった)

suzy1031 commented 3 years ago

参考 type matcher

suzy1031 commented 3 years ago

参考 bad request書き方

suzy1031 commented 3 years ago

特定のファイルのみテスト実行する

bundle exec rspec spec/features/studies_spec.rb
suzy1031 commented 3 years ago

$ bundle exec rspec spec/features/studies_spec.rbエラー

NameError:
  uninitialized constant Rails
# ./spec/spec_helper.rb:1:in `require'
# ./spec/spec_helper.rb:1:in `<top (required)>'
No examples found.
An error occurred while loading spec_helper.
Failure/Error: require 'capybara/rails'

原因capybaraのセットアップができていない

gem capybara追加

group :development, :test do
+gem 'capybara'
end
$ bundle install
# rails_helper
require 'rspec/rails'
+require 'capybara/rspec'
Faker::Config.locale = :ja
suzy1031 commented 3 years ago

js: :trueを追加したらエラー

LoadError:
Capybara's selenium driver is unable to load `selenium-webdriver`, please install the gem and add `gem 'selenium-webdriver'` to your Gemfile if you are using bundler.
group :development, :test do
+gem 'selenium-webdriver'
end
Selenium::WebDriver::Error::WebDriverError:
Could not find Firefox binary (os=macosx). Make sure Firefox is installed or set the path manually with Selenium::WebDriver::Firefox::Binary.path=

firefoxインストール(homebrew cask経由)

$ brew cask install --appdir="/Applications" firefox
Updating Homebrew...
firefox was successfully installed!

rspec実行したら次のエラー

Selenium::WebDriver::Error::WebDriverError:
       Unable to find Mozilla geckodriver. Please download the server from
       https://github.com/mozilla/geckodriver/releases and place it somewhere on your PATH.
       More info at https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver.

時間かかりそうなので、一旦selenium-webdriver使わないでやってみる

RSpecのsystem testで実行してみる

参考 RSpecでCould not find Firefox binary (os=macosx)というエラーが発生した件 rspec-rails 3.7の新機能!System Specを使ってみた

suzy1031 commented 3 years ago

vue.jsでcapybara使ったfeatureテストするには? rails(erb)と同じ方法でやっても要素が表示(取得)されていない?

Failure/Error: select '0:30', from: 'text' # セレクトボックス

Capybara::ElementNotFound:
Unable to find select box "text"

issue

suzy1031 commented 3 years ago

featureテストではなくsystemテストを使う? vueの場合仮想DOMを使っている為、html(erb)同様のテストではダメかも…jsを動かす必要がありそう。 rspec-rails 3.7の新機能!System Specを使ってみた

suzy1031 commented 3 years ago

rspecでsystem testを行う準備

brew install chromedriver
chromedriver was successfully installed!

gem最新化

bundle update rspec-rails capybara selenium-webdriver

rspec実行

bundle exec rspec spec/system/studies_spec.rb

“chromedriver”は、開発元を検証できないため開けません。 キャンセル押下 設定 > セキュリティとプライバシー > 一般 > このまま許可

再実行

bundle exec rspec spec/system/studies_spec.rb
ポップアップ表示 > 開く
実行できた

参考

suzy1031 commented 3 years ago

v-selectをRSpecでテストする <select></select>タグを使っていないので、他の要素(class)で指定しないとエラーになる

Capybara::ElementNotFound:
Unable to find select box "study-select" that is not disabled and Unable to find input box with datalist completion "study-select" that is not disabled
↓
page.find('div.v-select').click

vue-selectのoption部分の指定方法

page.find('ul.vs__dropdown-menu', text: '0:30').click

参考

suzy1031 commented 3 years ago

studies_controller.rbのパスを元に戻す 該当vueファイルのソースも修正する ↓ studies_contollerのロジックが変わったので、テストの書き直しする

suzy1031 commented 3 years ago

rspecテストの書き方

describe ' '(シングルコート)や、
describe " "(ダブルコート)は不要

api/users_controller.rbのテストを書く時は、

RSpec.describe Api::UsersController type: :controller do
// テスト内容
end

# ×UsersContoller
# ○Api::UsersController
=> NameErrorになる
suzy1031 commented 3 years ago

user modelテスト valdationが有効か確認

expect(FactoryBot(:モデル名, カラム名: ' ')).to_not be_valid

参考 RailsでのRSpecの設定やら書き方とかいろいろ

suzy1031 commented 3 years ago

describe, context, itの使い方

describe => 大ブロック. 大きく分けてどのアクションのテストをしているかを記載する ex)describe 'GET #index' do ~ end => getメソッドのindexアクションのテスト

'context' => 中ブロック. どのアクション内で正常系テスト異常系テストかを記載する ex)context 'with valid params' do ~ end => 正常系処理のテスト

'it' => 小ブロック. そのテストで何をテストしているのかを記載する ex)it 'returns a success response' do ~ end => 正しいレスポンスが返ってくるテスト

suzy1031 commented 3 years ago

認証の仕組みについて勉強

suzy1031 commented 3 years ago

capybara使い方 github 使えるRSpec入門・その4「どんなブラウザ操作も自由自在!逆引きCapybara大辞典」

suzy1031 commented 3 years ago

model specのassociationの使い方

FactoryBotを使う

# spec/factories/goals.rb
FactoryBot.define do
factory :goal do
+association :user
target_time { "10" }
end
end

# spec/models/goals.rb
describe ' 'do
+let(:goal) { FactoryBot.create(:goal) }
context ' ' do
it ' ' do
+goal.valid?
+expect(goal).to be_valid
end
end
end

factoryBotを使わない方法でテストデータを作成する方法

# spec/models/goals.rb
RSpec.describe Goal, type: :model do
  let(:user) { FactoryBot.create(:user) }
  let(:Goal) { FactoryBot.create(:Goal, user_id: user.id) }
end

参考 【FactoryBot】associationの使い方

suzy1031 commented 3 years ago

changeマッチャの使い方

データ変更を検証するchange

expect/change句にブロック({})を渡している部分に注意

# blockを渡していない場合エラー
Failure/Error: expect(goal).to change{ Goal.count }.by(1)
expected `Goal.count` to have changed by 1, but was not given a block
# spec/models/goals.rb
+it 'create data' do
+user = User.create(email: 'test@test.com', password: 'password')
+user.goals.create(target_time: '10')
+expect{ goal }.to change{ Goal.count }.by(1)
+end

参考 Rspec入門。Rspecのマッチャ、to, eq, be, be_truthy/falsey,change

suzy1031 commented 3 years ago

JWTを利用した認証でpost・updateのテストを実行する際

request.cookies[JWTSessions.access_cookie] = @tokens[:access]
request.headers[JWTSessions.csrf_header] = @tokens[:csrf]

必ずクッキーとcsrfをトークンに含めて一緒にリクエストを投げてあげないと認証されずにエラーが返ってくる

#updateエラー
Failure/Error: expect(goal.target_time).to eq new_params[:target_time]

       expected: 12.0
            got: 10.0

       (compared using ==)
# レスポンスエラー
Failure/Error: expect(response).to have_http_status(:ok)
       expected the response to have status code :ok (200) but it was :internal_server_error (500)