2か月くらい前にSelenium + Capybara + RSpecで自動テストしてみる : 準備編という記事を書いたんですけど、そいつのMinitestバージョンな感じ。

まず、前述の記事の続きですが見て解る通り書いてないです。いちおう、この後結構いろいろやったのはやったんですが、たぶん、今後も書かないと思います。というのも、RSpecだとどうも思ったようにテストが書けませんでした。これはRSpecどころかRubyもよくわかってないのが一因にあると思うんですけど、どうもRSpecだとクラスを作るっていうのができない(?)っぽくて、その結果テストコードが重複しまくるんですよ。DRY原則に反してしまう…

あとは、そもそもRSpecの書き方が超独自でもう一つ新しい言語を勉強しているというか、ただでさえRubyもやったことねえのに…みたいな感じで、前述の記事の後にもページオブジェクトパターンにのっとってクラス作りまくったり(こっちはRubyでですが)したんですけど、テストコードの重複はどうやっても回避できそうになかったのでやめました…

じゃあどうすんねん??ですけど、Minitestではじめてみました。っつてもMinitestでも前述の問題が回避できるかどうかは解りませんけど、たぶんできそうな気がしてます。また、Minitestを選ぶまでの過程でCucumberとかturnipも検討したんですけども、この辺もRSpecが前提(???)っぽかったのでやめました。後は、MinitestがRubyの標準テストフレームワークらしいので、そういったあたりもMinitestを選んだ理由の一つです。

ま~なんかダラダラ書いてますが、私RSpecわかんないですし、そもそもE2Eテストどころかテスト周りよくわかってないですし、Minitestもまだ数日使った程度なんで大いに間違ってるような気がしますので、あんまり鵜呑みにしないでね。

また、今回のコードはここにあげてます

前書きが長くなったけど、以下やり方。

環境


以下でやってます。この辺はこの記事に書いてます

  • Ruby 2.3
  • Windows10
  • Selenium 3.0.1
  • ブラウザ Chrome

Gemfile


こんな感じで書きます。いらんのが入ってるかもしれん。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
source 'https://rubygems.org'

source 'http://production.cf.rubygems.org' do
gem "capybara", "2.10.1"
gem "selenium-webdriver", "3.0.1"
end

gem "ruby-debug-ide"
gem "minitest"
gem "minitest-capybara"
gem "minitest-doc_reporter"
gem "minitest-stub_any_instance"
gem "minitest-bang"
gem "minitest-line"

ちなみに、Selenium + Capybara + Minitestで調べると大体Railsがらみの記事ばっかり引っかかるのですが、弊社システムはRubyでもRailsでもないのです。minitest-capybara-rspecのgemを使うみたいな記事しか出てきませんがminitest-capybaraのgemがあります。

ドキュメントなどは下記参照。

https://github.com/wojtekmach/minitest-capybara
https://www.ruby-toolbox.com/projects/minitest-capybara
http://www.rubydoc.info/gems/minitest-capybara/0.8.2

インストール


bundlerがインストールされていない場合は下記のコマンドでインストールします。

1
gem install bundler

そのあと、Gemfileに記述したgemをインストールします。

1
bundle install

test_helper.rbの作成


testディレクトリみたいなのを作ってその中にtest_helper.rbというファイルを作成して下記のように書きます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# coding: utf-8
require 'rubygems'
require 'minitest/autorun'
require 'selenium-webdriver'
require 'minitest-capybara'

Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end

Capybara.configure do |config|
config.run_server = false
config.default_driver = :selenium
config.default_wait_time = 8
config.app_host = 'https://www.google.co.jp/'
end

今回はGoogleでこのサイトを検索してみるというためにconfig.app_hosthttps://www.google.co.jp/って書いてます。

テストコードを書いてみる


Google検索でこのサイトの名前で検索してその結果にhttps://yoshinorin.net/の文字が含まれているかどうか。
というあんまり意味がなさそうなテストをしてみます。

testディレクトリ内にfeaturesディレクトリを作成して、その中にsearch_myblog.rbというファイルを作成して以下を記述します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# coding: utf-8
require '../test_helper'

class SearchTest < Minitest::Capybara::Test

def test_search_myblog
visit "/"
find_by_id('lst-ib').send_keys('YoshinoriN in Hexo')
find_by_id('lst-ib').native.send_keys(:return)
assert_content "https://yoshinorin.net/"

sleep 5
end
end

実行


下記のコマンドでテスト実行します。

1
ディレクトリ\test\fixtures>ruby search_myblog.rb

下記のような結果が表示されると思います。

1
2
3
4
5
6
SearchTest
myblog


1 tests run in 11.301024 seconds.
Errors: 0 | Failures: 0 | Skips: 0

今回やってる設定だと成功の場合は何も表示されないんですが、失敗の場合はちゃんと失敗と表示されるので成功していると判断できます。
テスト結果の表示設定は下記を参考にしました。

minitestのオススメ基本設定調べてみた

その他


まあ、とにかく情報がないですね…RSpecの時もそんなにないな~と思ったんですけど、それ以上にないです。Ruby界隈の人ってTDDでバリバリテストコード書いて…見たいなイメージがあったんですけど、E2Eテストはそこまでやんないのでしょうか…?
後は、RSpecの時に作成したページオブジェクトパターンの各ページのクラスは使いまわせるので、それぞれのメソッドに合わせたテストコードをごちゃごちゃ書いて、テストパターンに応じて順番に呼び出せたら一応、思ってるものはできるんじゃないかな?と思ってます。(※ちなみに前述のコードはページオブジェクトパターンでもなんでもないです)

弊社事情ですが、そもそもRubyでやる必要があるのかどうか…なんですけど、ほら、もともとの要件がスクリプト言語でって話だったんですよ。弊社の場合。この記事、上司も見てる可能性もあるのであんまり大きい声で言えないんですけど、ぶっちゃけRubyでやる必要はなかったのでは…私も「やったことない言語でできるからいいかな~」くらいのノリだったんですけど、やったことない言語でやるとなると実際やるとすっげえめんどくさいですね。50倍とまでは言わないですけど、C# + xUnit +Seleniumあたりだと、数十倍の生産性が出せた気がします。まあ、私C#でも人並みレベルのスキルはないと思いますけども…