PR TIMESデザイナー&エンジニアブログ BREAK TIMES

PR TIMES Developer Blog(デザイナー&エンジニアによる開発者ブログ)

PR TIMES Developer Blog

当ブログは下記URLに移転しました。
https://developers.prtimes.jp/

古いWebアプリケーションのブラウザテスト

エンジニアのアカイです。

今回はブラウザテストを行ってみます。

具体的には、Capybara/Poltergeistを使用して、無人テストを行います。

これらはRuby on Railsのテストのために作られている雰囲気がありますが、
他のアプリケーションでも使用できます。

条件は以下の通りです。

  • 3画面構成のフォーム(入力・確認・完了)
  • 入力は正常値のみ
  • 自動的に完了画面まで動作させる
  • サーバ上で実行
環境構築

ubuntu 15.10 で環境を作成します。
ruby/bundlerはインストール済みです(2.2.4)。

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に関する説明は省略します。

qiita.com


それでは、早速テストを設置してみます。

フォームは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の内容が空になってしまうようです。

いろいろ試してみましたが、最初から最後までを通して行うテストになってしまいました。

とりあえず目的は達成できましたので、今回はこれで完了とします。


この類のテストはルーチン的なものを自動的に行うことで、
時間を有効に使えるというのが大きいと思います。

ただ、動作があまり見えないこともあり、かなりハマりやすそうですので注意しましょう。