Robot FrameworkのSetupやTeardownでは、キーワードが1つしか指定できない

Robot Frameworkで、xUnit系にあるようなSetupやTeardownを使うことで、テストの実行前や実行後に必ず実施したいキーワードを指定できます。

 
ただ、SetupやTeardownではキーワードが1個しか指定できません。

そのことをいつも忘れるため、メモしておきます。

 

環境

  • Python 3.6.3
  • Robot Framework 3.0.2

 

実験

テストケース

  • SetupとTeardownのキーワードを1つにした場合
  • SetupとTeardownのキーワードを2つにした場合
  • SetupとTeardownのキーワードを1つにまとめた場合
  • SetupとTeardownのキーワードをRun Keywordsで複数同時に起動した場合

を作ってみます。

*** Keywords ***
セットアップキーワードをまとめた
    Log To Console  ${\n}セットアップ1です
    Log To Console  セットアップ2です

ティアダウンキーワードをまとめた
    Log To Console  ティアダウン1です
    Log To Console  ティアダウン2です


*** Test Cases ***

SetupとTeardownのキーワードを1つにした場合
    [Setup]  Log To Console  ${\n}セットアップです
    [Teardown]  Log To Console  ティアダウンです
    Log To Console  テスト本体です


SetupとTeardownのキーワードを2つにした場合
    [Setup]  Log To Console  ${\n}セットアップ1です  Log To Console  セットアップ2です
    [Teardown]  Log To Console  ティアダウン1です  Log To Console  ティアダウン2です
    Log To Console  テスト本体です


SetupとTeardownのキーワードを1つにまとめた場合
    [Setup]  セットアップキーワードをまとめた
    [Teardown]  ティアダウンキーワードをまとめた
    Log To Console  テスト本体です


SetupとTeardownのキーワードをRun Keywordsで複数同時に起動した場合
    [Setup]  Run Keywords  Log To Console  ${\n}セットアップ1です  AND  Log To Console  セットアップ2です
    [Teardown]  Run Keywords  Log To Console  ティアダウン1です  AND  Log To Console  ティアダウン2です
    Log To Console  テスト本体です

 
なお、Run Keywordsでは複数のキーワードを指定できます。

ただ、キーワードに引数がある場合には、キーワードの区切りに対して明示的に AND を入れる必要があります。

 
実行してみます。

$ robot test_setup_teardown.robot 
======================
Test Setup Teardown
======================
SetupとTeardownのキーワードを1つにした場合                            
セットアップです
.テスト本体です
.ティアダウンです
SetupとTeardownのキーワードを1つにした場合    | PASS |
-------------------------------
SetupとTeardownのキーワードを2つにした場合
セットアップ1です.テスト本体です
SetupとTeardownのキーワードを2つにした場合    | PASS |
-------------------------------
SetupとTeardownのキーワードを1つにまとめた場合
セットアップ1です
セットアップ2です
.テスト本体です
.ティアダウン1です
ティアダウン2です
SetupとTeardownのキーワードを1つにまとめた場合    | PASS |
--------------------------------
SetupとTeardownのキーワードをRun Keywordsで複数同時に起動した場合
セットアップ1です
セットアップ2です
.テスト本体です
.ティアダウン1です
ティアダウン2です
SetupとTeardownのキーワードをRun Keywordsで複数同時に起動した場合    | PASS |
---------------------------------
Test Setup Teardown    | PASS |
4 critical tests, 4 passed, 0 failed
4 tests total, 4 passed, 0 failed

実行結果より、 SetupとTeardownのキーワードを2つにした場合 の場合のみ、最初のキーワードしか実行されていないようです。

ただ、テスト自体はパスしてしまうため、そのことに気づきにくいです。

そのため、SetupとTeardownにはキーワードが1つしか指定できないことを覚えておいたほうが良さそうです。

 

ソースコード

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

Robot Frameworkでは、埋め込み引数とArgments設定のある引数を同時に使えない

Robot Frameworkでは、キーワードの仮引数を使う方法として

  • 埋め込み引数
  • [Arguments] 設定のある引数

の2つがあります。

以前、このあたりで試しました。

 
ただ、両方を使おうとするとエラーとなるため、注意が必要です。

試しに、

*** Keywords ***
埋め込みキーワード「${embed}」のみ
    log to console  ${embed}

Argumentsのみ
    [Arguments]  ${arg}
    log to console  ${arg}

キーワード「${embed}」とArgumentsの両方
    [Arguments]  ${arg}
    log to console  ${embed}
    log to console  ${arg}


*** Test Cases ***

埋め込み引数のみのキーワードを使う
    埋め込みキーワード「埋め込み」のみ

Arguments設定がある引数のみのキーワードを使う
    Argumentsのみ  arg=Argument設定

両方の引数を使う
    キーワード「埋め込み」とArgumentsの両方  arg=Argument設定

というテストケースを用意します。

 
実行してみます。

$ robot test_keyword_args.robot 
[ ERROR ] Error in test case file '/path/to/builtin_library_samples/test_keyword_args.robot': Creating keyword 'キーワード「${embed}」とArgumentsの両方' failed: Keyword cannot have both normal and embedded arguments.
========================
Test Keyword Args
========================
埋め込み引数のみのキーワードを使う    埋め込み
埋め込み引数のみのキーワードを使う    | PASS |
---------------------------------
Arguments設定がある引数のみのキーワードを使う    Argument設定
Arguments設定がある引数のみのキーワードを使う    | PASS |
---------------------------------
両方の引数を使う    | FAIL |
No keyword with name 'キーワード「埋め込み」とArgumentsの両方' found.
---------------------------------
Test Keyword Args    | FAIL |
3 critical tests, 2 passed, 1 failed
3 tests total, 2 passed, 1 failed

と、両方使った場合のみ、エラーが発生しました。

 
エラーメッセージにも

Keyword cannot have both normal and embedded arguments.

とあり、どちらかしか使えないことがわかります。

 
両者の差は

埋め込み引数には、通常のキーワードの引数で使えるような、デフォルト値や可変個の引数のサポートがありません。 キーワードを呼ぶときに、変数を指定するのはもちろん可能ですが、テストの可読性を下げてしまうかもしれません。 埋め込み引数を使えるのは、ユーザキーワードだけです。

基本の書き方 - キーワード名の中に引数を埋め込む - ユーザキーワードを定義する — RobotFramework和訳・日本語ドキュメント集

です。

そのため、両者は

  • 引数のデフォルト値や可変個の引数が必要か
  • キーワードの可読性をどうするか

を考慮して使い分ければ良さそうです。

 

ソースコード

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

Robot Frameworkのキーワード、Run Keyword IfのELSEは大文字で書く

Robot Frameworkで、Run Keyword If でif以降の条件マッチとする場合、

  • ELSE IF
  • ELSE

を使います。

この ELSE IFELSE ですが、Builtinライブラリの説明には、

ELSE や ELSE IF は *args に指定し、厳密に ELSE, ELSE IF と書かねばなりません。

http://robotframework-ja.readthedocs.io/ja/latest/lib/BuiltIn.html#run-keyword-if http://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Run%20Keyword%20If

とありました。

キーワードは UPPER CASE、camelCase、lower case のそれぞれで書いた時にも同じ挙動をしています。

なぜELSEやELSE IFだけは挙動が違うのかと思い、試してみました。

 

環境

  • Python 3.6.3
  • Robot Framework 3.0.2

 

UPPER CASEで書いた場合

*** Keywords ***
ELSEをUPPER CASEで書く
    Run Keyword If  0 == 1  Log To Console  IFの表示
    ...  ELSE  Log To Console  ELSEの表示

ELSE IFとELSEをUPPER CASEで書く
    Run Keyword If  0 == 1  Log To Console  IFの表示
    ...  ELSE IF  0 == 2  Log To Console  ELSE IF の表示
    ...  ELSE  Log To Console  ELSE IFの表示

*** Test Cases ***

それぞれの出力を比べる
    Log To Console  ${SPACE}
    ELSEをUPPER CASEで書く
    ELSE IFとELSEをUPPER CASEで書く

 
実行結果です。テストがパスしました。

$ robot test_else_upper_camel_lower_case.robot 
==========================
Test Else Upper Camel Lower Case
==========================
それぞれの出力を比べる
.ELSEの表示
.ELSE IFの表示
それぞれの出力を比べる    | PASS |

 

Pascal Caseで書いた場合

*** Keywords ***
ELSEをPascal Caseで書く
    Run Keyword If  0 == 1  Log To Console  これは表示されないはず
    ...  Else  Log To Console  Elseの表示

ELSE IFとELSEをPascal Caseで書く
    Run Keyword If  0 == 1  Log To Console  これは表示されないはず
    ...  Else If  0 == 2  Log To Console  これも表示されないはず
    ...  Else  Log To Console  Else Ifの表示

*** Test Cases ***

それぞれの出力を比べる
    Log To Console  ${SPACE}
    ELSEをPascal Caseで書く
    ELSE IFとELSEをPascal Caseで書く

 
実行結果です。

$ robot test_else_upper_camel_lower_case.robot 
...
Pascal Caseで書く    | PASS |

テストはパスしたものの、Log To Consoleの結果が出力されていません。

 
今は else以降で条件にマッチしましたが、 ifでマッチするように変えてみます。

ELSEをPascal Caseで書く
    Run Keyword If  1 == 1  Log To Console  Ifの表示
    ...  Else  Log To Console  Elseの表示

 
実行してみます。

$ robot test_else_upper_camel_lower_case.robot 
...
Pascal Caseで書く    | FAIL |
Keyword 'BuiltIn.Log To Console' expected 1 to 3 arguments, got 4.

テストが失敗しました。シンタックスエラーが発生しているようです。

 

lower caseで書いた場合

同じく、lower caseで書いてみた場合を試します。

*** Keywords ***
ELSEをlower caseで書く
    Run Keyword If  0 == 1  Log To Console  ifの表示
    ...  Else  Log To Console  elseの表示

ELSE IFとELSEをlower caseで書く
    Run Keyword If  0 == 1  Log To Console  ifの表示
    ...  else if  0 == 2  Log To Console  else ifの表示
    ...  else  Log To Console  elseの表示

*** Test Cases ***

lower caseで書く
    ELSEをlower caseで書く
    ELSE IFとELSEをlower caseで書く

 
実行してみます。

$ robot test_else_upper_camel_lower_case.robot 
...
# elseに条件がマッチする場合
lower caseで書く    | PASS |

# ifに条件がマッチする場合
lower caseで書く    | FAIL |
Keyword 'BuiltIn.Log To Console' expected 1 to 3 arguments, got 4.

Pascal Caseと同じ結果となりました。

 
これらより、Run Keyword Ifの ELSE IFELSE はUPPER CASEで書く必要があると分かりました。

 

ソースコード

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

RobotFrameworkで、ifのあるキーワードの書き方の違いについて

RobotFrameworkのBuiltinライブラリには、Ifを使っているキーワードとして

  • Set Variable If
  • Run Keyword If

があります。

ただ、if/else の書き方が両者で異なるため、メモとして残しておきます。

 
目次

 

環境

  • Python3.6.3
  • RobotFramework 3.0.2

 

Set Variable If

条件によって変数の値を切り替える Set Variable If です。

switchっぽい書き方です。

${result} =  Set Variable If  ${random} == 0  ${\n}Zero
...          ${random} == 1  ${\n}One
...          ${\n}Other

なお、 ... は継続行文字となります(.の後ろの半角スペース2を含む)。

 

Run Keyword If

条件によって実行するキーワードを切り替える Run Keyword If です。

If/elseっぽい書き方です。

Run Keyword If  ${random} == 0  Log To Console  Zero
...  ELSE IF    ${random} == 1  Log To Console  One
...  ELSE  Log To Console  Other

 

ソースコード

GitHubに上げました。builtin_library_samples/test_if_else.robot が今回のファイルです。
thinkAmi-sandbox/RobotFramework-sample: Robot Framewrok samples

FakerLibraryを使って、Robot Framework向けのダミーデータを作成する

この記事は 「Robot Framework Advent Calendar 2017 - Qiita」 の22日目の記事です。

テストデータを作成する時、何かしらのダミーデータが必要になることがあります。

例えば、Pythonでは Faker などのライブラリを使ってダミーデータを作成します。
joke2k/faker: Faker is a Python package that generates fake data for you.

 
Robot Frameworkでもダミーデータを作る方法がないかを探したところ、Fakerのラッパーである FakerLibrary がありました。

そこで今回は、FakerLibraryを試してみます。

 
目次

 

環境

  • Python 3.6.3
  • Robot Framework 3.0.2
  • FakerLibrary 4.2.0

 
FakerLibraryのインストールはpipで行います。

pip install robotframework-faker

 
なお、以下のissueがクローズされているため、Python3でも問題なく使えます。
Python 3.x compatibility · Issue #20 · guykisel/robotframework-faker

 

FakerLibraryの参照

FakerLibraryのドキュメントを見たところ、いろいろな項目のダミーデータが用意されているようでした。

また、Importing欄に locale がありました。fakerのラッパーだとしたら日本語が扱えそうです。

そこで、

*** Settings ***
Library  FakerLibrary  locale=ja_JP

として FakerLibrary を参照することにしました。

 

FakerLibraryで日本語のダミーデータを作成する

以下のRobot Frameworkのテストコードを作成してみました。

*** Settings ***
Library  FakerLibrary  locale=ja_JP


*** Test Cases ***
個人のフェイクデータを作成する
    # "FakerLibrary" というプレフィックスがなくても動作する
    ${address} =  FakerLibrary.Address
    ${city} =  FakerLibrary.City
    ${first_name} =  FakerLibrary.First Name
    ${last_name} =  FakerLibrary.Last Name
    ${name} =  FakerLibrary.Name

    Log To Console  ${\n}${address}${\n}${city}${\n}${first_name}${\n}${last_name}${\n}${name}

    ${email} =  FakerLibrary.Email
    ${tel} =  FakerLibrary.Phone Number

    # special_chars, digits, upper_case, lower_case の設定も可能
    ${password} =  FakerLibrary.Password  length=15
    ${postcode} =  FakerLibrary.Postcode

    Log To Console  ${\n}${email}${\n}${password}${\n}${tel}${\n}${postcode}${\n}${zipcode}


会社のフェイクデータを作成する
    ${company} =  FakerLibrary.Company
    ${email} =  FakerLibrary.Company Email

    # サフィックスはIncであり、(株)などではない
    ${suffix} =  FakerLibrary.Company Suffix

    Log To Console  ${\n}${company}${\n}${email}${\n}${suffix}


適当な文を作成する
    ${paragraph} =  FakerLibrary.Paragraph
    Log To Console  ${paragraph}

 
実行してみます。

$ robot test_faker.robot 
======================
Test Faker
======================
個人のフェイクデータを作成する    ...
新潟県西多摩郡檜原村虎ノ門虎ノ門ヒルズ森タワー3丁目125号
山武郡九十九里町
香織
工藤
木村 和也
個人のフェイクデータを作成する    ...
unotakuma@hotmail.com
+z4d2Zdy8%aYyyx
090-3496-6948
46207
個人のフェイクデータを作成する    | PASS |
--------------------------------
会社のフェイクデータを作成する    ...
株式会社 伊藤
unoakira@kato.com
LLC
会社のフェイクデータを作成する    | PASS |
--------------------------------
適当な文を作成する    .
明らかにするサワーテント索引屋根裏移動暖かい。見落とす試してみるヒールホイール。
適当な文を作成する    | PASS |

日本語のテストデータができました。

 

アンドキュメントな郵便番号の出力について

先ほどの結果をよく見ると、 FakerLibrary.Postcode が5桁で出力されていました。日本の郵便番号とは異なっているようです。

 
fakerでは日本の郵便番号はどうなっているのだろうと思い調べたところ、以下の記事がありました。
Pythonのfakerで日本語テストデータを生成する - Qiita

記事によると zipcode が日本の郵便番号のようでした。

 
そこでドキュメントにはなかったものの、 zipcode を指定してみます。

 

*** Test Cases ***
個人のフェイクデータを作成する
#...
    ${postcode} =  FakerLibrary.Postcode
    ${zipcode} =  FakerLibrary.Zipcode

 
実行してみます。

46207
153-4563
個人のフェイクデータを作成する    | PASS |

日本の郵便番号っぽいのが出力されました。

 

ソースコード

GitHubに上げました。faker_sample ディレクリの中が今回のものです。
thinkAmi-sandbox/RobotFramework-sample: Robot Framewrok samples

Robot Framework + SSHLibraryで、SSHのテストをする

この記事は 「Robot Framework Advent Calendar 2017 - Qiita」 の21日目の記事です。

Robot Frameworkでは、 SSHLibrary を使ってSSHのテストができます。

そこで今回、SSHLibraryを試してみました。

 
目次

 

環境

  • Python 2.7.14
    • SSHLibraryがPython3系に対応していないため
  • Robot Framework 3.0.2
  • SSHLibrary 2.1.3

 

SSHサーバの用意

SSHLibraryはSSHクライアントなので、SSHサーバを別途用意する必要があります。

今回はSSHサーバをDocker (Ubunt 16.04ベース) で作成します。

なお、Dockerfileの内容は、Dockerのドキュメントにあったものをそのまま使います。
Dockerize an SSH service | Docker Documentation

また、公開鍵認証も試すため、以下を参考にDockerfileや公開鍵を準備します。
Docker | 公開鍵を使ってサーバーにssh接続する ( コンテナに公開鍵をコピーする場合 ) - Qiita

 
まずは公開鍵を準備します。

$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_sshlibrary_sample

Dockerコンテナに公開鍵を転送するため、作成した公開鍵( id_rsa_sshlibrary_sample.pub ) を、Dockerfileと同じディレクトリに入れておきます。

 
Dockerfileは以下の通りです。

FROM ubuntu:16.04

RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:screencast' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

# ローカルで生成した公開鍵をコンテナへ転送
COPY id_rsa_sshlibrary_sample.pub /root/authorized_keys

# ディレクトリ作成、キーの移動、パーミッションの変更
CMD mkdir ~/.ssh && \
    mv ~/authorized_keys ~/.ssh/authorized_keys && \
    chmod 0600 ~/.ssh/authorized_keys

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

 
ビルド後、起動しておきます。

# ビルド
$ docker build -t eg_sshd .

# 起動:Dockerのポート22はMacの12345ポートへと転送
$ docker run -d -p 12345:22 --name test_sshd eg_sshd

 
なお、このテスト終了後は削除を忘れずに行います。

$ docker stop test_sshd
$ docker rm test_sshd
$ docker rmi eg_sshd

 

SSHLibraryの実行

インストール

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

なお、以下のissueにある通り、まだPython3系では動かないことに注意します。

# バージョン確認
$ python --version
Python 2.7.14

# pipでインストール
pip install robotframework-sshlibrary

 

テストケースの作成

今回はパスワード認証と公開鍵認証の2つでSSH接続してみます。

*** Settings ***
Library  SSHLibrary

*** Variables ***
${user}  root
${password}  screencast

*** Test Cases ***
パスワードでログインしてhelloする
    Open Connection  localhost  port=12345
    Login  root  screencast
    ${output} =  Execute Command  echo Hello SSHLibrary with password!
    Log To Console  ${\n}${output}
    Should Be Equal  ${output}  Hello SSHLibrary with password!
    Close All Connections

公開鍵でログインしてhelloする
    Open Connection  localhost  port=12345
    # 鍵は秘密鍵を指定する
    Login With Public Key  root  id_rsa_sshlibrary_sample  screencast
    ${output} =  Execute Command  echo Hello SSHLibrary with public key!
    Log To Console  ${\n}${output}
    Should Be Equal  ${output}  Hello SSHLibrary with public key!
    Close All Connections

 

テストの実行

両方のテストがパスしました。

$ robot test_ssh.robot 
===========================
Test Ssh
===========================
パスワードでログインしてhelloする    ...
Hello SSHLibrary with password!
パスワードでログインしてhelloする    | PASS |
-------------------------------------
公開鍵でログインしてhelloする    ...
Hello SSHLibrary with public key!
公開鍵でログインしてhelloする    | PASS |
-------------------------------------
Test Ssh    | PASS |
2 critical tests, 2 passed, 0 failed
2 tests total, 2 passed, 0 failed

 

ソースコード

GitHubに上げました。ssh_library_sample ディレクリの中が今回のものです。
thinkAmi-sandbox/RobotFramework-sample: Robot Framewrok samples

Robot FrameworkのlintツールであるRobot Framework Lintを試してみた

この記事は 「Robot Framework Advent Calendar 2017 - Qiita」 の20日目の記事です。

Robot Frameworkのlintツール(ソースコード静的解析ツール)を探したところ、 Robot Framework Lint がありました。
boakley/robotframework-lint: Linter for robot framework plain text files

そこで今回は Robot Framework Lintを試してみました。

 
目次

 

環境

  • Python 3.6.3
  • Robot Framework 3.0.2
  • Robot Framework Lint 0.9

Robot Framework LintのインストールはpipでOKです。

pip install --upgrade robotframework-lint

 

Lintの実行

例えば、こんな感じのテストファイル test_selenium.robot があるとします。

*** Settings ***
Library  SeleniumLibrary

*** Variables ***
${browser}  chrome

*** Keywords ***
ブラウザを起動する
    Open Browser  https://google.co.jp  ${browser}

*** Test Cases ***
Seleniumをテストする
    ブラウザを起動する
    Close Browser

 
このファイルに対してlintを実行してみます。

$ rflint test_selenium.robot 
+ test_selenium.robot
W: 2, 0: No suite documentation (RequireSuiteDocumentation)
E: 13, 0: No testcase documentation (RequireTestDocumentation)
E: 9, 0: No keyword documentation (RequireKeywordDocumentation)
W: 8, 0: Too few steps (1) in keyword (TooFewKeywordSteps)

結果が出力されました。

Documentがなかったり、テストケースの中のステップが短すぎるようです。

 

デフォルトのlint内容

rflint --list コマンドにて、デフォルトのlint内容が確認できます。

$ rflint --list
E DuplicateKeywordNames
E DuplicateTestNames
W FileTooLong
W InvalidTable
W LineTooLong
W PeriodInSuiteName
W PeriodInTestName
E RequireKeywordDocumentation
W RequireSuiteDocumentation
E RequireTestDocumentation
E TagWithSpaces
W TooFewKeywordSteps
W TooFewTestSteps
W TooManyTestCases
W TooManyTestSteps
W TrailingBlankLines

 
それぞれの内容はソースコードを見て確認します。
https://github.com/boakley/robotframework-lint/tree/master/rflint/rules

 

lintの範囲

lintの範囲を確かめるため、

  • 一つのファイル内でキーワードが重複するケース
  • 複数のファイル間でキーワードが重複するケース

を試してみます。

 
test_duplicate_in_onefile.robot

*** Settings ***
Documentation  一つのファイルで重複したテストケースを含むテスト

*** Test Cases ***
一つのファイルでテストケース名が重複
    Log To Console  foo

一つのファイルでテストケース名が重複
    Log To Console  bar

 

  • test_duplicate_in_multi_file1.robot
  • test_duplicate_in_multi_file2.robot
*** Settings ***
Documentation  複数のファイルで重複したテストケースを含むテスト

*** Test Cases ***
複数のファイルでテストケース名が重複
    Log To Console  foo

 
rflintを実行します。

$ rflint .
+ ./test_duplicate_in_multi_file1.robot
E: 6, 0: No testcase documentation (RequireTestDocumentation)
W: 5, 0: Too few steps (1) in test case (TooFewTestSteps)
+ ./test_duplicate_in_multi_file2.robot
E: 6, 0: No testcase documentation (RequireTestDocumentation)
W: 5, 0: Too few steps (1) in test case (TooFewTestSteps)
+ ./test_duplicate_in_onefile.robot
E: 8, 0: Duplicate testcase name '一つのファイルでテストケース名が重複' (DuplicateTestNames)
E: 6, 0: No testcase documentation (RequireTestDocumentation)
W: 5, 0: Too few steps (1) in test case (TooFewTestSteps)
E: 9, 0: No testcase documentation (RequireTestDocumentation)
W: 8, 0: Too few steps (1) in test case (TooFewTestSteps)

これよりlintの範囲はテストケースファイルのようです。

 

カスタムルールを作成する

Wikiによると、カスタムルールを作成できるようです。
How to write custom rules · boakley/robotframework-lint Wiki

 

カスタムルールファイルのディレクトリを確認する

カスタムルールファイルをどこに置けばよいのか確認したところ、

At the moment, rflint will only look for rules in the rules folder where rflint is installed.

Home · boakley/robotframework-lint Wiki

Custom rules should be put in the site-rules folder. The only difference between these classes is how and when they are called.

How to write custom rules · boakley/robotframework-lint Wiki

とありました。

robotframework-lint がインストールされているディレクトリの中にある rules の中に site-rules を追加すれば良さそうでした。

ディレクトリを確認すると、

$ pwd
/path/to/rfenv363/lib/python3.6/site-packages

$ tree rflint
rflint
├── __init__.py
...
├── rules
│   ├── keywordRules.py
│   ├── otherRules.py
│   ├── suiteRules.py
│   └── testcaseRules.py
...

のようです。

ただ、ディレクトリが深いので他の方法がないかを探したところ、コマンドラインオプションで指定できるようでした。

$ rflint --help
usage: python -m rflint [-h] [--error RULENAME] [--ignore RULENAME]
                        [--warning RULENAME] [--list] [--describe]
                        [--no-filenames] [--format FORMAT] [--version]
                        [--verbose] [--configure CONFIGURE] [--recursive]
                        [--rulefile RULEFILE] [--argumentfile ARGUMENTFILE]
                        ...

A style checker for robot framework plain text files.

positional arguments:
  file

optional arguments:
...
  --rulefile RULEFILE, -R RULEFILE
                        import additional rules from the given RULEFILE

なお、ディレクトリは指定できないようです。

$ rflint --rulefile rflint/rules/ .
rflint: rflint/rules/: exception while loading: [Errno 21] Is a directory: 'rflint/rules/'

 
今回はお手軽にするため、コマンドラインオプションでカスタムルールファイルを指定することとします。

 

カスタムルールファイルを作成する

Pyhonにてカスタムルールファイルを作成します。

ルールとして作成できるのは、

  • SuiteRule
  • ResourceRule
  • TestRule
  • KeywordRule
  • GeneralRule

があるようです。
How to write custom rules · boakley/robotframework-lint Wiki

 
今回は「3文字未満のキーワードはエラーとする」というカスタムキーワードルールを作成します。

# 継承元のKeywordRule、およびlintで出力するレベルをimport
from rflint.common import KeywordRule, ERROR


# KeywordRuleを継承したクラスを定義
class TooShortKeywordRule(KeywordRule):
    # クラス変数 severity に、出力レベルを指定
    severity = ERROR

    # apply()メソッドに、実際のチェック内容を指定
    def apply(self, keyword):
        # チェックエラーとする条件
        if len(keyword.name) < 3:
            # reportメソッドを使って、lintエラーになった時の内容を出力する
            # 第一引数は該当したオブジェクト、第二引数はメッセージ、第三引数は該当行
            self.report(keyword, f'too short keyword name: {keyword.name}', keyword.linenumber)

 
なお、KeywordRuleで参照できる属性は以下に書かれています。
The Keyword class · boakley/robotframework-lint Wiki

他のルールも、同様のページがWikiに用意されています。

 

lint対象のファイル

今回は以下のファイルをlint対象にします。

test_error_keyword_rule.robot

*** Settings ***
Documentation  カスタムキーワードルール違反


*** Keywords ***
ふー
    Log To Console  baz

ふーー
    Log To Console  hoo

*** Test Cases ***
一つのファイルでテストケース名が重複
    ふー

 

カスタムルールを追加したlintの実行

test_error_keyword_rule.robot ファイルに対してlintを実行してみます。

$ rflint --rulefile custom_rule/keyword_rule.py test_error_keyword_rule.robot 
+ test_error_keyword_rule.robot
E: 14, 0: No testcase documentation (RequireTestDocumentation)
W: 13, 0: Too few steps (1) in test case (TooFewTestSteps)
E: 7, 0: No keyword documentation (RequireKeywordDocumentation)
W: 6, 0: Too few steps (1) in keyword (TooFewKeywordSteps)
E: 6, 0: too short keyword name: ふー (TooShortKeywordRule)
E: 10, 0: No keyword documentation (RequireKeywordDocumentation)
W: 9, 0: Too few steps (1) in keyword (TooFewKeywordSteps)

E: 6, 0: too short keyword name: ふー (TooShortKeywordRule) が出力されています。

一方、 ふーー というキーワードは3文字なのでlintエラーの対象外となりました。

 

ソースコード

GitHubに上げました。 rflint_sample ディレクリの中が今回のものです。
thinkAmi-sandbox/RobotFramework-sample: Robot Framewrok samples