Selenium,RSpecを利用した自動テストのサンプルプログラム【Ruby】

Selenium WebDriverを利用したブラウザ自動操作について、以前サンプルプログラムをあげて解説しました。Seleniumは、ブラウザで動作するWebアプリケーションのテスト目的で使用されることも多いソフトウェアです。

ただし、Seleniumはテスト実行結果の管理・評価を行うための「テストフレームワーク」と組み合わせて使用することが一般的です。テストフレームワークはプログラミング言語によって様々ですが、自分が自動テスト開発の現場で使用したことがあるものは、Rubyのテストフレームワーク「RSpec」です。

RSpecは、テスト対象の処理を特殊な構文で囲み、想定と異なる挙動が検出された場合に、テスト失敗レポートを出力します。これを利用して、Seleniumによるブラウザ処理をRSpecの構文内に記述し、Webアプリケーションの動作テストとその結果評価を行うことができます。

RSpecについて、サンプルプログラムをあげて解説していきます。

開発環境

■OS、ブラウザ

・Windows10 64bit
・Edge

■プログラミング言語、主なライブラリとバージョン

・Ruby 2.6.10p210 / Ruby 3.1.2p20
・selenium-webdriver 4.1.0
・rspec 3.11.0

プログラム実行方法

GitHubにサンプルプログラムを公開します。
https://github.com/kotetsu99/selenium_edge

使用するファイルは以下です。
・Gemfile
・edge_rspec.rb

(1)Selenium,Rspec等のインストール
GitHubにあるプログラムをダウンロードした後、コマンドプロンプトでダウンロードしたディレクトリに移動し、bundler を利用してGemfileにあるライブラリをインストールします。

bundle install

これでGemfileにあるライブラリがインストールされます。Gemfileにはselenium-webdriverとRSpec等が記述されており、ここでともにインストールされます。

(2)Edgeドライバーのダウンロード
以下のサイトから、Edgeドライバーをダウンロード・解凍し、先ほどのフォルダの中に「msedgedriver.exe」を置いておきます。

Microsoft Edge ドライバー - Microsoft Edge Developer

※Windows 64ビットであれば「x64」が対象。 

(3)edge_rspec.rbの実行

以下のコマンドを実行します。

bundle exec rspec edge_rspec.rb


サンプルプログラム解説

edge_rspec.rb を実行するとEdgeブラウザが起動し、以下の流れで自動操作が行われます。

(1)Edgeブラウザが起動
(2)Googleのトップページを開く
(3)検索欄に「test」を入力して検索
(4)検索結果を表示
(5)検索結果のトップにある文字列が「test」であるか検証


最後の(5)についてはSeleniumではなく、RSpecによるテスト結果の評価処理となります。

サンプルプログラムを掲載します。


require 'selenium-webdriver'
require "rspec"

# Edgeドライバーパスを指定
Selenium::WebDriver::Edge::Service.driver_path = 'msedgedriver.exe'
# 起動時のページURL指定
url= "https://www.google.com/"

# 検索文字列
query = "test"
# 検索結果ページタイトル
page_title = "test - Google 検索"

# describe(テスト概要)
describe "edge_test" do

  # テスト事前処理
  before(:each) do
    # ブラウザ起動(describeクラス内で使うため、インスタンス変数として定義)
    @driver = setting_driver()
    # 暗黙的待機時間の設定
    @driver.manage.timeouts.implicit_wait = 5
  end
  
  # テスト事後処理
  after(:each) do
    # ブラウザ終了
    @driver.quit  
  end

  # テスト対象処理
  it "google_search" do
  
    # Googleホームページを開く  
    @driver.get(url)

    # 検索欄にキーワードを入力して検索実行
    el = @driver.find_element(:name, "q")
    el.send_keys query
    el.send_keys(:enter)
    
    # 明示的待機時間の設定
    wait = Selenium::WebDriver::Wait.new(:timeout => 10)
    # 検索結果ページタイトルが表示されるまで待機
    wait.until {@driver.title == page_title}
    
    # 検索結果トップに現れる文字列を取得
    el = @driver.find_element(:id, "tw-source-text-ta")
    wait.until {el.displayed?}
    res = el.attribute("value").to_s
    
    # 文字列が「test」かを検証
    expect(res).to eq query
    #expect(res).to eq "test_error"
    
  end

  # Edgeドライバー設定
  def setting_driver()
    # ブラウザ動作のオプションを定義
    options = Selenium::WebDriver::Edge::Options.new
    #options.add_argument('--headless')
    options.add_argument('--inprivate')
    options.add_argument('--lang=ja')
    options.add_argument('--window-size=1000,1000')

    # ブラウザ起動
    Selenium::WebDriver.for :edge, capabilities: options
  end
  
end

RSpec構文により、やや複雑そうにみえますが、構文の意味を理解していれば、それほど難しくありません。

全体的な構成としては、describe直前まで

・Webdriverのパス設定
・ブラウザ起動直後に開くページURL(googleトップページ)
・検索文字列

等の初期設定・変数定義を行います。

describe以降は、RSpecによるテストフレームワーク内の処理となり、これがテストをしたい処理となります。

(1)Edgeブラウザが起動
(2)Googleのトップページを開く
(3)検索欄に「test」を入力して検索
(4)検索結果を表示
(5)検索結果のトップにある文字列が「test」であるか検証

RSpecの構文に触れながらdescribe内の処理について解説します。登場するRSpec構文・文法は以下の5つです。

構文
文法
説明
describe・テスト処理を始めることを宣言。
describe "edge_test" do

end
のように記述し、" "の部分に任意の名前を記述する。テスト概要がわかる名前などを記載。
・describeで宣言された処理はクラスとして扱われ、テスト名がクラス名となる。
・describe内で、独自に関数を定義することが可能。サンプルプログラムでは、
def setting_driver() という、ブラウザ起動処理の関数を定義している。
・以下のit内で記述されるテスト処理をグループ化する機能を持つ。
it・テスト対象の処理を記述する。
it "google_search" do

end
のように記述し、" "の部分に任意の名前を記述。テスト検証内容がわかる名前などを記載。
・itはdescribe内に複数記述することが可能。
・itはexampleという単位で扱われる。これは実行後に表示されるテスト結果において実行テスト数、成功テスト数、失敗テスト数などの単位として表現される。
before・テストの事前準備処理を記述する。
before(:each) do

end
のように記述。
・ブラウザ起動、ログイン処理のように、Webアプリテストで必ず実行するものの、テスト対象とはしない処理などはここに書く。
・(:each)は、各itの実行前に実行するという意味。ほかにも(:all)というのがあり、これは最初のit前のみに実行する。
after・テストの事後処理を記述する。
after(:each) do

end
のように記述。
・ブラウザ終了、ログアウト処理のように、Webアプリテストで必ず実行するものの、テスト対象とはしない処理などはここに書く。
・(:each)は、各it実行後に実行するという意味。ほかにも(:all)というのがあり、これは最後のit後のみに実行する。
expect・it内で使用する、期待値の検証命令。
expect(A).to eq B
という形式で使用する。
・AとBが同一の値であれば、想定通りのテスト結果として、itのテスト(example)は成功となる。
・AとBが異なる値であれば、想定外のテスト結果として、itのテスト(example)は失敗となる。


RSpecには、これら以外にも構文・文法がありますが、自分が現場で多用しているものはこれらです。構文の細かい所を省略して書くと、以下のような骨組みがRSpecの基本構成になります。


describe

 before
  ~
 end
 
 after
  ~
 end
 
 it
  ~ expect ~
 end

end


サンプルプログラムも大方、この構成にしたがっています。
describeでテスト名宣言を行い、beforeでブラウザ起動の事前準備処理を記述。afterでブラウザ終了処理の事後処理を記述。itでテスト対象となる処理を記述し、その中でexpectで実行結果の評価を行う。

expectで評価しているのは、googleの検索結果のトップに来る大文字です。seleniumコマンドで、この値をresという変数に格納し、期待値であるquery(値:test)と比較しています。

expect(res).to eq query

これが期待値通り(「test」)となっていればOKとしています。実行後に以下のようなテスト結果がレポートされ、想定通りの動きをしていることがわかります。


Finished in 5.52 seconds (files took 0.42788 seconds to load)

1 example, 0 failures

一方で、期待値を「test_error」に変えてみると

expect(res).to eq "test_error"

想定外の結果となったため、実行後にテスト失敗のレポートが表示されます。


Failures:

  1) edge_test google_search
     Failure/Error: expect(res).to eq "test_error"

       expected: "test_error"
            got: "test"

       (compared using ==)
     # ./edge_rspec.rb:54:in `block (2 levels) in <top (required)>'

Finished in 5.65 seconds (files took 0.48123 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./edge_rspec.rb:32 # edge_test google_search


このように、Seleniumでテスト作業を自動化し、その結果をRSpecを用いて評価する。これで、Webアプリケーションが想定通り動作するかを検証するテストの自動化を実現することができます。

スポンサーリンク