Robot Framework + Selenium2Libraryで、HTMLフォームまわりをテストする

前回、Robot Framework + Selenium2Libraryで、静的HTMLをテストしてみました。
Robot Framework + Selenium2Libraryで、静的HTMLをテストする - メモ的な思考的な

 
今回は、Robot Framework + Selenium2Libraryで、HTMLフォームまわりをテストしてみます。

 
2017/9/2追記

Selenium2Libraryですが、バージョン3からは SeleniumLibrary へと名称が変更されています。詳しくはこちらに書きました。
RobotFrameworkのSelenium2Libraryの名前が、SeleniumLibraryへと変更されてた - メモ的な思考的な

なお、本文はSelenium2Libraryのままにしてあります。

2017/9/2追記ここまで

 
目次

 

環境

  • 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
    • GitHubから現在の最新版をインストール
    • PyPIにある1.8.0では、Python3系だとエラーが出てインストールできない
  • Selenium 3.4.3
  • Bottle 0.12.13
    • Webアプリ用

 

フォームの送信ボタンを押す場合

こんな感じでフォームの送信ボタンがあるとします。

<form id="id_form" action="/form" method="POST">
    <input id="id_submit" type="submit">
</form>

この送信ボタンを押す方法を考えてみます。

 

フォームの送信ボタンをクリックする

Click Buttonを使って、フォームの送信ボタンをクリックします。
Click Button | Selenium2Library

click button  id=id_submit

 

フォームの送信ボタンに対してEnterキーを押す

Press Keyを使って、フォームの送信ボタンに対してEnterキーを押すこともできます。

なお、Enterキーのコードは \\13 となります。

press key  id=id_submit  \\13

 

リンクをクリックする

フォームとは関係ないような気もしますが、画面遷移になるので、ここに記載します。

このようなリンクがあるとします。

<a id="back_to_top" href="/">トップへ戻る</a>

この時のリンクのクリック方法を考えます。

 

Click Element

Click Elementでリンクをクリックします。
Click Element | Selenium2Library

click element  id=back_to_top

 

Click Linkでもリンクをクリックできます。
Click Link | Selenium2Library

click link  id=back_to_top

 

type=textなinput要素に値を入力する

<input type="text" id="id_subject" name="subject">

というHTMLの場合、

input text  id=id_subject  件名です

とすると、input要素に件名ですが入力されます。

 

type=passwordなinput要素に値を入力する

<input type="password" id="id_password" name="aikotoba">

というHTMLの場合、

input password  id=id_password  パスワードです

とすると、input要素にパスワードですが入力されます。

 

ラジオボタンを選択する

<p>
    <label for="id_apple">リンゴ</label>
    <input id="id_apple" type="radio" name="fruit" value="りんご">
    <label for="id_mandarin">ミカン</label>
    <input id="id_mandarin" type="radio" name="fruit" value="みかん">
    <label for="id_grape">ブドウ</label>
    <input id="id_grape" type="radio" name="fruit" value="ぶどう">
</p>
<p>
    <label for="id_big"></label>
    <input id="id_big" type="radio" name="fruit_size" value="大きいもの">
    <label for="id_small"></label>
    <input id="id_small" type="radio" name="fruit_size" value="小さいもの">
</p>

という2つのラジオボタングループがあった場合に、正しいラジオボタンを選択する方法を考えます。

 

Select Radio Button

Select Radio Buttonキーワードを使います。
Select Radio Button | Selenium2Library

select radio button  fruit  りんご

とすると、name=fruitなラジオボタングループのうち、value=“りんご"なラジオボタンを選択します。

 

Click Element

Click Elementキーワードでも選択できます。

click element  id=id_small

 

ラジオボタンの選択確認

ラジオボタンの選択確認はRadio Button Should Be Set Toキーワードを使います。
Radio Button Should Be Set To | Selenium2Library

radio button should be set to  fruit  りんご

 

単一値のみ選択可能なSelect要素の選択と検証

<p>
    <label for="id_quantity">個数</label>
    <select id="id_quantity" name="quantity">
        <option id="id_selected1_1" name="select1_1" value="1個">1</option>
        <option id="id_selected1_2" name="select1_2" value="2個">2</option>
        <option id="id_selected1_3" name="select1_3" value="3個">3</option>
    </select>
</p>

という、単一値のみ選択可能なSelect要素での選択と検証について考えます。

 

ラベルで選択する

ラベルとは、

<option>ここ</option>

でのここの値を指します。

 
ラベルの場合、Select From List By Labelを使います。
Select From List By Label | Selenium2Library

select from list by label  id=id_quantity  2

 

valueで選択する

option要素のvalue属性の値で選択する場合、Select From List By Valueを使います。
Select From List By Value | Selenium2Library

select from list by value  id=id_quantity  3個

 

indexで選択する

option要素のindexで選択する場合、Select From List By Indexを使います。
Select From List By Index | Selenium2Library

なお、indexは0始まりになります。

select from list by index  id=id_quantity  0

 

選択されているoption要素をラベルやvalue属性で確認する

List Selection Should Beを使います。
List Selection Should Be | Selenium2Library

なお、第二引数には、ラベルとvalue属性の値のどちらかを指定します。

# ラベル
list selection should be  id=id_quantity  2

# value属性
list selection should be  id=id_quantity  2個

 

選択したラベルを取得する

Get Selected List Labelを使います。
Get Selected List Label | Selenium2Library

以下の例では、一度変数に入れた後、内容を検証しています。

${選択ラベル} =  get selected list label  id=id_quantity
should be equal  ${選択ラベル}  3

 

選択したvalue属性を取得する

Get Selected List Valueを使います。
Get Selected List Value | Selenium2Library

こちらも、一度変数に入れて内容を検証する例になります。

${選択値} =  get selected list value  id=id_quantity
should be equal  ${選択値}  3個

 

Selectに含まれるOptionの件数を調べる

Optionの件数が動的に変わる場合、その件数を調べたくなるかもしれません。

その場合、2つの方法にて検証できます。
selenium webdriver - Check whether SelectBox has items, Robot-Framework, Selenium2Library - Stack Overflow

 

Get List ItemsとGet Lengthを組み合わせる

を組み合わせて検証します。

なお、Get List Itemsの戻り値はリスト型である一方、Get Lengthの引数はスカラ変数をとるため、波括弧の前を@から$へと切り替えます。

@{items} =  get list items  id=id_quantity
${list_length} =  get length  ${items}
should be equal as integers  ${list_length}  3

 

Get Matching Xpath Countを使う

XPathでの検索となりますが、Get Matching Xpath Countも使えます。
Get Matching Xpath Count | Selenium2Library

${list_count} =  get matching xpath count  //select[@id="id_quantity"]/option
should be equal as integers  ${list_count}  3

複数選択可能なSelectに含まれるOptionの選択と検証

<p>
    <label for="id_accessories">付属品</label>
    <select id="id_accessories" name="accessories" multiple>
        <option id="id_selected2_1" name="select2_1" value="paper"></option>
        <option id="id_selected2_2" name="select2_2" value="box">容器</option>
        <option id="id_selected2_3" name="select2_3" value="rope">ロープ</option>
    </select>
</p>

という、複数選択可能なSelect要素独特の選択と検証について考えます。

 

全選択する

Select All From Listを使います。
Select All From List | Selenium2Library

select all from list  id=id_accessories

 

選択をやめる

Unselect From ListUnselect From List By [Index/Lable/Value]を使います。

なお、Unselect From Listに It's faster to use 'by index/value/label' functions. とある通り、by系の方が速いようです。

unselect from list  id=id_accessories

 

何も選択されていないことを確認する

List Should Have No Selectionsを使います。
List Should Have No Selections | Selenium2Library

list should have no selections  id=id_accessories

 

チェックボックスの選択と確認

<p>
    <label for="id_takeout">持ち帰る</label>
    <input type="checkbox" id="id_takeout" name="takeout" value="自分で持ち帰る">
</p>

というチェックボックスのチェックと検証について考えます。

 

チェックボックスをチェックする

Select Checkboxを使います。
Select Checkbox | Selenium2Library

select checkbox  id=id_takeout

 

チェックボックスのチェックをやめる

Unselect Checkboxを使います。
Unselect Checkbox | Selenium2Library

unselect checkbox  id=id_takeout

 

チェックボックスがチェックされているか検証する

Checkbox Should Be Selectedを使います。
Checkbox Should Be Selected | Selenium2Library

checkbox should be selected  id=id_takeout

なお、否定形のCheckbox Should Not Be Selectedもあります。

 

テキストエリアの入力と検証

<textarea id="id_memo" name="memo"></textarea>

というテキストエリアの入力と検証を考えます。

 

テキストエリアに入力する

input type=textと同じく、Input Textを使います。

input text  id=id_memo  テキストエリアです

 

入力文字のクリア

こちらもinput type=textと同じく、Clear Element Textを使います。

clear element text  id=id_memo

 

テキストエリアの検証
完全一致

Textarea Value Should Beを使います。
Textarea Value Should Be | Selenium2Library

textarea value should be  id=id_memo  テキストエリアです

 

部分一致

Textarea Should Containを使います。
Textarea Should Contain | Selenium2Library

textarea should contain  id=id_memo  エリア

 

type=hiddenなinput要素のvalue属性を取得する

<input type="hidden" id="id_hidden_value" class="hidden_class" name="hidden_value" value="隠しデータ">

という、type="hidden"なinput要素があるとします。

Get Element Attributeを使うことで、hiddenなinput要素であってもvalue属性を取得できます。
Get Element Attribute | Selenium2Library

なお、<locator>@<対象の属性>のように書きます。

${hidden_value1} =  get element attribute  id_hidden_value@value

# 検証
should be equal  ${hidden_value1}  隠しデータ

 

ソースコード

GitHubに上げました。tests/の中にあるselenium_form_test.robotファイルが今回のテストファイルです。
thinkAmi-sandbox/RobotFramework-sample

Robot Framework + Selenium2Libraryで、静的HTMLをテストする

以前、Robot FrameworkとSelenium2Libraryを使ってみました。

 
今回は Robot Framework + Selenium2Libraryで、静的HTMLをテストしてみます。

 
2017/9/2追記

Selenium2Libraryですが、バージョン3からは SeleniumLibrary へと名称が変更されています。詳しくはこちらに書きました。
RobotFrameworkのSelenium2Libraryの名前が、SeleniumLibraryへと変更されてた - メモ的な思考的な

なお、本文はSelenium2Libraryのままにしてあります。

2017/9/2追記ここまで

 
目次

 

環境

  • 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
    • GitHubから現在の最新版をインストール
    • PyPIにある1.8.0では、Python3系だとエラーが出てインストールできない
  • Selenium 3.4.3
  • Bottle 0.12.13
    • Webアプリ用

 
Selenium2LibraryをGitHubからインストールする方法は以下と同様ですので、今回は省略します。
Robot Framework + Selenium2Library + ImageMagickで、スクリーンショットの差分を確認する - メモ的な思考的な

 

ブラウザの起動・移動・終了

起動

が使えます。

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

 

ページに文字や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

のような、 andcontainnotなども使えます。

 

CSS

CSSセレクタもlocatorとして使えます。

<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='画像タイトル']

と使います。

画像のalttitle属性で検索したい時は便利かもしれません。

 

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の違い

似たようなキーワードとして、

があります。

 
例えば

<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:nonevisibility:hiddennot visibledisabledvisible
  • display:nonevisibility:hiddenenableddisableddisabled
  • いずれも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など色々とありますので、ドキュメントを見ると良いかと思います。

 

ソースコード

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のテストコードを実行して動作確認できます。

Heroku CLI を使わずに、BottleアプリをHerokuへデプロイする

通常、Heroku CLI (以前のHeroku Toolbelt)を使ってHerokuにデプロイしています。
Heroku CLI | Heroku Dev Center

ただ、Heroku CLIを使わずにデプロイする方法があるのか気になったため、その方法を調べた時のメモです。

目次

 

環境

 

Bottleアプリまわりの作業

Bottleのインストール
$ pip install bottle

 

Bottleアプリの作成

Hello, world的なものを作成します。

 

Bottleアプリ本体

app.py

import os
from bottle import get, run

@get('/')
def index():
    return 'Hello, heroku'

if __name__ == "__main__":
    run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)))

 
起動して動作確認します。

$ python app.py 

 

requirements.txtの作成
$ pip freeze > requirements.txt

 

Procfileの作成
web: python app.py

 

runtime.txtの作成
python-3.6.2

 
なお、サポートされているバージョンは現時点では以下の2つでした。

参考:Specifying a Python Runtime | Heroku Dev Center

 
そのため、

python-3.5.3

のようなサポート外のバージョンを指定すると、push時に

remote: -----> Python app detected
remote: -----> Installing python-3.5.3
remote: -----> Installing pip
remote: -----> Installing requirements with pip
remote:        /app/tmp/buildpacks/779a8bbfbbe7e1b715476c0b23fc63a2103b3e4131eda558669aba8fb5e6e05682419376144189b29beb5dee6d7626b4d3385edb0954bffea6c67d8cf622fd51/bin/steps/pip-install: line 7: /app/.heroku/python/bin/pip: No such file or directory
remote:  !     Push rejected, failed to compile Python app.
remote: 
remote:  !     Push failed

とエラーになりました。

 

Herokuの準備

アプリの作成

Personal appより作成します。

 

公開鍵の登録

ssh-keygen -t rsaで公開鍵を作成します。
Managing Your SSH Keys | Heroku Dev Center

 
作成した鍵は、HerokuのAccount settingsの SSH Keys に登録しておきます。

 

接続の確認

sshでHerokuにアクセスできるか確認します。

状況に応じて、~/.ssh/id_rsa_herokuとしてあるプライベート鍵ファイルのパスを変更します。

$ ssh -i ~/.ssh/id_rsa_heroku -v git@heroku.com
...
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Offering RSA public key: ~/.ssh/id_rsa_heroku
debug1: Server accepts key: pkalg ssh-rsa blen 535
debug1: Authentication succeeded (publickey).
Authenticated to heroku.com ([50.19.85.156]:22).
debug1: channel 0: new [client-session]
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = ja_JP.UTF-8
PTY allocation request failed on channel 0
shell request failed on channel 0

と表示されればOKです。

 
なお、接続に失敗した場合は

$ ssh -i ~/.ssh/id_rsa_heroku -v git@heroku.com
...
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Offering RSA public key: ~/.ssh/id_rsa_heroku
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
Permission denied (publickey).

となります。

その時は、ここを見ると解決するかもしれません。
Fixing problems with keys | Managing Your SSH Keys | Heroku Dev Center

 

Herokuへのデプロイ

コミット
$ git add .
$ git commit -m "first commit"

 

push

add remoteします。

Heroku_Git_URLは、アプリのSettingsページにあるHeroku Git URLの値を設定します。

$ git remote add heroku https://git.heroku.com/<Heroku_Git_URL>

 
あとはpushしてデプロイします。

$ git push heroku master

 
なお、git - Can a Rails app be deployed without using Heroku Toolbelt? If so, how? - Stack Overflowでは

git remote add heroku git@heroku.com:falling-wind-1624.git

となっていましたが、その方法だと

$ git push heroku master
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

となり、デプロイに失敗します。

 

デプロイ後の確認

動作確認

ターミナルに

https://<app_name>.herokuapp.com/ deployed to Heroku

と記載されているURLにアクセスし、動作を確認します。

 

ログ確認

Heroku CLIを使っていないため、heroku logsが使えません。

そのため、アドオンでの確認となります。手元ではPapertrailを使いました。

ただ、無料プランであっても、Papertrailを追加するにはクレジットカード認証が必要でした。

 

参考資料

libsass-pythonを使って、IntelliJ + File WathersプラグインでSassをコンパイルする

IntelliJで書いているPythonアプリにて、Sassを使おうと考えました。

Sassのサイトを見たところ、Rubyが必要そうでした。
Sass: Install Sass

他の方法がないかを探したところ、LibSassがありました。

LibSass周りを調べると、libsass-pythonを使うことで、PythonでもSassをコンパイルできそうでした。
libsass-python: Sass/SCSS for Python — libsass 0.13.2 documentation

 
次に、特定のSassファイルだけをコンパイルする方法を調べたところ、IntelliJFile Watchersプラグインを使えば良さそうでした。
IntelliJ IDEAで特定のscssだけcssにコンパイルする - Qiita

 
あとはIntelliJlibsass-pythonを使う方法が分かればよいのですが、IntelliJのヘルプにはLibSassを使ったコンパイル方法は記載されていませんでした。
Compiling Sass, Less, and SCSS to CSS - Help | IntelliJ IDEA

 
そこで、libsass-pythonを使って、IntelliJ + FileWatherプラグインでSassコンパイルを試してみました。

 
目次

 

環境

 

libsass-pythonのインストー

pipでインストールします。

# venv環境を作り、activate
$ python -m venv env36
$ source env36/bin/activate

# libsassをインストール
(env36) $ pip install libsass
...
Successfully installed libsass-0.13.2 six-1.10.0

 

プロジェクトの用意

IntelliJでプロジェクトルートを開く

File > Open より、プロジェクトルートを開きます。

プロジェクトルートはこんな感じです。

$ ls -al
total 0
drwxr-xr-x   6 you  staff   204  7 31 12:35 .idea
drwxr-xr-x   7 you  staff   238  7 31 12:34 env36

 

Python SDKを追加
  • File > Project Structure
  • Project SDKNewボタン > Python SDK > Add Local
  • /path/to/project_root/env36/bin/python を選択

 

File Watchers プラグインの確認

IntelliJ IDEA > Preferences > Plugins より、File Watchersが有効になっていることを確認します。

 

Sassファイルを用意

IntelliJ IDEAで特定のscssだけcssにコンパイルする - Qiita同様の構成とします。

$ tree -L 2 -a
.
├── .idea
├── css
├── env36
└── scss
    ├── exclude.scss
    └── style.scss

 

File Watchersプラグインを設定

Preferencesの Tools > File Watchers > 「+」ボタン > SCSS にて、File Watchersプラグイン設定を起動し、以下の設定を行います。

 

Scopeの設定
  • ...ボタン > +ボタン > Local > 任意の名前
  • 中央のディレクトリ構造で、先ほど作成したscss/style.scss を選択し、 Include ボタン
  • Pattern欄に、 file:scss/style.scss が設定されたことを確認

 

Programの設定

...ボタンを押して、venv環境のPythonを指定します。

/path/to/project_root/env36/bin/python

 

Argumentsの設定

今回はlibsass-pythonのsasscを使ってSassをコンパイルします。

そのため、Argumentsにはコマンドラインからsasscを使う時の設定を記載します。
sassc — SassC compliant command line interface — libsass 0.13.2 documentation

今回は

  • -tオプションで、expandedフォーマットで出力
  • -mオプションで、mapファイルを出力
  • コンパイル後のファイルの拡張子をcssにして、別のディレクトリへと出力

とするため、Argumentsには

-m sassc -t expanded -m $FileName$ ../css/$FileNameWithoutExtension$.css

を指定します。

 
あとはOKボタンを押してPreferencesを閉じます。

 

Sassファイルのコンパイル

以下の2ファイルを用意して保存します。

style.scss

#content {
  background-color: blue;
  p {
    color: red;
  }
}

exclude.scss

p{
  color: green;
}

 
すると、File Watchersプラグインが動作し、Sassがコンパイルされます。

$ tree -L 2 -a
.
├── .idea
├── css
│   ├── style.css    << 増えた
│   └── style.css.map    << 増えた
├── env36
├── scss
│   ├── exclude.scss
│   └── style.scss
├── style.css

 
expandedなフォーマットでコンパイルされました。

style.css

#content {
  background-color: blue;
}

#content p {
  color: red;
}

/*# sourceMappingURL=style.css.map */

 
style.css.map

{
    "version": 3,
    "file": "style.css",
    "sources": [
        "../scss/style.scss"
    ],
    "names": [],
    "mappings": "AAAA,AAAA,QAAQ,CAAC;EACP,gBAAgB,EAAE,IAAI;CAIvB;;AALD,AAEE,QAFM,CAEN,CAAC,CAAC;EACA,KAAK,EAAE,GAAG;CACX"
}

Robot Framework + Selenium2Library + ImageMagickで、スクリーンショットの差分を確認する

Robot Frameworkを使ってWebサイトの検証をする中で、Webサイトの修正による差異はどこなのかを知りたいことがありました。

何か方法がないかを調べると、ImageMagickを使うのが良さそうでした。

 
そこで、Robot FrameworkからImageMagickを呼び出して、Robot Frameworkで撮影したスクリーンショットの差分を確認して見ることにしました。

 
2017/9/2追記

Selenium2Libraryですが、バージョン3からは SeleniumLibrary へと名称が変更されています。詳しくはこちらに書きました。
RobotFrameworkのSelenium2Libraryの名前が、SeleniumLibraryへと変更されてた - メモ的な思考的な

なお、本文はSelenium2Libraryのままにしてあります。

2017/9/2追記ここまで

 
目次

 

環境

  • Mac OS X 10.11.6
  • Python 3.6.1
  • Google Chrome 60.0.3112.78 (stable)
  • ChromeDriver 2.31 (stable)
  • RobotFramework 3.0.2
  • Selenium2Library 1.8.1dev1
    • GitHubから現在の最新版をインストール
    • PyPIにある1.8.0では、Python3系だとエラーが出てインストールできない
  • ImageMagick 7.0.6-3

 

準備

Selenium2Library のインストール

PyPIにあるバージョン1.8.0のSelenium2LibraryではPython3系では動作しないため、GitHubよりインストールします。

$ pip install git+https://github.com/robotframework/Selenium2Library

 

ImageMagickのインストール

Homebrewでインストールします。

$ brew install imagemagick
...
🍺  /usr/local/Cellar/imagemagick/7.0.6-3: 1,522 files, 22.7MB

 

ChromeDriverのインストール

Chrome v60ではスクリーンショットまわりの不具合があるため、最新版のv60をインストールします。

Chromeに合わせ、ChromeDriverも最新の2.31をHomebrewでインストールします。

# インストールする場合
$ brew install chromedriver

# アップグレードする場合
$ brew upgrade chromedriver

 

実装

今回は以下の仕様で実装します。

  • ImageMagickサイトにアクセス
  • スクリーンショットを撮る
    • 差分があれば、差分画像を表示
    • 差分がなければ、コンソールに「差分はありません」と表示

 

画像の差分比較

Robot FrameworkからImageMagickを実行して差分の比較結果を取得するには、OperatingSystemライブラリのrun and return rc and outputキーワードを使います。
Run And Return Rc And Output | OperatingSystem

また、画像の差分を比較し、どれだけ差分があるかはImageMagickcompareとオプションの-metric AEを使います。
MiniMagick を使って 2 枚の画像が同一かどうか判定する - Qiita

# ${rc}と${output}の間には、スペース2つ
# run and return rc and outputキーワードの後はスペース2つ、compare以降の実行時オプション部分はスペース1つずつ
${rc}  ${output} =  run and return rc and output  compare -metric AE before1.png before2.png diff1.png

 

画像ファイルを開く

RobotFrameworkのRunキーワードと、Macターミナルのopenコマンドを組み合わせます。
Macターミナルのopenコマンドの使用例 - Qiita

# ${output}には、差分がある場合は0よりも大きい値がセットされている
run keyword if  ${output} != 0  run  open diff2.png

 

ソースコード全体

imagemagick.robot

*** Settings ***

Library  Selenium2Library
Library  OperatingSystem


*** Keywords ***
スクリーンショットを撮って差分を確認する
    # headlessなChromeで確認する
    ${options} =  evaluate  sys.modules['selenium.webdriver'].ChromeOptions()  sys
    call method  ${options}  add_argument  --headless
    create webdriver  Chrome  chrome_options=${options}

    # ImageMagickのトップページへ
    go to  https://www.imagemagick.org/script/index.php

    # リロード前にスクリーンショットを撮る
    capture page screenshot  filename=before1.png

    # もう一度、リロード前のスクリーンショットを撮る
    capture page screenshot  filename=before2.png

    # ページをリロードする:たぶん広告が変わるはず
    reload page

    # リロード後のスクリーンショットを撮る
    capture page screenshot  filename=after.png

    # ブラウザを閉じる
    close browser

    # ImageMagickを使って、差分があるかを確認する
    ${rc}  ${output} =  run and return rc and output  compare -metric AE before1.png before2.png diff1.png

    # リロードする前なので、差分はないはず
    run keyword if  ${output} == 0  log to console  差分はありません

    ${rc}  ${output} =  run and return rc and output  compare -metric AE before1.png after.png diff2.png

    # リロード後は差分があるはずなので、差分を表示する
    run keyword if  ${output} != 0  run  open diff2.png


*** TestCases ***

ImageMagickサイトでのテスト
    スクリーンショットを撮って差分を確認する

 

実行

robotコマンドで実行してみます。

$ robot imagemagick.robot 
==============================================================================
Imagemagick                                                                   
==============================================================================
ImageMagickサイトでのテスト                                           差分はありません
ImageMagickサイトでのテスト                                           | PASS |
...

成功したようです。

また、画面に以下のような画像が表示されました。

f:id:thinkAmi:20170727221723p:plain

 

ソースコード

GitHubに上げました。imagemagick_sampleディレクトリ以下が今回のコードです。
thinkAmi-sandbox/RobotFramework-sample

Robot FrameworkでHeadless Chromeを使ってみた

Robot FrameworkにはSelenium2Libraryという、Seleniumと連携するためのライブラリがあります。

 
サポートされているブラウザは、ChromeFirefox・PhantomJSなど、ひと通り揃っています。
http://robotframework.org/Selenium2Library/Selenium2Library.html#Open%20Browser

 
そんな中、

を目にしました。

 
そのため、Robot FrameworkでHeadless Chromeが使えるのかを試してみたくなりました。

Python + SeleniumでHeadless Chromeを使う記事がありましたので、今回はこれを元に書いてみようと思います。
SeleniumからHeadless Chromeを使ってみた - Qiita

 
2017/9/2追記

Selenium2Libraryですが、バージョン3からは SeleniumLibrary へと名称が変更されています。詳しくはこちらに書きました。
RobotFrameworkのSelenium2Libraryの名前が、SeleniumLibraryへと変更されてた - メモ的な思考的な

なお、本文はSelenium2Libraryのままにしてあります。

2017/9/2追記ここまで

 
目次

 

環境

  • Mac OS X 10.11.6
  • Python 3.6.1
  • Google Chrome 59.0.3071.115 (stable)
  • chromedriver 2.30 (stable)
  • RobotFramework 3.0.2
  • Selenium2Library 1.8.1
    • pipでインストール可能
    • pip install robotframework-selenium2library

 

ソースコード

上記のQiita記事をRobotFramework用に書き直しただけなので、ソースコードだけ記載します。

なお、stable Chrome 59を使っているせいか、スクリーンショットは1x1の画像のままです。Qiita記事によるとChrome 61では解消されているようです。

また、GitHubにも上げてあります。selenium2_chrome_headless_sampleディレクトリ以下が今回のコードです。
thinkAmi-sandbox/RobotFramework-sample

 
2017/8/9 追記ここから

Chrome 60 + chromedriver 2.31 の場合、スクリーンショットが正しく撮影されるようになっています。

2017/8/9 追記おわり

 
selenium_google.robot

*** Settings ***

# Libraryは大文字小文字の区別があるようで、libraryとしてしまうとIDEが認識しない
Library  Selenium2Library


*** Keywords ***
GoogleでPythonを検索してスクリーンショットを撮り、結果を出力する
    # 以下のコードをRobot Framework風にした
    # http://qiita.com/orangain/items/db4594113c04e8801aad

    # 以下を参考に、Chromeのオプションを追加して、Chromeを起動する
    # https://groups.google.com/d/msg/robotframework-users/gPsiVaMo19A/cBRH7mr2BAAJ
    ${options} =  evaluate  sys.modules['selenium.webdriver'].ChromeOptions()  sys
    call method  ${options}  add_argument  --headless
    create webdriver  Chrome  chrome_options=${options}

    # Googleのトップ画面を開く
    go to  https://www.google.co.jp/

    # タイトルにGoogleが含まれていることを確認する
    ${page_title} =  get title
    should contain  ${page_title}  Google

    # 検索後を入力して送信する
    input text  name=q  Python
    # Robot FrameworkではEnterキーは\\13になる
    # https://github.com/robotframework/Selenium2Library/issues/4
    press key  name=q  \\13

    # Ajax遷移のため、適当に2秒待つ
    sleep  2sec

    # タイトルにPythonが含まれていることを確認する
    ${result_title} =  get title
    should contain  ${result_title}  Python

    # スクリーンショットを撮る
    # stableなChrome59だと、1x1の画像しか撮れない...
    capture page screenshot  filename=result_google_python.png

    # ログを見やすくするために改行を入れる
    log to console  ${SPACE}

    # 検索結果を表示する
    # ForでElementを回したかったことから、WebElementを取得し、そのAPIを利用する
    # http://robotframework.org/Selenium2Library/Selenium2Library.html#Get%20Webelements
    @{web_elements} =  get webelements  css=h3 > a
    :for  ${web_element}  in  @{web_elements}
    \  ${text} =  get text  ${web_element}
    \  log to console  ${text}
    # 以下を参考に、WebElementからattribute(href)を取得
    # https://groups.google.com/d/msg/robotframework-users/xx3KYxpDu_w/0hyulqKPKQAJ
    \  ${href} =  call method  ${web_element}  get_attribute  href
    \  log to console  ${href}

    # ブラウザを終了する
    close browser


*** TestCases ***

GoogleでPythonを検索するテスト
    GoogleでPythonを検索してスクリーンショットを撮り、結果を出力する

 

実行結果

コンソールには以下が表示されました。HeadlessのChromeでも動作するようでした。

$ robot selenium_google.robot 
==============================================================================
Selenium Google                                                               
==============================================================================
GoogleでPythonを検索するテスト                                         
Python - ウィキペディア
https://ja.wikipedia.org/wiki/Python
Pythonとは - python.jp
https://www.python.jp/about/
Python チュートリアル — Python 3.6.1 ドキュメント
https://docs.python.jp/3/tutorial/index.html
Python基礎講座(1 Pythonとは) - Qiita
http://qiita.com/Usek/items/ff4d87745dfc5d9b85a4
【入門者必見】Pythonとは?言語の特徴やシェア、仕事市場を徹底解説 | 侍 ...
http://www.sejuku.net/blog/7720
Python入門
http://www.tohoho-web.com/python/
Pythonに咬まれるな : 注意すべきセキュリティリスクのリスト | プログラミング ...
http://postd.cc/a-bite-of-python/
Download Python | Python.org
https://www.python.org/downloads/
初心者でもほぼ無料でPythonを勉強できるコンテンツ10選 - paiza開発日誌
http://paiza.hatenablog.com/entry/2015/04/09/%E5%88%9D%E5%BF%83%E8%80%85%E3%81%A7%E3%82%82%E3%81%BB%E3%81%BC%E7%84%A1%E6%96%99%E3%81%A7Python%E3%82%92%E5%8B%89%E5%BC%B7%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%8410
Pythonとは - はてなキーワード - はてなダイアリー
http://d.hatena.ne.jp/keyword/Python
GoogleでPythonを検索するテスト                                        | PASS |
------------------------------------------------------------------------------
Selenium Google                                                       | PASS |
1 critical test, 1 passed, 0 failed
1 test total, 1 passed, 0 failed

受け入れテストのフレームワークRobot Frameworkで、組込機能であるBuiltin Libraryを使ってみた

Python製の受け入れテストのフレームワークとして、Robot Frameworkがあります。

 
当初、ドキュメントが充実しているのでテストコードが書きやすいかなと思いました。

ただ、いざ書いてみるようとすると「こういう時はどう書けばよいのか」と悩みました。

そこで今回、Robot Frameworkの組込機能であるBuiltin Libraryを使ってみた時のメモを残します。

 
目次

 

環境

  • Python 3.6.1
  • Robot Framework 3.0.2
    • pipでインストール可能
    • pip install robotframework
  • テストコードを含むファイル:builtin_lib_test.robot
    • Robot Frameworkの対象ファイルは、拡張子がrobotのもの

 

コンソール出力まわり

コンソールにHello, world!を出力する

log to consoleキーワードを使い、コンソールへと出力します。

*** Settings ***
Documentation  ビルトインの機能を使ったテスト

*** TestCases ***
コンソールを使ったテスト
    # Hello, world!
    log to console  Hello, world!

ポイントは

  • log to consoleキーワードに値を渡す場合、半角スペース2つ + 出力したい文字列
    • Robot Frameworkでは、半角スペース2個をキーワードの区切りとして認識するため
  • キーワードに渡す文字列は、クォートで囲む必要なし
    • クォートで囲むと、そのクォートまでコンソールに出力
  • コメントはPython同様、文頭に#を書く

です。

 
robotコマンドを使って実行したところ、Hello, world!が出力されました。

$ robot builtin_library_samples/builtin_lib_test.robot 
==============================================================================
Builtin Lib Test :: ビルトインの機能を使ったテスト                            
==============================================================================
コンソールを使ったテスト                                              Hello, world!

なお、昔からあるコマンド

  • pybot
  • jybot
  • ipybot

などはdeprecated & 将来的には削除されると、GitHubのREADMEに記載がありました。
robotframework/robotframework: Generic test automation framework.

 

日本語をコンソールへ出力する

日本語を出力したい場合も、そのまま書けば良いです。

log to console  こんにちは!
# => こんにちは!

 

文字列まわり

文字列の中にスペースを2つ以上使う

Hello, world!では、文字列の中にスペースが1つ含まれていました。

ただ、2つ以上のスペースを入れると、文字列の中のスペースではなくキーワードの区切りと認識されてしまいます。

 
そのため、2つ以上のスペースを入れたい時は、組込定数${SPACE}を使います。

# スペースが2個以上必要な場合は、組込変数${SPACE}を利用する
log to console  スペースが${SPACE}${SPACE}${SPACE}3個必要
# => スペースが   3個必要

# 拡張変数表記も使える
log to console  スペースが${SPACE * 3}3個必要
# => スペースが   3個必要

 

文字列を結合する

Catenateを使います。

なお、デフォルトでは文字間にスペースが入ります。

文字間にスペースが不要な場合は、SEPARATOR=という書き方をします。

# 文字間スペースあり
${スペースあり} =  Catenate  スペース  あり
log to console  ${スペースあり}
# => スペース あり

# 文字間スペース無し
${スペースなし} =  Catenate  SEPARATOR=  スペース  無し
log to console  ${スペースなし}
# => スペース無し

 

文字列に該当の文字が含まれているか確認する

Should Containを使います。

Should Contain 対象の文字列 検索する文字列 の順に指定します。

# Pythonという文字列の中に、thという文字列が含まれるか
Should Contain  Python  th

 
なお、

もあります。

 

キーワードまわり

キーワードを自作する

今までは*** TestCases ***の下に直接log to consoleなどを記述しました。しかし、それだと他のテストケースでは再利用できません。

そのため、キーワード(いわゆる関数)の自作を行うため、

*** Keywords ***
コンソールに文字を出力する
    log to console  Hello, world!

と、*** Keywords ***に定義します。

*** TestCases ***では

*** TestCases ***
コンソールを使ったテスト
    コンソールに文字を出力する

のように、自作キーワードを利用します。

 
なお、キーワードには半角スペース1個を含めることもできます。

スペース があるキーワード を実行する
    log to console  スペースのあるキーワードです

 

キーワードの仮引数を定義する
[Arguments]を使う

[Arguments]で、キーワードの仮引数を定義できます。

なお、[Arguments]は一行で書く必要があります。キーワード内に[Arguments]が複数あると、used multiple timesエラーが発生します。

引数を受け取ってメッセージを出力する1
    [Arguments]  ${foo}  ${bar}
    log to console  ${foo}
    log to console  ${bar}

   
上記のキーワードは

*** TestCases ***
コンソールを使ったテスト
    引数を受け取ってメッセージを出力する1  foo=フー1  bar=バー1

と使うことができます。

実行すると、

フー1
バー1

となります。

 

継続行を使って[Arguments]を複数行表記にする

[Arguments]は一行で書く必要があるため、引数が多くある場合は見づらくなってしまいます。

そのため、...を使って継続行の表記もできます。
python 2.7 - If ElseIf in Robot Framework - Stack Overflow

 
上記の例の継続行表記は、

引数を受け取ってメッセージを出力する2
    [Arguments]  ${foo}
    ...          ${bar}
    log to console  ${foo}
    log to console  ${bar}

です。

なお、three-dotの後にはスペースを2つ以上入れないと、正しく認識されません。

 

キーワードの中に仮引数を埋め込む

キーワードの中に仮引数を埋め込むこともできます。

キーワードを埋め込んでコンソールに${メッセージ}を出力する
    log to console  ${メッセージ}

 
使う側は

キーワードを埋め込んでコンソールに分かりにくいハローを出力する
#=> 分かりにくいハロー

となります。

これを使う場合は分かりづらくなるため、「」などで囲んで引数であることを明示したほうがいいかもしれません。

 

キーワードの戻り値を定義する
[Return]を使う

[Return]で戻り値を定義できます。

Returnで戻り値を取得する
    [Return]  戻り値1

 
使う側は

${foo4} =  Returnで戻り値を取得する

となります。

 

Return From Keywordを使う

Return From Keyword[Return]と同じです。

ReturnFromKeywordで戻り値を取得する
    Return From Keyword  戻り値2

 

Return From Keyword Ifを使う

条件によって戻り値を返す場合は、Return From KeywordIfを使います。

ReturnFromKeywordIfで戻り値を取得する
    Return From Keyword If  ${true}  戻り値3

 

変数まわり

変数に値を設定する

set variableキーワードで値を設定します。

=の左側はスペース1つ、右側はスペース2つになります。

また、キーワードと引数を区別するため、set variableと実際に設定する値の間はスペースが2つ必要です。

${variable} =  set variable  こんばんは!
log to console  ${variable}
# => こんばんは!

 

条件付きで変数に値を設定する

set variable ifキーワードを使います。

以下の書き方は常に「条件を満たさない値」がコンソールに出力されます。

${condition_value} =  set variable if  False  空データ  条件を満たさない値
log to console  ${condition_value}
# => 条件を満たさない値

 

リスト変数を用意する

変数のタイプとして、${}の他に、

などがあります。

 
今回はリスト変数なので、@{FRUIT}のように、@を使って定義します。

今回は、*** Variables ***に記載して、グローバルな変数として使ってみます。

*** Variables ***
@{FRUIT}  りんご  みかん

*** Keywords ***
コンソールに配列を出力する
    log to console  ${\n}---$を出力---
    log to console  ${FRUIT}
    log to console  ---@を出力---
    log to console  @{FRUIT}
    log to console  @{FRUIT}[0]
    log to console  @{FRUIT}[1]

結果です。

---$を出力---
['りんご', 'みかん']
---@を出力---
りんご
りんご
みかん

 
また、set variableでも配列を変数に設定できます。

@{medals} =  set variable  金  銀  銅
log to console  ${medals}
# => ['金', '銀', '銅']

 

Ifまわり

条件に応じてキーワードを実行する(クォート版)

Run Keyword Ifを使います。

ポイントは

です。

キーワードの定義は以下となります。

Ifを使って処理を切り替えてログを出力する
    [Arguments]  ${引数}
    Run Keyword If  '${引数}' == '${EMPTY}'  log to console  空っぽです1
    ...  ELSE IF  '${引数}' == '${false}'  log to console  Falseです1
    ...  ELSE  log to console  ${引数}

使う側は

# 準備として、空の値を取得する
${empty_value} =  ReturnFromKeywordで空の戻り値を取得する

# 実際にキーワードを使うところ
Ifを使って処理を切り替えてログを出力する  引数=${empty_value}
Ifを使って処理を切り替えてログを出力する  引数=${false}
Ifを使って処理を切り替えてログを出力する  引数=値が入ってます1

です。

なお、キーワードで[Arguments]引数という文字列を定義しているため、キーワードを使う側も文字列引数を指定して値を渡しています。

 

条件に応じてキーワードを実行する(評価ネームスペース版)

もう一つの書き方として、評価ネームスペースを使う方法があります。

Robot Framework 2.9以降の場合、

Robot Framework 2.9 からは、変数自体を評価ネームスペース (evaluation namespace) の中で使えるようになりました。 ネームスペース中の変数は、波括弧のない $variable のような特殊な変数の書き方で表わせます。 この書き方にした変数はクオートする必要はなく、テストファイル中で一旦文字列に置き換えられたりもしません。

http://robotframework-ja.readthedocs.io/ja/latest/lib/BuiltIn.html#evaluating-expressions

とのことです。

試してみたところ、

  • ${EMPTY} ではうまく動作しない(クォートする必要がある)
    • Variable '$EMPTY' not found. エラー
  • 引数や${false}などは評価ネームスペースを使ってもうまく動作する

でした。

そのため、書き方は

Ifを使って処理を切り替えてログを出力する(評価ネームスペース版)
    [Arguments]  ${引数}
    Run Keyword If  $引数 == '${EMPTY}'  log to console  空っぽです2
    ...  ELSE IF  $引数 == $false  log to console  Falseです2
    ...  ELSE  log to console  ${引数}

となります。

キーワードを使う側は変わりません。

# 準備として、空の値を取得する
${empty_value} =  ReturnFromKeywordで空の戻り値を取得する

# 実際にキーワードを使うところ
Ifを使って処理を切り替えてログを出力する(評価ネームスペース版)  引数=${empty_value}
Ifを使って処理を切り替えてログを出力する(評価ネームスペース版)  引数=${false}
Ifを使って処理を切り替えてログを出力する(評価ネームスペース版)  引数=値が入ってます2

 

Forループまわり

Forループにはいくつか方法があります。
Robot Framework User Guide

今回は IN RANGE を使う方法と、listを使う方法を記載します。

IN RANGEを使ったForループ

Pythonのfor in rangeと似たようなものです。

ループブロックに関する注意点は

  • \ (バックスラッシュ)で示す
  • バックスラッシュの後ろには、スペースを2つ以上入れる

です。

Forループを使う(InRange版)
    :FOR  ${i}  IN RANGE  1  4
    \   log to console  ${i}回目

 

listを使ったForループ

今回はCreate Listキーワードを使ってリストを作成し、そのリストをループしてみます。

使い方は以下です。

@{items} =  create list  1  4  6
:FOR  ${v}  IN  @{items}
\   log to console  リストの値は${v}

 

Forループを抜ける

Exit For Loop If を使います。

:FOR  ${v}  IN  one  two  three
\   exit for loop if  $v == 'two'
\   log to console  ${v}

 

キーワードの実行まわり

今回は

  • Fail
  • Run Keyword And Return Status
  • Run Keyword And Ignore Error

について記載します。

Run Keyword系には、その他にも色々とありますので、公式ドキュメントを読んでみると良いかもしれません。

 

強制的にキーワードを失敗させる

Failを使います。失敗した時のメッセージを引数として渡せます。

Fail  常に失敗する

 

キーワードの成否を確認する

Run Keyword And Return Statusを使うと、失敗する可能性のあるキーワードの実行に対する成否判定を行うことができます。

そのため、「想定していた失敗であれば、テストが落ちないようにしたい」などの用途に使えます。

${成否} =  Run Keyword And Return Status  常に失敗するキーワードを実行する
log to console  ${成否}
#=> False

 

キーワードが失敗しても無視する

Run Keyword And Ignore Errorを使うと、

  • キーワードが失敗しても、テストを継続できる
  • キーワードが失敗した時のエラーメッセージを取得できる

を行えます。

用途しては、「キーワード失敗時のメッセージにより処理を分けたい」などでしょうか。

${エラーメッセージ} =  Run Keyword And Ignore Error  常に失敗するキーワードを実行する
log to console  ${エラーメッセージ}
#=> ('FAIL', '常に失敗する')

 

Pythonコードを実行する

Evaluate を使います。

 
以下では、Pythonコードを使ってゼロ埋めをしています。
python - Robot Framework string padding - Stack Overflow

${結果} =  Evaluate  '%06d %s' % (1, 'ゼロ埋めです')
log to console  ${結果}

 

条件を満たしていない場合、テストをパスする

Pass Execution Ifを使います。

Pass Execution If  ${true}  テストをパスしました!

なお、常にパスしたい時は Pass Execution を使います。

 

現在のテストまわりの情報を取得する

組込変数が用意されています。

例えば、

*** TestCases ***
コンソールを使ったテスト
    現在のテスト名を取得する

というテストケースの場合、

*** Keywords ***
現在のテスト名を取得する
    log to console  ${TEST NAME}
    #=> コンソールを使ったテスト

    log to console  ${SUITE NAME}
    #=> Robotframework Sample.Builtin Library Samples.Builtin Lib Test

という結果になります。

 

ソースコード

GitHubに上げました。builtin_library_samples/builtin_lib_test.robotファイルが、今回作成したファイルです。
thinkAmi-sandbox/RobotFramework-sample