pytest-asyncio のモードのデフォルト値が変わったよ&出戻りのご連絡

この記事を書いたメンバー:

那須 隆

pytest-asyncio のモードのデフォルト値が変わったよ&出戻りのご連絡

目次

みなさま、初めまして! 8/1 付けで BeeX に出戻り再入社した那須と申します。

アイキャッチ画像は神戸にあるしあわせの村の陸上競技場です。とても綺麗ですね。400m ジョグしてヘロヘロになりました。


出てから出戻るまで

スタートアップ企業で onedog という愛犬の健康管理などができるモバイルアプリのバックエンド/インフラエンジニア(やってた内容は SRE というらしい)と、New Relic という SaaS でオブザーバビリティを提供する会社でプリセールスをやっておりました。短い期間で役に立ってたかどうか怪しいですが、個人的には体験したことのないことを体験でき、関わった方々への感謝でいっぱいです。


これから

実際にサービス運用に関わったこととオブザーバビリティに触れたことで、モニタリングからさらに進化したサービスを考えたりそれを実際に定着するように BeeX の MSP サービスに関わって、お客様にとって価値のあるサービスを提供できるようがんばっていこうと思っています。

とはいってもまずは社内外から信頼してもらえるようになるところからだと思うので、小さなことからコツコツとやっていこうと思います。突然「これやれば劇的によくなります!」って言われても受け入れるの難しいですよね。

また、以前のように書いていたブログも初心に戻って書いていくつもりです。



では今回の共有内容です

FastAPI で作った API のテストをしようとしてずっこけたので、その内容と解決策を共有します。

pytest-asyncio を使ってローカルで非同期処理を含むテストをしようとしたら、こんなエラーが出ました。

$ docker-compose run --entrypoint "poetry run pytest" app
platform linux -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
 plugins: asyncio-0.19.0, anyio-3.6.1
 asyncio: mode=strict
======================================================= FAILURES =======================================================
 _________________________________________________ test_dayo _________________________________________________
~省略~
 >       response = await async_client.post("/tags", json={"title": "test-tag"})
 E       AttributeError: 'async_generator' object has no attribute 'post'
 
test_main.py:59: AttributeError
 =============================================== short test summary info ================================================
 FAILED test_main.py::test_dayo - AttributeError: 'async_generator' object has no attribute 'post'
 ================================================== 2 failed in 0.33s ===================================================
 ERROR: 1

これまでも asyncio でテストしたことがありますが、httpx のクライアントでエラーになることはなかったです。しかもクライアントに get や post がないだなんて… いつもと違うことといえば、asyncio のバージョンを何も考えずに最新化してしまったことくらいです(まあこれが原因なわけですが…

Release note を読んでみると、バージョン 0.19 から asyncio_mode のデフォルトが auto から strict に変わっていました。strict だと、@pytest.mark.asyncio と @pytest_asyncio.fixture が強制される的なことが書かれています。


Releases · pytest-dev/pytest-asyncio

Pytest support for asyncio. Contribute to pytest-dev/pytest-asyncio development by creating an account on GitHub.

github.com

og_img

というわけで、こうなっていた fixture のデコレータを↓

@pytest.fixture
async def async_client() -> AsyncClient:
    ...

こうする↓

import pytest_asyncio

@pytest_asyncio.fixture
async def async_client() -> AsyncClient:
    ...

すると無事にテスト実行できました。

 $ docker-compose run --entrypoint "poetry run pytest" app
 ================================================= test session starts ==================================================
 platform linux -- Python 3.9.13, pytest-7.1.2, pluggy-1.0
 plugins: asyncio-0.19.0, anyio-3.6.1
 asyncio: mode=strict
 
test_main.py ..                                                                                            [100%]
 
================================================== 2 passed in 0.40s ===================================================

poetry run pytest 実行時に asyncio mode を auto に上書き指定することでもいけるかもしれませんが、デフォルト値を変更するには理由があってのことだと思うので、テストコードの方を修正しました。


教訓

何も考えずにライブラリ等のバージョンを上げない(当たり前ですが)


こんな感じで初心を思い出してやっていきます。改めてよろしくお願いします! 

カテゴリー

SAPシステムや基幹システムのクラウド移行・構築・保守、
DXに関して
お気軽にご相談ください

03-6260-6240 (受付時間 平日9:30〜18:00)