LoginSignup
0
0

More than 5 years have passed since last update.

Todo アプリ作成 〜テスト編〜 RSpec で e2e テスト リベンジマッチ

Last updated at Posted at 2019-03-03

はじめに

前提
seed データを投入し /tasks にアクセスしたら seed データが表示されている状態

前回 のあらすじ
1. 景気良く RSpec をインストールし、テストファイルを作成する
2. controller の機能テストを行いたく spec/controller/ 配下にテストファイルを移動
3. 紆余曲折し、capybara の存在を知る
4. エラーにより利用出来ず capybara から手を引く
Bad End

前回やりたかったこと

  • / (ルートページ) にアクセスし、同じく seed データ一覧を表示
  • /tasks にアクセスし、 seed データ一覧を表示

対象ページのキャプチャ
image.png

今回はそれのリベンジマッチです。

困り果てていたら、ヒントをいくつか頂きました。

ヒントを元にこの記事を書きながら強くなっていこうと思います

それでは、はじまりはじまり

1. 準備

capybara さんとお別れをします。
さっぱり綺麗に忘れることが出来ないので、

$ git commit -m 'bad end by capybara'  

capybara との思い出に『名前をつけて保存する』をする。

そして

spec/spec_helper.rb
- #require 'capybara/rails'
- #require 'capybara/rspec'
require 'rails_helper'

これだけにする
あいつの顔はしばらく見たくないです...

2. Who is SystemSpec ?

あしたのために(その1) : SystemSpec を知るべし

まずこの人は誰で何ができるのでしょうか

2.1 再会は突然に

公式 を見つけれました

ん?
image.png
visit "hoge" ????
おいおいおいおい ま 待ってくれ!!!
こいつ、、こいつ capybara じゃねえかよ!!!

知ってます!私こいつ知ってますよ!
トラウマ(僕のQiita記事)トラウマ(公式)

なんてこった、前回どん詰まりした visit method を使うなんて...

💡(・□・;)ハッ!
いや待てよ、 、、
もしかして、 System Spec を使えば capybara とやり直せる?

そうとわかれば話が早い
使いましょう使いましょうすぐ使いましょう

2.2 How to use System Spec

いくつかルールがあるみたいでした
1. describe に :type => :system と記載すべし
2. spec/system/ に配置すべし
3. before に driven_by(:rack_test) を記載すべし

あれ?なんか デジャブ
ルールの1と2って被ってないか?そんな予感がする
よし、ルール1を無視してみよう

2.3 Let's try

Before

spec/controllers/index_page_spec.rb
RSpec.describe TasksController do
  render_views

  before do
    `rails db:reset RAILS_ENV=test`
  end

  context 'show index' do
    it 'show task list on index page' do
      get :index
      expect(response).to render_template('index')
      expect(response.body).to include 'task 001 : hogehoge'
    end
  end
end

After

spec/system/index_page_spec.rb
RSpec.describe TasksController do
  before do
    driven_by(:rack_test)
    `rails db:reset RAILS_ENV=test`
  end

  context 'show index' do
    it 'show tasks list on index page' do
      visit '/tasks'

      assert_selector 'h1', text: 'Your Tasks'
      assert_text 'task 001 : hogehoge'
    end
  end
end

テストの書き方は System Spec の公式様が

system tests.
We encourage you to familiarize yourself with their documentation.
(うるせえこれ読んどけ)

と仰ったので、読んでみたら書いてありました
ちなみに 日本語版 もあるみたい

result
Finished in 8.1 seconds (files took 8.62 seconds to load)
1 example, 0 failures

わ、動いた。
しかも成功した....成功した!!!!

成功した!!!(大興奮)

大歓喜すぎて実験結果の記載を忘れるところでした

System Spec を使うとき、
spec/system/ 以下にある xxx_spec.rb ファイルには
:type => :system の記載は不要である!!!

勉強になりました。
それと type と ディレクトリとディレクトリ名は深い繋がりがありそうです

あしたのために(その2) : 単語の意味を覚えよ

そういうこと????
いや、多分これだけじゃないな

2.4 テストを1つ完成させよう

spec/system/index_page_spec.rb
it 'show tasks list on index page' do
  visit '/tasks'

  assert_selector 'h1', text: 'Your Tasks'
  assert_text 'task 001 : hogehoge'
  assert_text 'task 002 : fugafuga'
  assert_text 'task 003 : piyopiyo'
end

なめてんのか、とどこからか声が聞こえます。
わかってます。

assert_text 'task 002 : fugafuga'
assert_text 'task 003 : piyopiyo'

この辺でしょ?
なんとかしますよ。。。いつか

まあ何はともあれ

rspec
# bundle exec rspec
.

Finished in 8.47 seconds (files took 6.81 seconds to load)
1 example, 0 failures

WRYYYYYYY!!!!

2.5 景気良くきましょう!2つ目も終わらせる

spec/system/index_page_spec.rb
RSpec.describe TasksController do
  before do
    driven_by(:rack_test)
    `rails db:reset RAILS_ENV=test`
  end

  context 'show index' do
    it 'show tasks list on index page' do
      visit '/tasks'

      assert_selector 'h1', text: 'Your Tasks'
      assert_text 'task 001 : hogehoge'
      assert_text 'task 002 : fugafuga'
      assert_text 'task 003 : piyopiyo'
    end

    it 'show tasks list on root page' do
      visit '/'

      assert_selector 'h1', text: 'Your Tasks'
      assert_text 'task 001 : hogehoge'
      assert_text 'task 002 : fugafuga'
      assert_text 'task 003 : piyopiyo'
    end
  end
end
rspec
# bundle exec rspec                               
..

Finished in 17.47 seconds (files took 5.91 seconds to load)
2 examples, 0 failures

WRYYYYYYYーーーーッ!!!!!!!!

$ git commit -m 'happy end by system spec'

ところで、僕はなんで capybara が使えるようになっていたんでしょうか。。。
調べるものとして残しておく必要がありそうです。

3. テストデータの初期化

あしたのために(その3) : テストの度にDBの中身をリセットせよ

これは、毎回テストデータをリセットしないと、前提条件が一致しないからだそうです。
そりゃそうですよね、前回のテストデータが前提条件とかになったら、そのテスト単体で出来ないし
前提条件が必要ならテストの外で書かないといけないですよね。

それでは RSpec でのテストデータの中身の消し方を調べましょう

3.1 DatabaseCreaner とはなんぞや

あしたのために(その3)には続きが

あしたのために(その3) :
テストの度にDBの中身をリセットせよ
ただしRails 5.1 以降では DatabaseCreaner は不要

念の為、確認

web
# rails -v
Rails 5.2.2

5.1 以降ですね

要らない=知らないでよい
にはならないので、
不要なら不要になった理由を知る必要がありますね

DatabaseCreaner 公式

Database Cleaner is a set of strategies for cleaning your database in Ruby.
(db を綺麗にするぜ)

名前の通りの人でした

3.2 DatabaseCreaner は要らない子?

書いてあることはめちゃくちゃ あしたのための(その3) の要件をクリアしてそうなんですけどね、
標準装備されたとかかな?

RSpec 3.7 has been released! ー 日本語訳

Feature Spec では、JavaScript が有効な Capybara ドライバー(Selenium や Poltergeist)を使った場合、 テストは Rails とは別のプロセスで実行されます。 その結果、テストプロセスと Rails プロセス間でデータベースのトランザクションが共有されないため、 RSpec 標準のデータベースロールバック機構を利用できず、 代わりに Database Cleaner のような gem を使う必要がありました。 Rails 開発チームは System Test でこのような問題が発生しないように実装をしました。 そのおかげで、System Spec では別の gem を利用することなく RSpec のロールバック機構を利用できます。

この人たちが頑張ったおかげで、要らなくなったってこと?

へ〜、で?

3.3 db:reset はだめ?

そもそも、

 before do
    driven_by(:rack_test)
    `rails db:reset RAILS_ENV=test`
  end

rails db:reset で初期化されているのではなかろうか

これまでなんどもテストを実行してきた、ここでテスト環境の html をみてみる

byebug
(byebug) puts page.html
<!DOCTYPE html>
<html>
  <head>
    <title>Myapp</title>



    <link rel="stylesheet" media="all" href="/assets/application-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css" data-turbolinks-track="reload" />
    <script src="/assets/application-3c2e77f06bf9a01c87fc8ca44294f3d3879d89483d83b66a13a89fc07412dd59.js" data-turbolinks-track="reload"></script>
  </head>

  <body>
    <h1>Your Tasks</h1>

<ul>
  <li>task 001 : hogehoge</li>
  <li>task 002 : fugafuga</li>
  <li>task 003 : piyopiyo</li>
</ul>

  </body>
</html>

なんかちゃんと都度 reset が効いていそうに見える

終わり?

4. 完了...?

e2e テストが完了しました。

# bundle exec rspec
..

Finished in 13.11 seconds (files took 6.26 seconds to load)
2 examples, 0 failures

思ったのは、テストデータに seed を使うのは普通じゃないのかもしれない。
テストデータはテストデータで作成してするのが普通なのかもしれない。

task = Task.create(...) とかで作ったら
save されたデータを削除しないといけない
= テストデータの中身をリセットする(昔はこれに DatabaseCreaner を使っていた?)
につながるのではないだろうか

今はすごいシンプルな形だから seed データで事足りてるけど
今後は、上記のようなケースにぶち当たりそうな気配を感じます。

あってるっぽい?
RSpecでテストDBに突っ込んだデータを消したい

宿題

ちょっと理解するのをスキップしたものリスト

  • なんで System Spec の設定をしていたら、いつの間にか capybara が使えるようになっていたのか
  • driven_by(:rack_test)」 これは何か
  • テストコードの assert_text '..' のあたりは、同じことを繰り返し行なっているので、うまいことやりたい
  • あしたのために(その2、3) を深める

あしたのために

あしたのために(その1) : SystemSpec を知るべし
あしたのために(その2) : 単語の意味を覚えよ
あしたのために(その3) : テストの度にDBの中身をリセットせよ

ありがとうございました!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0