小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

測(cè)試開發(fā)工程師必備技能分享:Mock的使用技巧

 測(cè)試開發(fā)技術(shù) 2022-06-18 發(fā)布于廣東

優(yōu)質(zhì)文章,第一時(shí)間送達(dá)!

1. 背景

在實(shí)際產(chǎn)品開發(fā)過程中,某個(gè)服務(wù)或前端依賴一個(gè)服務(wù)接口,該接口可能依賴多個(gè)底層服務(wù)或模塊,或第三方接口,比如說服務(wù) A 依賴服務(wù)B,服務(wù)B又依賴服務(wù) C,如下圖所示:

這種依賴的問題會(huì)導(dǎo)致原本的需求目的是要驗(yàn)證服務(wù)A,但由于所依賴的服務(wù)B或者服務(wù)C不穩(wěn)定或者未開發(fā)完成,導(dǎo)致工作無法正常開展。

那作為測(cè)試工程師,面對(duì)這樣的情形,我們?cè)撛趺崔k呢?解決這類問題的核心的思路:引入依賴服務(wù)替身,更通俗的叫法,引入Mock服務(wù)。

今天就結(jié)合unittest框架,給大家分享一些關(guān)于Mock的一些常見使用。

2. Mock是什么

可能還有些讀者之前并沒有接觸過Mock,不清楚Mock是個(gè)啥。

Mock簡(jiǎn)單來理解,就是在測(cè)試過程中,對(duì)于某些不容易構(gòu)造或者不容易獲取的對(duì)象,用一個(gè)虛擬的對(duì)象來創(chuàng)建以便測(cè)試。而這個(gè)虛擬的對(duì)象就是mock對(duì)象。mock對(duì)象就是真實(shí)對(duì)象在調(diào)試期間的代替品。

有時(shí)也將Mock服務(wù)稱之為測(cè)試服務(wù)替身,或者測(cè)試服務(wù)檔板,下圖很形象的描述了Mock的作用。

3. Mock能做什么

就Mock功能而言,本身適用場(chǎng)景較多,但在實(shí)際項(xiàng)目中,引入Mock常用來解決的幾類,概括起來,主要有:

  • 接口間的相互依賴
  • 單元測(cè)試
  • 第三方接口調(diào)用

1.前后端聯(lián)調(diào)

比如你是一個(gè)前端頁(yè)面開發(fā),現(xiàn)在需要開發(fā)一個(gè)功能:下一個(gè)訂單,支付頁(yè)面的接口,根據(jù)支付結(jié)果,支付成功,展示支付成功頁(yè),支付失敗,展示支付失敗頁(yè)。要完成此功能,你需要調(diào)用后端的接口,根據(jù)返回給你的結(jié)果,來展示不同的頁(yè)面。此時(shí)后端接口還沒開發(fā)好,作為一個(gè)前端開發(fā)總不能等別人開發(fā)好了,你再開發(fā),那你只有加班的命了。為了同步開發(fā)完成任務(wù),此時(shí),你可以根據(jù)接口文檔的規(guī)定,把接口的地址和入?yún)鬟^去,然后自己mock接口的不同返回界面,來完成前端的開發(fā)任務(wù)。

2.單元測(cè)試

由于單元測(cè)試僅針對(duì)當(dāng)前單元進(jìn)行測(cè)試,這就要求所有的內(nèi)部或者外部依賴都應(yīng)該是穩(wěn)定的,采用mock的方法模擬跟本單元依賴的其他單元,可以將測(cè)試重點(diǎn)放在當(dāng)前單元功能,排除外界因素干擾,提升測(cè)試精準(zhǔn)度。

3.第三方接口依賴

在做接口自動(dòng)化的時(shí)候,有時(shí)候需要調(diào)用第三方的接口,但是別人公司的接口服務(wù)不受你的控制,有可能別人提供的測(cè)試環(huán)境今天服務(wù)給你開著,別人就關(guān)掉了,給自動(dòng)化接口測(cè)試帶來很多的麻煩,此時(shí)就可以通過mock來模擬接口的返回?cái)?shù)據(jù),比如模擬各種第三方異常時(shí)的返回。

4. Mock實(shí)現(xiàn)方式

Mock雖然是作為依賴服務(wù)的替身,但并不需要原原本本去構(gòu)造實(shí)現(xiàn)一個(gè)完整的服務(wù)邏輯,比如現(xiàn)在有一個(gè)A服務(wù)依賴B服務(wù),需要通過Mock來替換B服務(wù)(做一個(gè)假的B服務(wù)替身)。

那么我們做一個(gè) Mock 服務(wù)其實(shí)就是做了一個(gè)簡(jiǎn)單的服務(wù) B,它不需要實(shí)現(xiàn)原有服務(wù) B 負(fù)載的處理邏輯,只要能按服務(wù)A需要服務(wù)B返回的處理邏輯給出對(duì)應(yīng)返回?cái)?shù)據(jù)就可以了。

目前常見服務(wù)或接口協(xié)議主要兩種,一種是RPC,另一種是HTTP/HTTPS,mock原理都類似,要么是修改原服務(wù)地址為Mock服務(wù)地址,要么是攔截原服務(wù)的請(qǐng)求Mock返回值,總之就是構(gòu)造一個(gè)假的服務(wù),替代原有服務(wù)。

5. Mock市面上常見的解決方案

如果你不想自己動(dòng)手構(gòu)建一套Mock解決方案,市面上也提供了很多現(xiàn)存的Mock方案。常用的有:EasyMock、MockitoWireMock、JMockitMock、Moco。

如果你團(tuán)隊(duì)技術(shù)基礎(chǔ)相對(duì)比較薄弱,推薦你看看Moco這個(gè)方案,官網(wǎng)如下:

https://github.com/dreamhead/moco/

接下來,重點(diǎn)介紹Python系下Mock方案的使用。

6. Python下unittest.mock使用

unittest.mock是一個(gè)用于在Python中進(jìn)行單元測(cè)試的庫(kù),顧名思義這個(gè)庫(kù)的主要功能是模擬一些東西。它的主要功能是使用mock對(duì)象替代掉指定的Python對(duì)象,以達(dá)到模擬對(duì)象的行為。

需要注意的是在Python2.x版本中,Mock需要單獨(dú)安裝

pip install -U mock

從Python 3.3以后的版本mock已經(jīng)合并到unittest模塊中了,是unittest單元測(cè)試的一部分,直接導(dǎo)入過來就行

from unittest import mock

官方文檔:

https://docs./dev/library/unittest.mock.html

unittest.mock模塊中最常用的是Mock類。

Mock類庫(kù)是一個(gè)專門用于在unittest過程中制作(偽造)和修改(篡改)測(cè)試對(duì)象的類庫(kù),避免這些對(duì)象在單元測(cè)試過程中依賴外部資源(網(wǎng)絡(luò)資源,數(shù)據(jù)庫(kù)連接,其它服務(wù)以及耗時(shí)過長(zhǎng)等)

案例:如下場(chǎng)景:支付是一個(gè)獨(dú)立的接口,由其它開發(fā)提供,根據(jù)支付的接口返回狀態(tài)去顯示失敗,還是成功,這個(gè)是你需要實(shí)現(xiàn)的功能,代碼存放在pay.py腳本中:

# !/usr/bin/python3
# -*- coding: utf-8 -*-
# @Author : Mike Zhou
# @Email : 公眾號(hào):測(cè)試開發(fā)技術(shù)
# @File : pay.py

def zhifu():
    '''假設(shè)這里是一個(gè)支付的功能,未開發(fā)完
    支付成功返回:{"result": "success", "msg":"支付成功"}
    支付失敗返回:{"result": "fail", "msg":"余額不足"}
    '
''
    pass

def zhifu_statues():
    '''根據(jù)支付的結(jié)果success or fail,判斷跳轉(zhuǎn)到對(duì)應(yīng)頁(yè)面'''
    result = zhifu()
    try:
        if result["result"] == "success":
            return "支付成功"
        elif result["result"] == "fail":
            return "支付失敗"
        else:
            return "未知錯(cuò)誤異常"
    except:
        return "Error, 服務(wù)端返回異常!"

在zhifu_statues方法中,依賴了zhifu方法,但由于zhifu支付方法的接口是由另外一個(gè)同事開發(fā),正常情況下,你同事開發(fā)的進(jìn)度你是無法控制的,需要等他開發(fā)完了你才能進(jìn)行聯(lián)調(diào)你所負(fù)責(zé)的zhifu_statues接口,因此我們可以通過引入Mock來解決這個(gè)問題。

引入mock后單元測(cè)試用例代碼

# !/usr/bin/python3
# -*- coding: utf-8 -*-
# @Author : Mike Zhou
# @Email : 公眾號(hào):測(cè)試開發(fā)技術(shù)

import unittest
from unittest import mock
import pay

class TestZhifuStatues(unittest.TestCase):
    '''單元測(cè)試用例'''
    def test_01(self):
        '''測(cè)試支付成功場(chǎng)景'''
        # mock一個(gè)支付成功的數(shù)據(jù)
        pay.zhifu = mock.Mock(return_value={"result""success""msg":"支付成功"})
        # 根據(jù)支付結(jié)果測(cè)試頁(yè)面跳轉(zhuǎn)
        statues = pay.zhifu_statues()
        print(statues)
        self.assertEqual(statues, "支付成功")

    def test_02(self):
        '''測(cè)試支付失敗場(chǎng)景'''
        # mock一個(gè)支付失敗的數(shù)據(jù)
        pay.zhifu = mock.Mock(return_value={"result""fail""msg""余額不足"})
        # 根據(jù)支付結(jié)果測(cè)試頁(yè)面跳轉(zhuǎn)
        statues = pay.zhifu_statues()
        print(statues)
        self.assertEqual(statues, "支付失敗")

if __name__ == "__main__":
    unittest.main()

上述代碼引入Mock后,我們就可以順利完成對(duì)支付成功和支付異常兩類場(chǎng)景的驗(yàn)證工作。(實(shí)際你可以補(bǔ)充更多)

mock中還有另一種實(shí)現(xiàn)方式,通過patch裝飾器的使用,patch作為函數(shù)裝飾器,為您創(chuàng)建模擬并將其傳遞到裝飾函數(shù)。

用mock.patch實(shí)現(xiàn)如下:

# !/usr/bin/python3
# -*- coding: utf-8 -*-
# @Author : Mike Zhou
# @Email : 公眾號(hào):測(cè)試開發(fā)技術(shù)


import unittest
from unittest import mock
import pay

class TestZhifuStatues(unittest.TestCase):
    '''單元測(cè)試用例'''

    @mock.patch("pay.zhifu")
    def test_001(self, mock_zhifu):
        '''測(cè)試支付成功場(chǎng)景'''
        # 方法一:mock一個(gè)支付成功的數(shù)據(jù)
        # pay.zhifu = mock.Mock(return_value={"result": "success", "msg":"支付成功"})
        # print(pay.zhifu())

        # 方法二:mock.path裝飾器模擬返回結(jié)果
        mock_zhifu.return_value = {"result""success""msg":"支付成功"}

        # # 根據(jù)支付結(jié)果測(cè)試頁(yè)面跳轉(zhuǎn)
        statues = pay.zhifu_statues()
        print(statues)
        self.assertEqual(statues, "支付成功")

    @mock.patch("pay.zhifu")
    def test_002(self, mock_zhifu):
        '''測(cè)試支付失敗場(chǎng)景'''
        # mock一個(gè)支付失敗的數(shù)據(jù)

        mock_zhifu.return_value = {"result""fail""msg""余額不足"}
        # 根據(jù)支付結(jié)果測(cè)試頁(yè)面跳轉(zhuǎn)
        statues = pay.zhifu_statues()
        self.assertEqual(statues, "支付失敗")

if __name__ == "__main__":
    unittest.main()

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多