<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 8759字,需瀏覽 18分鐘

           ·

          2020-12-07 11:16

          點(diǎn)擊上方“測(cè)試開(kāi)發(fā)技術(shù)”,選擇“加為星標(biāo)

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

          1. 背景

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

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

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

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

          2. Mock是什么

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

          Mock簡(jiǎn)單來(lái)理解,就是在測(cè)試過(guò)程中,對(duì)于某些不容易構(gòu)造或者不容易獲取的對(duì)象,用一個(gè)虛擬的對(duì)象來(lái)創(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常用來(lái)解決的幾類,概括起來(lái),主要有:

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

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

          比如你是一個(gè)前端頁(yè)面開(kāi)發(fā),現(xiàn)在需要開(kāi)發(fā)一個(gè)功能:下一個(gè)訂單,支付頁(yè)面的接口,根據(jù)支付結(jié)果,支付成功,展示支付成功頁(yè),支付失敗,展示支付失敗頁(yè)。要完成此功能,你需要調(diào)用后端的接口,根據(jù)返回給你的結(jié)果,來(lái)展示不同的頁(yè)面。此時(shí)后端接口還沒(méi)開(kāi)發(fā)好,作為一個(gè)前端開(kāi)發(fā)總不能等別人開(kāi)發(fā)好了,你再開(kāi)發(fā),那你只有加班的命了。為了同步開(kāi)發(fā)完成任務(wù),此時(shí),你可以根據(jù)接口文檔的規(guī)定,把接口的地址和入?yún)鬟^(guò)去,然后自己mock接口的不同返回界面,來(lái)完成前端的開(kāi)發(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ù)給你開(kāi)著,別人就關(guān)掉了,給自動(dòng)化接口測(cè)試帶來(lái)很多的麻煩,此時(shí)就可以通過(guò)mock來(lái)模擬接口的返回?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ù),需要通過(guò)Mock來(lái)替換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ù)就可以了。

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

          5. Mock市面上常見(jiàn)的解決方案

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

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

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

          接下來(lái),重點(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)入過(guò)來(lái)就行

          from unittest import mock

          官方文檔:

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

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

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

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

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

          def zhifu():
              '''假設(shè)這里是一個(gè)支付的功能,未開(kāi)發(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è)同事開(kāi)發(fā),正常情況下,你同事開(kāi)發(fā)的進(jìn)度你是無(wú)法控制的,需要等他開(kāi)發(fā)完了你才能進(jìn)行聯(lián)調(diào)你所負(fù)責(zé)的zhifu_statues接口,因此我們可以通過(guò)引入Mock來(lái)解決這個(gè)問(wèn)題。

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

          # !/usr/bin/python3
          # -*- coding: utf-8 -*-
          # @Author : Mike Zhou
          # @Email : 公眾號(hào):測(cè)試開(kāi)發(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)方式,通過(guò)patch裝飾器的使用,patch作為函數(shù)裝飾器,為您創(chuàng)建模擬并將其傳遞到裝飾函數(shù)。

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

          # !/usr/bin/python3
          # -*- coding: utf-8 -*-
          # @Author : Mike Zhou
          # @Email : 公眾號(hào):測(cè)試開(kāi)發(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()


          還有更多的使用技巧,篇符有限,今天就先分享到這,如果覺(jué)得有用,幫忙點(diǎn)個(gè)好看朋友圈轉(zhuǎn)發(fā)分享一下就行!


          作者新書

          新書資訊新書除了紙質(zhì)圖書外,電子版也已在京東、當(dāng)當(dāng)網(wǎng)上線了。


          (點(diǎn)擊直達(dá)小程序)


          推薦閱讀


          重磅消息 |《自動(dòng)化測(cè)試實(shí)戰(zhàn)寶典:從小工到專家》隆重上市!

          推薦一款萬(wàn)能抓包神器:Fiddler Everywhere

          推薦一款技術(shù)人必備的接口測(cè)試神器:Apifox

          推薦一款Python開(kāi)源庫(kù),技術(shù)人必備的造數(shù)據(jù)神器!

          重磅消息 | 2020年最新全棧測(cè)試開(kāi)發(fā)技能實(shí)戰(zhàn)指南(第1期)


          END

          所有原創(chuàng)文章
          第一時(shí)間發(fā)布至此公眾號(hào)「測(cè)試開(kāi)發(fā)技術(shù)」

          長(zhǎng)按二維碼/微信掃碼  關(guān)注


          關(guān)注后,回復(fù)「me」試試
          點(diǎn)擊閱讀原文
          瀏覽 19
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费黄色电影网站在线观看 | 国产极度色诱视频在线观看 | 在线视频第一页 | 操B电影| 午夜理理伦电影A片无码蜜桃av |