タダです.
以前から気になっていた moto
というツールを試す機会があったので,この記事で導入と pytest と組み合わせたテストをチュートリアルの内容を通して見ていきたいと思います.
moto って?
moto
とはテストで AWS サービスをモックで作っていくための Python ライブラリです.
導入はpip
でさくっとできます.なお,moto
は全ての AWS サービスを呼び出す関数を網羅しているわけではなさそうなので,その点は注意です.
$ pip install moto
moto が対応しているサービス一覧 github.com
moto でモックを作り pytest でテストする
それでは, moto
を使ってみようと思います.
$ pipenv install boto3
$ pipenv install --dev pytest moto
以下のようなディレクトリ切って,app.py
とそのテストをするためのtest.py
を作りました.
.
├── app
│ ├── app.py
│ └── __init__.py
└── tests
├── __init__.py
└── test.py
チュートリアルとして S3 に put_object
を実行する save
関数があるコードを用意しました.
import boto3 class MyModel(object): def __init__(self, name, value): self.name = name self.value = value def save(self): s3 = boto3.client('s3', region_name='ap-northeast-1') s3.put_object(Bucket='mybucket', Key=self.name, Body=self.value)
テスト用コードとしては次のものを用意しました.@mock_s3
を記述することで S3 へのアクセスをモックしてくれてます.save
関数を呼んで,オブジェクトを読みファイルの中身がis awesome
かを確認するようになっています.
import boto3 from moto import mock_s3 from app.app import MyModel @mock_s3 def test_my_model_save(): conn = boto3.resource('s3', region_name='ap-northeast-1') conn.create_bucket(Bucket='mybucket',CreateBucketConfiguration={ 'LocationConstraint':'ap-northeast-1' }) model_instance = MyModel('steve', 'is awesome') model_instance.save() body = conn.Object('mybucket', 'steve').get()[ 'Body'].read().decode("utf-8") assert body == 'is awesome'
テストコードを走らせてみたところテストをパスしたのを確認できました.
$ pipenv run pytest tests/test.py =============================================================================== test session starts =============================================================================== platform linux -- Python 3.7.9, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 rootdir: /xxxx/xxxx/environment collected 1 item tests/test.py . [100%] ================================================================================ warnings summary ================================================================================= ../.local/share/virtualenvs/environment-QZ1wNgYc/lib64/python3.7/distutils/__init__.py:1 /xxxx/xxxx/.local/share/virtualenvs/environment-QZ1wNgYc/lib64/python3.7/distutils/__init__.py:1: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses import imp -- Docs: https://docs.pytest.org/en/stable/warnings.html ========================================================================== 1 passed, 1 warning in 0.69s ===========================================================================
まとめ
簡単になりますが,moto
を使ったテストコードを書くことをやってみました.AWS リソースを作ってまで確認するとコストがかかって確認が遅くなってしまうような状況ならこう言ったツールを作って素早く確認して行けると良さそうです.