古いWebアプリケーションのブラウザテスト
エンジニアのアカイです。
今回はブラウザテストを行ってみます。
具体的には、Capybara/Poltergeistを使用して、無人テストを行います。
これらはRuby on Railsのテストのために作られている雰囲気がありますが、
他のアプリケーションでも使用できます。
条件は以下の通りです。
- 3画面構成のフォーム(入力・確認・完了)
- 入力は正常値のみ
- 自動的に完了画面まで動作させる
- サーバ上で実行
PhantomJS
$ wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 $ tar xjf phantomjs-2.1.1-linux-x86_64.tar.bz2 $ sudo mv phantomjs-2.1.1-linux-x86_64 /usr/local/ $ sudo ln -s /usr/local/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs $ sudo aptitude -y install libfontconfig
テストコード置き場
$ mkdir test $ cd test $ bundle init $ vi Gemfile $ bundle install --path=vendor/bundle
Gemfileの内容は以下のようにしました。
使わないものもありますが、あまり重要ではないのでそのままにしておきます。
# A sample Gemfile source "https://rubygems.org" # gem "rails" gem 'capybara' gem 'poltergeist' gem 'headless' gem 'rspec' gem 'activesupport' gem 'pry'
rspecを使用しますので、準備します。
$ bundle exec rspec --init
spec_helper.rbファイルを編集して、Capybara/Poltergeistを使用できるように設定します。
# coding: utf-8 require 'bundler' Bundler.require require 'capybara/rspec' require 'capybara/poltergeist' require 'headless' Capybara.register_driver :poltergeist do |app| Capybara::Poltergeist::Driver.new( app, js_errors: false, inspector: true ) end Capybara.default_max_wait_time = 10 Capybara.default_driver = :poltergeist Capybara.javascript_driver = :poltergeist Capybara.run_server = false Capybara.app_host = 'http://172.17.1.111:4567' # テスト対象のホスト設定です RSpec.configure do |config| config.include Capybara::DSL config.before(:suite) do Headless.new(destroy_on_exit: true).start end end
テストは存在しませんが実行してみます。
$ bundle exec rspec No examples found. Finished in 0.00093 seconds (files took 0.34605 seconds to load) 0 examples, 0 failures test/vendor/bundle/ruby/2.2.0/gems/headless-2.2.2/lib/headless/cli_util.rb:9:in `ensure_application_exists!': Xvfb not found on your system (Headless::Exception) from test/vendor/bundle/ruby/2.2.0/gems/headless-2.2.2/lib/headless.rb:77:in `initialize' from test/spec/spec_helper.rb:26:in `new' from test/spec/spec_helper.rb:26:in `block (2 levels) in' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/example.rb:425:in `instance_exec' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/example.rb:425:in `instance_exec' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/hooks.rb:357:in `run' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration.rb:1724:in `block in run_hooks_with' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration.rb:1724:in `each' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration.rb:1724:in `run_hooks_with' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/configuration.rb:1679:in `with_suite_hooks' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:118:in `block in run_specs' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/reporter.rb:77:in `report' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:117:in `run_specs' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:93:in `run' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:78:in `run' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/lib/rspec/core/runner.rb:45:in `invoke' from test/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.4.3/exe/rspec:4:in ` ' from test/vendor/bundle/ruby/2.2.0/bin/rspec:23:in `load' from test/vendor/bundle/ruby/2.2.0/bin/rspec:23:in ` ' $
xvfbがないといわれていますので、インストールします。
そういえば、フォントを入れていなかったので、念のため追加しておきます。
これは、スクリーンショットを撮る場合に、漢字ひらがななどを表示するためです。
$ sudo aptitude -y install xvfb fonts-ipafont
そしてもう一度実行します。
$ bundle exec rspec No examples found. Finished in 0.17762 seconds (files took 0.40034 seconds to load) 0 examples, 0 failures $
今度はエラーが発生せずに終了しました。
テストの記述
テストはspecディレクトリ以下に設置します。
rspecに関する説明は省略します。
それでは、早速テストを設置してみます。
フォームは3画面構成で、以下のようになっています。
path | タイトル | ボタン |
---|---|---|
/form | Registration Form | Confirm |
/confirm | Input Confirm | Regist |
/complete | Registration completed | - |
spec/form_spec.rb
# coding: utf-8 require 'spec_helper' describe 'アカウント登録' do before do visit '/form' end it 'フォームを正しく表示する', js: true do expect(page).to have_title 'Registration Form' end end
$ bundle exec rspec . Finished in 0.94537 seconds (files took 0.31413 seconds to load) 1 example, 0 failures $
次は、画面遷移を含めたテストを追加します。
# coding: utf-8 require 'spec_helper' describe 'アカウント登録' do before do visit '/form' end it 'フォームを正しく表示する', js: true do expect(page).to have_title 'Registration Form' end it 'フォームに入力して確認ボタンを押す', js: true do data = { account: "account-name-#{SecureRandom.hex(8)}", pwd: SecureRandom.hex(8) } data.each do |k, v| fill_in k, with: v end click_on 'Confirm' expect(page).to have_title 'Confirm' end end
$ bundle exec rspec .. Finished in 1.09 seconds (files took 0.32112 seconds to load) 2 examples, 0 failures $
最後に、登録完了までのテストを追加します。
# coding: utf-8 require 'spec_helper' @page = nil describe 'アカウント登録' do before do @data = { account: "account-name-#{SecureRandom.hex(8)}", pwd: SecureRandom.hex(8) } visit '/form' end it 'フォームを正しく表示する', js: true do expect(page).to have_title 'Registration Form' end it 'フォームに入力して確認ボタンを押す', js: true do @data.each do |k, v| fill_in k, with: v end click_on 'Confirm' expect(page).to have_title 'Input Confirm' end it 'フォーム入力から登録完了まで行う', js: true do @data.each do |k, v| fill_in k, with: v end click_on 'Confirm' click_on 'Regist' expect(page).to have_title 'Registration completed' end end
$ bundle exec rspec ... Finished in 1.34 seconds (files took 0.34232 seconds to load) 3 examples, 0 failures $
…リクエストパターンごとにitで分けると、pageの内容が空になってしまうようです。
いろいろ試してみましたが、最初から最後までを通して行うテストになってしまいました。
とりあえず目的は達成できましたので、今回はこれで完了とします。
この類のテストはルーチン的なものを自動的に行うことで、
時間を有効に使えるというのが大きいと思います。
ただ、動作があまり見えないこともあり、かなりハマりやすそうですので注意しましょう。