概要
motoをつかってboto3のテストをしてみたいと思います。
そもそもmotoとは
AWSサービスのモックをつくることができるやつです。
mock botoでmotoです(たぶん)
motoでテストしてみる
実際にやってみます。
こんかいはS3にオブジェクトを置くスクリプトのテストをしてみます。
motoのインストール
pip
でできます。
pip install moto
テストされる.py
S3にオブジェクトを置くだけのスクリプトです。
import boto3
class s3(object):
def __init__(self, name, value):
self.name = name
self.value = value
def put(self):
s3 = boto3.client('s3', region_name='ap-northeast-1')
s3.put_object(Bucket='mybucket', Key=self.name, Body=self.value)
テストする.py
オブジェクトをGETして中身が正しいかどうかを確かめています。
kabegiwa_blogという名前のオブジェクトの中身がawesomeであればOKです。
import boto3
from moto import mock_s3
from put_object import s3
@mock_s3
def test_put_object():
conn = boto3.resource('s3', region_name='ap-northeast-1')
conn.create_bucket(Bucket='mybucket')
model_instance = s3('kabegiwa_blog', 'is awesome')
model_instance.put()
body = conn.Object('mybucket', 'kabegiwa_blog').get()['Body'].read().decode("utf-8")
assert body == 'is awesome'
test_put_object()
実際にテストしてみる
テストしてみます。
テストする.pyを実行します。
わかりやすくするためにpytestを利用します。
pytestについてはまえにかきました。
www.kabegiwablog.com
テストがとおっていることがわかる。
pytest -v test_put_object.py
=== test session starts ===
platform win32 -- Python 3.7.4, pytest-5.2.1, py-1.8.0, pluggy-0.13.0 -- c:\users\takak\appdata\local\programs\python\python37-32\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\takak\Downloads\moto_test
collected 1 item
test_put_object.py::test_put_object PASSED [100%]
テストする.pyのassertの部分を以下のように変えてもう一度テストしてみます。
assert body == 'is not awesome'
テスト実行するとエラーになっていることがわかります。
pytest -v .\test_put_object.py
=== test session starts ===
platform win32 -- Python 3.7.4, pytest-5.2.1, py-1.8.0, pluggy-0.13.0 -- c:\users\takak\appdata\local\programs\python\python37-32\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\takak\Downloads\moto_test
collected 0 items / 1 errors
=== ERRORS ===
____ ERROR collecting test_put_object.py ___
test_put_object.py:18: in <module>
test_put_object()
..\..\appdata\local\programs\python\python37-32\lib\site-packages\moto\core\models.py:80: in wrapper
result = func(*args, **kwargs)
test_put_object.py:16: in test_put_object
assert body == 'is not awesome'
E AssertionError: assert 'is awesome' == 'is not awesome'
結局なにこれ?
mockなのでmybucketというAWSサービスはつくられていないです。
そしてオブジェクトも作成されていないです。
というかそんなバケット名はたぶんもうすでにつかわれているのでつくれないです。
でもなぜテストがとおったか(バケットからオブジェクトをGETできたか)というとmotoが仮想的にmockをつくって応答してくれているからです。
boto3のテストを実施するときはだいたいスクリプトを動かしてはAWSリソースを消してーとか、既存のものに影響がないように気をつけなくちゃーとかやっていたけれど、これを使うことでそういうことを気にしなくて良くなります。
注意点
すべてのAWSリソースがテストできるわけではないです
以下にいろいろかいてあります。
github.com
おわりに
kabegiwa_blog is awesome.