以前、Robot FrameworkとSelenium2Libraryを使ってみました。
- Robot FrameworkでHeadless Chromeを使ってみた - メモ的な思考的な
- Robot Framework + Selenium2Library + ImageMagickで、スクリーンショットの差分を確認する - メモ的な思考的な
今回は Robot Framework + Selenium2Libraryで、静的HTMLをテストしてみます。
2017/9/2追記
Selenium2Libraryですが、バージョン3からは SeleniumLibrary
へと名称が変更されています。詳しくはこちらに書きました。
RobotFrameworkのSelenium2Libraryの名前が、SeleniumLibraryへと変更されてた - メモ的な思考的な
なお、本文はSelenium2Libraryのままにしてあります。
2017/9/2追記ここまで
目次
- 環境
- ブラウザの起動・移動・終了
- ページに文字やElementが存在するか確認する
- locatorについて
- Elementの属性を取得する
- Elementに対するvisibleとenableとcontainの違い
- Elementが見えている/見えていない時に何かする
- テーブルに対する処理
- ソースコード
環境
- Mac OS X 10.11.6
- Python 3.6.2
- Google Chrome 60.0.3112.78 (stable)
- ChromeDriver 2.31 (stable)
- RobotFramework 3.0.2
- Selenium2Library 1.8.1dev1
- Selenium 3.4.3
- Bottle 0.12.13
- Webアプリ用
Selenium2LibraryをGitHubからインストールする方法は以下と同様ですので、今回は省略します。
Robot Framework + Selenium2Library + ImageMagickで、スクリーンショットの差分を確認する - メモ的な思考的な
ブラウザの起動・移動・終了
起動
Create Webdriver
Open Browser
が使えます。
Crate Webdriver
だと起動時のオプションを利用できます。
通常のChromeを起動する方法です。
create webdriver Chrome
HeadlessなChromeを起動する方法です。オプションとして--headless
を使います。
${options} = evaluate sys.modules['selenium.webdriver'].ChromeOptions() sys call method ${options} add_argument --headless create webdriver Chrome chrome_options=${options}
移動
Go To
を使います。
Go To | Selenium2Library
以下の例では、localhostの8084ポートへ移動しています。
go to http://localhost:8084
なお、URIスキームの有無で動作の違いがあります。詳しくは以下に書きました。
Robot Framework + Selenium2Libraryで、「Go To」を使う時はURIスキームを付ける - メモ的な思考的な
終了
close all browsers
Close Browser | close brower
などが使えます。
close all browsers
ページに文字やElementが存在するか確認する
いわゆるassert系のキーワードです。キーワードの条件を満たさない場合、テストが失敗します。
ページに文字が存在するか
Page Should Contain
を使います。
Page Should Contain | Selenium2Library
# ページに「Hello, world!」の文字列が含まれるか page should contain Hello,${SPACE}world!
他に
- ページに画像が存在するか(
Page Should Contain Image
) - ページに文字が存在しないか(
Page Should Not Contain
)
などのキーワードがあります。詳しくはドキュメントを見てください。
ページにElementが存在するか
Page Should Contain Element
を使います。
Page Should Contain Element | Selenium2Library
# ページにid=helloのelementが含まれるか page should contain element id=hello
なお、キーワードの後ろにあるid=hello
の部分はlocator
と呼ばれるものです。詳しくは次で説明します。
locatorについて
locator
とは、ページのElementを探す時のキーとなるものです。
いくつか種類があるため、今回は主なものだけ記載します。詳細は以下のドキュメントを確認してください。
Locating or specifying elements | Selenium2Library
id
Elementのid
属性を使って検索します。
<button id="locator_id" name="locator_name" class="locator_class"> locator_text1 </button>
に対し、
page should contain element id=locator_id
と使います。
name
Elementのname
属性を使って検索します。
<button id="locator_id" name="locator_name" class="locator_class"> locator_text1 </button>
に対し
page should contain element name=locator_name
と使います。
identifier
Elementのid
もしくはname
属性を使って検索します。
<button id="locator_id" name="locator_name" class="locator_class"> locator_text1 </button>
に対し、
page should contain element identifier=locator_id page should contain element identifier=locator_name
と使います。
XPath
XPathを使うこともできます。
<button id="locator_id" name="locator_name" class="locator_class"> locator_text1 </button>
に対し、
page should contain element xpath=/html/body/button[@class="locator_class"] page should contain element xpath=//button[@class="locator_class"]
と使います。
参考:xpathまとめ - Qiita
また、
<button class="locator_class" data-hoge="ham spam" disabled> locator_text2 </button> <button class="locator_class_foo" data-hoge="ham egg"> locator_text3 </button> <button class="locator_class_foo" data-hoge="ham spam"> locator_text4 </button>
のような場合は、
# andを使う element text should be xpath=//button[@class="locator_class" and @disabled] locator_text2 # containを使う(第二引数は文字列をクォートで囲む) element text should be xpath=//button[@class="locator_class" and contains(@data-hoge, "spam")] locator_text2 # notを使う element text should be ... xpath=//button[@class="locator_class_foo" and not(contains(@data-hoge, "egg"))] locator_text4
のような、 and
やcontain
やnot
なども使えます。
CSS
<div id="locator_css"> <ul><li>1-1</li></ul> <ul> <li>2-1</li> <li>2-2</li> <li><p>対象</p></li> </ul> <ul><li>3-1</li></ul> </div>
に対し、
page should contain element css=#locator_id page should contain element css=button.locator_class
と使います。
また、CSSのnth-childなども使えます(nth-childは1始まり)。
:nth-childの使い方 | CSSPRO
element text should be css=#locator_css > ul:nth-child(2) > li:last-child > p 対象
jQuery
jQueryもlocatorとして使えます。
ただし、対象のHTMLにてjQueryがロードされていない場合、WebDriverException: Message: unknown error: jQuery is not defined
というエラーが発生して使えません。
参考:Document that jQuery is not provided by Selenium2Library · Issue #262 · robotframework/Selenium2Library
<img id="img_200" src="/static/image/a.png" alt="あの字" title="画像タイトル">
に対し、
page should contain image jquery=img[alt='あの字'] page should contain image jquery=img[title='画像タイトル']
と使います。
画像のalt
・title
属性で検索したい時は便利かもしれません。
Elementの属性を取得する
Get Element Attribute
を使います。
Get Element Attribute | Selenium2Library
例えば、
<img id="img_200" src="/static/image/a.png" alt="あの字" title="画像タイトル">
に対し、画像のsrc
属性を取得し、比較する例です。
${src} = get element attribute css=#img_200@src ${url} = get location should be equal ${src} ${url}static/image/a.png
Elementに対するvisibleとenableとcontainの違い
似たようなキーワードとして、
Element Should Be Visible
Element Should Be Enabled
Element Should Contain
があります。
例えば
<button id="element_display_none" style="display: none"> None </button> <button id="element_visibility_hidden" style="visibility: hidden"> Hidden </button> <button id="element_disabled" disabled> Disabled </button>
があった場合、パスするテストの書き方は
# not be visible / be visible element should not be visible id=element_display_none element should not be visible id=element_visibility_hidden element should be visible id=element_disabled # be enable / be disable element should be enabled id=element_display_none element should be enabled id=element_visibility_hidden element should be disabled id=element_disabled # いずれもcontain element page should contain element id=element_display_none page should contain element id=element_visibility_hidden page should contain element id=element_disabled
となります。
そのため、
display:none
とvisibility:hidden
はnot visible
、disabled
はvisible
display:none
とvisibility:hidden
はenabled
、disabled
はdisabled
- いずれも
contain
という挙動です。
Elementが見えている/見えていない時に何かする
例えば、
<button id="visible_button"> 見えてる </button> <button id="invisible_button" style="display: none"> 見えてない </button>
があった時に、見えている/見えていないで処理を分ける場合、
# 見えてる ${visible} = run keyword and return status element should be visible id=visible_button run keyword if ${visible} log to console 見えてます # 見えてない ${invisible} = run keyword and return status element should be visible id=invisible_button # 「run keyword unless」を使うことで、第一引数がfalseの時に log to console する run keyword unless ${invisible} log to console 見えてないです
となります。
否定形の処理は、Run Keyword Unless
を使います。
- 参考
テーブルに対する処理
例えば、
<div id="table_search"> <table> <tr> <th>key</th> <th>value</th> </tr> <tr> <td>一行目のキー</td> <td>一行目の値</td> </tr> </table> <table> <tr> <th>項目</th> <th>値</th> </tr> <tr> <td>項目1</td> <td>値1</td> </tr> <tr> <td>項目2</td> <td>値2</td> </tr> </table> </div>
というテーブルがあった時に、行・列・セルの処理をしたい場合は、
# 行番号(row)にはヘッダ行(th)も含まれていることに注意 # また、「table row should contain」は、指定した行のどこかの列にその文字列があればPASSする table row should contain css=#table_search > table:nth-child(2) 3 項目2 table row should contain css=#table_search > table:nth-child(2) 3 値2 # 行・列の組み合わせで調べたい時は、「table cell should contain」を使う # 行、列、値の順で指定する table cell should contain css=#table_search > table:nth-child(2) 3 2 値2
となります。
他にも、Table Header Should Contain
など色々とありますので、ドキュメントを見ると良いかと思います。
- Table Row Should Contain | Selenium2Library
- Table Cell Should Contain | Selenium2Library
- Table Header Should Contain | Selenium2Library
ソースコード
GitHubに上げました。
thinkAmi-sandbox/RobotFramework-sample
selenium2_library_sample
ディレクトリの中にあるものが今回のコードです。
構成は
- target_app/target.py : Bottleアプリ
- target_app/views/index.html : 対象のHTML
- tests/selenium_page_test.robot : Selenium2Libraryを使ったテストコード
です。
python target.py
でBottleアプリを起動した後、RobotFrameworkのテストコードを実行して動作確認できます。