使用 py.test 對 python 代碼進行測試

其實之前我記得有人對我說過,寫代碼甚至能夠先寫完測試以後部署好了再開始寫邏輯代碼。我以爲有點吃驚和奇怪,這不是扯淡嗎?html

可是此次在完成了積分支付第一階段開發以後我意識到,這可能並非開玩笑,特別是項目可能還涉及到之前的代碼進行遷移,如何保證代碼遷移以後還能繼續正常運行?python

越是大的項目,在這個上面的維護成本就越高,若是是一人開發,既要負責測試又要負責開發,沒有單元測試對這種任務來講簡直就是災難。git

以前在編寫openapi模塊的時候也爲那邊的代碼寫過測試,可是對py.test也沒有使用什麼其它的特性,此次用到感受比較通用的幾個函數和用法因此紀錄一下。api

 

上個例子:數組

import pytest
@pytest.mark.parametrize("package_price, package_ident, begin_time, end_time", [ (-800, 1, datetime.datetime.now(), datetime.datetime.now()+datetime.timedelta(days=30)), (800, 1, datetime.datetime.now(), datetime.datetime.now()+datetime.timedelta(days=30)), ], ids=["-錢購買愛嚐鮮", "+錢購買愛嚐鮮"])

來分析一下這個pytest.mark.parametrize("", [])python2.7

第一個字符串參數裏面能夠傳你想要初始化的字段name以逗號分隔,注意它們都在一個字符串裏。ide

後面的數組以tuple爲一個元素,每一個tuple裏面能夠初始化在前面string裏面寫的各參數,一樣以逗號分隔。函數

ids是能夠指定單組參數也就是一個tuple爲一個單位的這組測試用例的id,這個會在測試的時候顯示出來就像這樣。單元測試

這樣咱們就能經過本身手動構造參數愉快的開始測試了。測試

可是其實除了這種簡單的參數,真正在測試的時候是比較難構造的是指定的obejct對象。

 

這裏能夠引入一個叫mock的庫

下面看個例子

from mock import MagicMock
order = MagicMock(id=order_id, shop_id=shop_id, user_id=user1.id, finish_time=order_finish_time)
gio = MagicMock(id=gio_id, order_id=order_id, goods_id=goods_id, goods_type=goods_type,
                    user_id=user1.id, shop_id=shop_id,
                    is_allowed_to_review=lambda: True, is_reviewed=lambda: False, order=order,
                    goods_paid_cash_amount=goods_paid_cash_amount)
gio.__class__ = GoodsInOrder

你用一個叫mock的庫來輕易構造那些看似複雜的須要傳遞大量參數的對象。上面那些參事能夠在parametrize裏面構造好而後傳入MagicMock裏要初始化的對象裏面去,就能按照你的想法初始化出這個對象。給測試帶來極大便利。

mock庫在python3.4中已加入標準庫。不過在python2.7裏面還須要經過pip install mock安裝。

 

下面貼上一個完整的例子.

@pytest.mark.parametrize("package_price, package_ident, begin_time, end_time", [
    (-800, 1, datetime.datetime.now(), datetime.datetime.now()+datetime.timedelta(days=30)),
    (800, 1, datetime.datetime.now(), datetime.datetime.now()+datetime.timedelta(days=30)),
], ids=["-錢買不起愛嚐鮮", "+錢也買不起愛嚐鮮"])
def test_can_not_buy_fresh_member(package_price, package_ident, begin_time, end_time, user4):
    with pytest.raises(NoEnoughAvailablePoints):
        decrease_points_by_fresh_member(user4.id, package_price, package_ident, begin_time, end_time)

 

 Reference:

https://wangshunping.gitbooks.io/testing_python/content/chapter3/Mock_and_Patch.html  Mock和Patch小技巧

相關文章
相關標籤/搜索