まえおき
playwright-pytest を使ってE2Eテストを始める方法については、以前に以下の記事で紹介した。
ここでは、失敗時の画面キャプチャを撮る方法までは書いたが、実際に自動試験スクリプトを書いていると「どうしてそうなった?!」と思うことが稀によくある。(しかも、そんなテストに限って、じっと見張っていると何回やってもpassしたりするw)
不毛すぎるので、見張らなくてもいいようにエビデンス動画を残しておきたいと思うのがエンジニアである。
playwright-pythonで動画を撮る方法
playwright-python には、自動操作中の動画を記録する機能がある。
以下の記事でも言及されているように、 browser.new_context()
もしくは browser.new_page()
の引数に record_video_dir: ./videos/
のように指定すればいい。
ただ、これはplaywright-pythonの話であり、そのままplaywright-pytestでは運用できない。なぜかというと
- 成功時の動画はべつに要らない
- 失敗時の動画は「ディレクトリに置いてあるのを見ろ」だと面倒なので、Allureレポートに添付したい
(特に2つめの理由が大きい)
playwright-pytest でAllureレポートに失敗時の動画を添付する方法
本題。
動画を撮る
テスト開始時に、そのテストが開始するか失敗するかはわからないので、動画の記録自体は無条件に行う。
playwright-pytestのソースを見ると、new_contextに渡す引数は browser_context_args
でカスタマイズできるようになっているので、適当にconftest.pyあたりに以下を追加する。
@pytest.fixture(scope="session")
def browser_context_args(browser_context_args, tmpdir_factory: pytest.TempdirFactory):
return {
**browser_context_args,
"record_video_dir": tmpdir_factory.mktemp('videos')
}
record_video_dir
は一時ディレクトリを作って、テスト終了後には消える場所にしているのがポイント。
テスト失敗時のレポートに動画を添付する
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
)
video_path = page.video.path()
page.context.close() # ensure video saved
allure.attach(
open(video_path, 'rb').read(),
name=f"{slugify(item.nodeid)}.webm",
attachment_type=allure.attachment_type.WEBM
)
スクリーンショットを撮ったあとの video_path = ... からの処理が動画の記録部分。
Playwrightの動画記録は、BrowserContext#close したタイミングで書き込みが完了されるので、明示的にcloseを読んで動画ファイルを確定させてからattachしているのがポイント。
もし明示的にcloseを呼ばないと、0秒の動画が貼り付けられたり、手順の途中で切れた動画が添付されたりするので注意。
Allureレポートでは、以下のように、事象が起きたときの様子を見ることができる。
まとめ
Flakyテストを眺めるのがしんどくなってきたので、自動テストの動画を撮る方法を調べてまとめました。
これで自動テストを放置して、コンビニにコーヒーを買いに行ける!(笑)