見出し画像

[output]Rspec結合テスト

●System Spec

結合テストは、System Specを用いて記述する。
記述には、カピバラというGemが必要だが、Railsが標準搭載している。

#Gemfile
group :test do
 略
 gem 'capybara', '>= 2.15'end``

そのため、導入処理不要。

ファイル生成は、bundle exec rspec:systemコマンドを実行する。
生成するファイル名の指定は、複数形で行う。

結合テストは、ユーザーの操作を再現しながら
想定した結果になるか検証していく。

「クリックしたら」、「カーソルをあわせたら」など、
ユーザー操作を再現するメソッドを用いてコードを記述する。

以下に単体テストで使用したメソッドと、結合テストで主に使用するメソッドを表にする。

スクリーンショット 2021-08-16 19.03.58

●それぞれのメソッドの紹介。(system)

・visit

指定したパスに遷移できる。
パスはprefixでもURIでも可。

visit '/'        #URI
visit root_path  #prefix

・fill_in

指定したフォームに、入力ができる。
ブラウザ上での入力を再現するのに使用する。

#構文
fill_in '入力したいフォーム',with: '入力したい文字'
#具体例
fill_in 'Nickname', with: @user.nickname

フォームの指定は、ラベルテキストの他、id・name属性値でも指定可能。(HTMLの記述を指定)

実際の動作確認 ↓

#name属性値ver /  name="user[nickname]"より、
[13] pry(#<RSpec::ExampleGroups::Users::Nested>)> fill_in 'user[nickname]', with: @user.nickname
=> #<Capybara::Node::Element tag="input" path="/HTML/BODY[1]/DIV[1]/DIV[1]/FORM[1]/DIV[1]/INPUT[1]">

#id属性値ver /  id = "user_nickname"より、
[14] pry(#<RSpec::ExampleGroups::Users::Nested>)> fill_in 'user_nickname', with: @user.nickname
=> #<Capybara::Node::Element tag="input" path="/HTML/BODY[1]/DIV[1]/DIV[1]/FORM[1]/DIV[1]/INPUT[1]">

#labelのテキストver /  Nicknameより、
[15] pry(#<RSpec::ExampleGroups::Users::Nested>)> fill_in 'Nickname', with: @user.nickname
=> #<Capybara::Node::Element tag="input" path="/HTML/BODY[1]/DIV[1]/DIV[1]/FORM[1]/DIV[1]/INPUT[1]">``

ちなみに、これらフォーム指定の記述は、ブラウザの検証ツールで確認できる。

ちなみにラベルテキストに関しては、
labelタグとinputタグが紐付けられている場合に使用可能。
紐付けられている条件とは、labelのfor属性値とinputのid属性値が一致すること。

・have_(no_)content

ページに、指定の文字列が含まれているか(いないか)確認するマッチャ。
コントローラー使用したincludeと似ているが、

includeはresponseに対して、
have_contentはpageに対して機能する。

expect(page).to have_content('あいうえお')     #あいうえおが含まれるならtrue
expect(page).to have_no_content('あいうえお')  #あいうえおが含まれていないならtrue

・change

主にモデルのカウント数の変化を確認するマッチャ。
chageを使う際は、expectもchangeの引数も()でなく{}で指定する。
changeの引数については、

モデル名.countで、モデル名のレコード変化の数を返す。

続けてbyやfrom&toなどのメソッドをつなげて
想定した変化数か確認する。

#構文
change{Model.count}.by(num)
#具体例
change{User.count}.by(1) #Userモデルのカウントが1増えたか
change{User.count}.by(-1) #Userモデルのカウントが1減ったか
change{User.count}.by(0) #Userモデルのカウントが変化ないか

・by

eqと同じような機能。
includeとhave_contentのように、相手によって使わい分けるイメージ。

・hover

指定した要素にカーソルを合わせたときの動作を再現する。
また、そのときの情報も取得する。
指定する要素は、findを使用して指定。

find('.submit').hover #submitクラスの要素にカーソルをあわせたら

・click

引数に指定した要素をクリックできる。こちらも指定する要素は、findを使用して指定。

find('input[name="aiueo"]').click #nameがaiueoのインプットタグをクリック

・find

引数に指定された要素を返す。
指定には、cssのセレクタの記述を指定する。
1つに特定できないとエラーが生じる。
そのため、findを連結して使用することも可能。

#構文
find('セレクタ')
#例文
find('.nav').find('span')    #クラスセレクタ、spanセレクタで指定
find('input[name="aiueo"]')  #inputセレクタ&name属性(HTML)で指定

・current_path

現在のページのパスを返す。

・page

遷移したページの可視部の情報が格納される。
可視部とは、カーソルを合わせて初めて見えるものは含まれない、という意味。