Robot Framework を使ってみる

# はじめに
「同じことを二度やりたくない」。設計に頭を使い、その裏付けとなる検証できるだけ機械化したい。というわけで Robot Framework での検証自動化を試みる。 この Robot Framework、もとは NOKIA 製ツールで、のちに OSS 化されたものだとか。テストケースの作成に一癖あり、ちょっと取っつきにくかった。調査結果をここで供養。

https://robotframework.org/

## 動作環境
このメモを書いたときの検証環境
| ソフトウェア | Version | メモ |
|:-----------|:------------:|:------------|
| Ubuntu | 22.04.3 | 最新安定板|
| Python | 3.10.12 | Ubuntu 22.04 でapt していれたバージョン |
| Robot Framework | 6.1.1 | 2023/8にインストールしたらこのバージョンだった |
| Allure-RobotFramework | 2.13.2 | テスト結果 Report 用 | 

## インストール
Robot Framework は Python ベースのツール。pip するだけで入ってくれる。動作環境を安定化させるために Docker を利用する例もあるようだが、現段階ではそこに至っていない。

```
pip install robotframework
```
## Robot Framework の簡単な文法

### テストデータテーブル
Robot Framework のテストコードは「テストデータテーブル」と呼ばれる（らしい）。このテストデータテーブルは Settings, Variables, Test Cases, Tasks, Keywords, Comments の6つのセクションで構成される。記法は HTML, TSV, プレーンテキストの3種。ここでは プレーンテキストベースで説明。

| セクション | 用途 |
|:-----------|:------------|
|Settings|1) テストライブラリ, リソースファイル, 変数ファイル の取り込み<br />2) テストスイート や テストケース のメタデータの定義|
|Variables	|テストデータ中で使う 変数 の定義|
|Test Cases	|定義済みのキーワードを使った テストケース定義|
|Tasks | 定義済みのキーワードを使ったタスク定義。一つのファイルには Test Cases か　Tasks のどちらかしか使えない|
|Keywords	|既存の低水準キーワードを使った キーワード定義|
|Comments | 追加のコメントor データ。Robot Frameworkからは無視される。|

:::note info
Tasks と Comments
Robot Frameworks 3.1 から実装された Section. 
[Robot Framework 和訳・日本語ドキュメント集](http://hometrade.nomura.co.jp/web/rmfCmnEtcInvTopAction.do) は Version 3.0.1 をベースとしているため記載がないので注意。
:::

### サンプルコード
以下は [Robot Framework 公式にあるサンプルコード](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#test-data-syntax)。

```robot-framework:hello.robot
*** Settings ***
Documentation     Example using the space separated format.
Library           OperatingSystem

*** Variables ***
${MESSAGE}        Hello, world!

*** Test Cases ***
My Test
    [Documentation]    Example test.
    Log    ${MESSAGE}
    My Keyword    ${CURDIR}

Another Test
    Should Be Equal    ${MESSAGE}    Hello, world!

*** Keywords ***
My Keyword
    [Arguments]    ${path}
    Directory Should Exist    ${path}
```

### 実行結果
```shell
shakapon@AutomationTest:~/Trial/Robot$ robot hello.robot
==============================================================================
Hello :: Example using the space separated format.
==============================================================================
My Test :: Example test.                                              | PASS |
------------------------------------------------------------------------------
Another Test                                                          | PASS |
------------------------------------------------------------------------------
Hello :: Example using the space separated format.                    | PASS |
2 tests, 2 passed, 0 failed
==============================================================================
Output:  /home/shakapon/Trial/Robot/output.xml
Log:     /home/shakapon/Trial/Robot/log.html
Report:  /home/shakapon/Trial/Robot/report.html
```

### ちょっと読んでみる

#### Test Cases セクション
Robot Framework で実行する検証項目の本体がここ。テストケースごとにキーワードを書いていく。基本フォーマットはこんな感じ。

> *** Test Cases ***        # ヘッダ
>
> テストケース名1
> 　　キーワード1   引数1   引数2   ...
> 　　キーワード2   引数1   ...
> 　　...
>
> テストケース名2
> 　　...

この「キーワード」がテスト中の一つ一つの命令。テストライブラリやリソースファイルからインポートしたり、またテストケースファイル内のキーワードテーブルで作成できたりする。この例だと「My Keyword」はキーワードセクションで定義されているもの、`Log`、`Should Be Equal`、`Directory Should Exist` はビルトインキーワード。意味は英文そのまま。それぞれ「ログを出力する」、また「等しいこと」「ディレクトリが存在すること」の判定に使用。この辺りが「キーワード駆動型」とされる所以、なのかな？


https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#introduction-1

https://robotframework.org/robotframework/latest/libraries/OperatingSystem.html

:::note info
日本語版資料.
3.0.1 対象だが、以下で概ね日本語化されていた。最新版（6.1.1）で追加/削除されたものがあるかは未確認。

https://robotframework-ja.readthedocs.io/ja/latest/cheatsheet.html
:::

##### ${CURDIR}
テストデータファイルの置かれている場所への絶対パス。 この変数の値には大小文字の区別がある。
これは Robot Frameworkの組み込み変数の一つ。ほかにも、`${TEMPDIR}` や `${EXECDIR}`などがある。

#### Keyword セクション
既存のキーワードを組み合わせて新しく高水準のキーワードを作るには、キーワードテーブルを利用する。 新しく定義したキーワードは、テストライブラリの中で定義している、より低水準の ライブラリキーワード と区別するため、 ユーザキーワード と呼ぶ。

##### キーワードセクションの設定
ユーザキーワードは、 テストケースの設定 と似た設定を持たせられる。設定は、テストケースの場合と同様、角カッコを使った構文を使って、キーワードと区別する。 使える設定は以下の通り。

| セクション | 用途 |
|:-----------|:------------|
| [Documentation]| ユーザキーワードのドキュメント の設定に使用|
| [Tags]| キーワードの タグ の設定に使用|
| [Arguments]|ユーザキーワードの引数 の設定に使用|
| [Return]|ユーザキーワードの戻り値 の設定に使用|
| [Teardown]|ユーザキーワードのティアダウン の設定に使用|
| [Timeout]　| ユーザキーワードのタイムアウト の設定に使用| 

##### 今回の例
`[Arguments]` セッティングを利用して引数を指定。ビルトイン関数の`Directory Should Exist` で引数として指定されたディレクトリがあるかを判定する。ここでは引数としてカレントディレクトリを指定しているわけで、当然に成功する。

## Robot Framework Lint

Test Case の品質担保手段の一つとして Lint があるが、 Robot Frameworkにも lintはあった。

https://github.com/boakley/robotframework-lint/

```shell
pip install --upgrade robotframework-lint
```

```shell
$ rflint hello.robot
shakapon@AutomationTest:~/Trial/Robot$ rflint ./hello.robot
+ ./hello.robot
E: 16, 0: No testcase documentation (RequireTestDocumentation)
W: 15, 0: Too few steps (1) in test case (TooFewTestSteps)
E: 20, 0: No keyword documentation (RequireKeywordDocumentation)
W: 19, 0: Too few steps (1) in keyword (TooFewKeywordSteps)
```

文法違反ではないが、Linter が想定する推奨項目違反。Test Caseにドキュメントがない、Test Caseのステップ数が少なすぎる、というものが引っかかる。

いわれた通り
1. `[Documentation]`をちゃんと書く
2. 各試験項目の Step 数を増やす

すれば良い。2は試験を分割しすぎると分かりにくくなるってことなんだろうな。最小ステップ数は設定変更可能。無視したければこんな感じ。逆に Test Documantation を省略することは許してくれない様子。

```shell
$ rflint --configure TooFewKeywordSteps:1 --configure TooFewTestSteps:1 hello.robot
+ hello.robot
E: 16, 0: No testcase documentation (RequireTestDocumentation)
E: 20, 0: No keyword documentation (RequireKeywordDocumentation)
```


## Allure による結果表示の改善
Robot Framework では検証結果が HTML/XML で出力される。個別に見るより、過去の結果を管理し、進捗を終えるようにしたい。Robot Framework をローカルで動かしていれば report.html をそのまま見ればよいのだが、サーバで動かしているとそうもいかない。また、自動化された検証は繰り返される。過去の結果と比較したい。こういう時、report.html だけだとちょっとつらい。

というわけで、Test 結果のダッシュボードとして Allure を利用してみる。Robot Framework はテスト結果を XML形式でも出力してくれる。これを Allure 形式に Parse するプラグインがあり、それを利用。

### Allure 自体のインストール
無償版の範囲において、 Allure 自体は Webサーバ機能を持たない。ただ、それを支援するOSS 実装があり、その一つが Allure Docker Service.

https://github.com/fescobar/allure-docker-service

インストール自体は Qiita 内で分かりやすいのがあったのでそちらを参照。

https://qiita.com/shun198/items/bb76d1eb98bb7290a6a8

先の記事の通り、Allure/Allure Docker Service は docker-compose.yml を使ってインストール。ただ今回は Project単位で検証結果を分けたかったので、`volume`だけ変更した。
Allure インストール後、プロジェクトを作成。プロジェクト名は`robot-test-v1` とした。

```yaml:docker-compose.yml
version: '3'
services:
  allure:
    container_name: allure
    image: "frankescobar/allure-docker-service"
    environment:
      KEEP_HISTORY: 1
    ports:
      - "5050:5050"
    volumes:
       - /home/shakapon/Trial/Allure/projects:/app/projects

  allure-ui:
    container_name: allure-ui
    image: "frankescobar/allure-docker-service-ui"
    environment:
      ALLURE_DOCKER_PUBLIC_API_URL: "http://localhost:5050"
      ALLURE_DOCKER_PUBLIC_API_URL_PREFIX: ""
    ports:
      - "5252:5252"
```

### Allure への出力
で、Robot Frameworks 側の設定。Allure-rebotframework プラグインを利用する。

https://pypi.org/project/allure-robotframework/

入れ方は
```shell
pip install allure-robotframework
```

実際に使用する際は`--listner`オプションを指定して Allure フォーマットで結果を出力する。

```shell
robot --listener allure_robotframework:/home/shakapon/Trial/Allure/projects/robot-test-v1/results ./hello.robot
```

### 結果のコンパイルと結果表示

### Allure で結果コンパイル
Web ブラウザで http://localhost:5252 へアクセス。
左側のバーで「robot-test-v1」を選択後、GENERATE REPORT をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409463/286b347a-f0a3-ff55-c4bc-8b407518998d.png)

ダッシュボードとしてこんな感じに表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409463/457bd2e4-e812-32d6-64f5-1745fe3015df.png)

SUITES> Helloをドリルダウンすると、詳細な結果が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409463/8e17c8a5-8b19-00db-af51-a681f99a24db.png)

## 今後の展開
GitLAB/GitLAB Runner を使ったCI/CT 連携。Robot Framework 自体の文法調査。