playwright-pythonを使ってE2Eテストを始める

Playwright (TypeScript版)は microsoft/folio ベースのplaywright-testという独自フレームワークを使うが、playwright-pythonにはPyTest用のプラグインがある。

Pytest plugin for Playwright
https://github.com/microsoft/playwright-pytest

## Getting Started!

macOSであれば

playwright-pythonのインストール

```
brew install python3
pip3 install playwright
python3 -m playwright install
```

playwright-pytestのインストール

```
pip3 install pytest-playwright
```

VSCodeの人は [Pylance](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) を入れておきましょう。（メソッド名などの補完能力が格段にアップします）

これでテストできる環境が整う。

```github_YusukeIwaki_test.py
from playwright.sync_api import Page


def test_github(page: Page):
    page.goto('https://github.com/YusukeIwaki')
    assert page.query_selector('text="Yusuke Iwaki"') is not None
```

テストの実行は `pytest` するだけ。

```
$ pytest
================================================= test session starts ==================================================
platform darwin -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: /Users/yusuke-iwaki/Desktop/some_test
plugins: base-url-1.4.2, playwright-0.0.11
collected 1 item                                                                                                       

github_YusukeIwaki_test.py .                                                                                     [100%]

================================================== 1 passed in 3.49s ===================================================
```


## Allureを導入する

エンジニアであればコマンドラインの結果だけで十分だが、テスターフレンドリーではないので、レポートツールのAllureを入れる。

PyTest用のインテグレーションをインストールする。
https://github.com/allure-framework/allure-python

> 公式ドキュメント
> https://docs.qameta.io/allure/#_pytest
>
> Selenium + pytest + Allure の構成の参考記事
> https://qiita.com/YoshikiIto/items/cc018cb2d92d26bf1df6

macOSであれば以下を実行する。

```
brew install allure
pip3 install allure-pytest
```

あとは、 以下のコマンドのようにpytestを実行するだけ。

```
pytest --alluredir=hoge
allure serve hoge
```

テストスクリプトはなにも変更せずとも、まぁまぁおしゃれなレポートが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74571/0873c90e-f07f-6f71-a2e4-a82fa32229dc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74571/22691e10-b7d9-d42e-305d-3316716c0dc9.png)


### テストタイトルをわかりやすくする

Allureレポートで表示されるテストタイトルを変更するには、 `@allure.title` という専用のデコレータが用意されているので、これを利用する。
https://github.com/allure-framework/allure-python/pull/527

ちなみに、テストメソッド名を日本語にするという方法もなくはないが、メソッド名で使用できる文字に限りがあることから、 `@allure.title` を素直に使ったほうがよいだろう。

```github_YusukeIwaki_test.py
from playwright.sync_api import Page
import allure


@allure.title('GitHubでYusukeIwakiのページを確認する')
def test_github(page: Page):
    '''
    https: // github.com/YusukeIwaki へアクセスし、
    "Yusuke Iwaki" の表示があることを確認する。
    '''
    page.goto('https://github.com/YusukeIwaki')
    assert page.query_selector('text="Yusuke Iwaki"') is not None
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74571/7ebcac85-fce1-9b83-4e2e-1d3292dcd3e0.png)

allure.titleがタイトルになり、docstringがdescriptionになる。

### テストが落ちたときに、スクリーンショットをAllureに貼り付ける

playwright-pytestのドキュメントには、失敗時に特定のディレクトリに画面キャプチャを格納する手順が書かれている。が、特定のディレクトリに置かれても、どのケストケースの失敗画面か、紐付けて管理するのが面倒だ。
https://github.com/microsoft/playwright-pytest#screenshot-on-test-failure

Allure上にスクリーンショットを残す手順は、Seleniumでの模範手順があったのでありがたく拝借
https://stackoverflow.com/questions/29929244/how-to-add-a-screenshot-to-allure-report-with-python

`pip3 install python-slugify` して、

```conftest.py
from playwright.sync_api import Page
import allure
from slugify import slugify


# Screenshot on test failure
# https://github.com/microsoft/playwright-pytest#screenshot-on-test-failure
def pytest_runtest_makereport(item, call) -> None:
    if call.when == "call":
        if call.excinfo is not None and "page" in item.funcargs:
            page: Page = item.funcargs["page"]

            # ref: https://stackoverflow.com/q/29929244
            allure.attach(
                page.screenshot(type='png'),
                name=f"{slugify(item.nodeid)}.png",
                attachment_type=allure.attachment_type.PNG
            )
```

これで、テストが落ちると、以下のようにAllure上でそのときの画面が確認できる。便利。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74571/aa71e3b3-ec86-1fbf-7d30-717c52c2a809.png)

## まとめ

playwright-python, playwright-pytestがあれば、前準備がほとんど不要でE2Eテストをサクッと書き始めることができます。
Allureを使えば、テスターフレンドリーなレポートも出力できますし、「つくってみた」レベルではなく実運用でもなかなかいい感じです。