Python学習【365日チャレンジ!】195日目のマスターU(@Udemy11)です。
近所の方からスイカを一玉いただきました。
普段なら、普通に切って、皮が付いたままかぶりつくのですが、今回は趣向を変えて、フルーツミックスとしてスーパーで売っているような感じで一口サイズにカットしていただきました。
思った以上に食べやすくて、甘かったので、ついつい食べすぎて、お腹がパンパンになってしまいました。
スイカはほぼ水分なので、体重が増えてしまいましたが、明日になればもとに戻っているような気がします。
ほんとこの時期のスイカってめっちゃ美味しいですよね。
それでは、今日もPython学習をはじめましょう。
昨日の復習
昨日はUIテストができるseleniumを使ってPython.orgのWebページを操作してみました。
Webブラウザーを立ち上げて、検索窓に入力したり、その結果がどのようになるのかをテストしたりしました。
ユーザーが実際にWebページでマウスを操作するような動作をテストすることができるので、リモート操作をしているような感じでしたね。
具体的なseleniumの使い方については、昨日の記事を参考にしてください。
今日は、外部のAPIなどから帰ってくる値を擬似的に取得してテストを実行するmockを学習します。
mock
mockは、作成するコードの中に、外部のサービスを利用して値を取得してくるコードがある場合、擬似的に返される値を指定してテストを実行することができるオブジェクトライブラリです。
10年ほど前なら携帯ショップにおいていた実際には使えない見本の携帯がモックと言われていましたが、最近では、見本のスマホは普通に使えますよね。
mockは、【模造品】、【まがい物】という意味ですが、Pythonのmockも実際の処理をせずに返り値だけ模擬的に取得するという意味では、mockの意味そのままですね。
mockを使ったテストの簡単な具体例をみていきましょう。
salary.py
今回のメインファイルは、salary.py
として、外部のサービスからボーナスの金額を取得して、月給と合わせた金額を計算するコードを書いています。
import requests
class BonusApi(object):
def bonus_price(self, year):
req = requests.get('http://localhost/bonus', params={'year': year})
return req.json()['price']
class Salary(object):
def __init__(self, base=50, year=2020):
self.bonus_api = BonusApi()
self.base = base
self.year = year
def cal_salary(self):
bonus = self.bonus_api.bonus_price(year=self.year)
return self.base + bonus
以前学習したrequests
をインポートして、3行目から6行目でhttp://localhost/bonus
からjsonファイルのprice
を取得する関数を作成しています。
このときにサーバーから取得するjsonは、{'price': 100}
というような値が入っているファイルを想定しています。
8行目からは、Salaryクラスを作成してBounusApi
から取得した値とbase
、year
をself変数に代入、14行目から16行目で代入した値を使って、base
とbonus
をあわせた金額を返すcal_salary
のコードを記述しています。
test_salary.py
salary.py
をテストするのがtest_salary.py
です。
通常のテストなら、外部サービスにアクセスして値が返されているか確認しますが、サーバーがダウンしていたり、自社のサービスでまだ完成していないけれど取得できる情報が決まっているときなどにmockを使って仮の値を入れてテストすることができます。
それでは、テストコードを書いてみましょう。
import unittest
from unittest.mock import MagicMock
import salary
class TestSalary(unittest.TestCase):
def test_cal_salary(self):
s = salary.Salary()
s.bonus_api.bonus_price = MagicMock(return_value=100)
self.assertEqual(s.cal_salary(), 150)
単独のサードパーティーライブラリだと思っていたのですが、mockってunittestの一部だったんですね。
最初にunittestとMagicMock、salary.pyをインポートして、TestSalaryクラスを作成します。
11行目で本来外部サービスから取得するメインファイルのbonus.price
の値にMagicMock
を使って100
を代入して12行目で計算結果が150
になるかどうかをテストしています。
実行結果
デバッグを使って実行してみると、外部サービスから取得する値のbonus_api.bonus_price
にMagicMock
で代入した100が入っているのがわかるかと思います。
APIを使いこなしたい
外部サービスから情報を取得するAPIはたくさんあるので、使いこなせるようになればかなりレベルアップすること間違いなしです。
仕組みをきっちりと理解して使いこなすためには、まだまだ時間がかかりそうですが、プログラムを学習する上で、避けて通れない道ですので、じっくり学んでいこうと思います。
今回学習したmockは、外部サービスを使ったプログラムには必要不可欠のテストなので、他の使い方も含めて明日から学習していきます。
それでは、明日もGood Python!