成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一日一技:如何正確為歷史遺留代碼補(bǔ)充單元測試?

開發(fā) 項目管理
如果你的項目是從一開始就寫單元測試,那么你寫起來應(yīng)該輕松又愉快,因為單元測試會促使你的代碼自身變成可測試的代碼。

我們知道,在軟件工程中,單元測試是保證軟件質(zhì)量的重要手段之一。一個優(yōu)秀的代碼,單元測試的代碼量,經(jīng)常會超過被測試的代碼本身。一個理想化的開發(fā)團(tuán)隊,可能有三分之二的時間是在寫測試,剩下的三分之一時間才是寫業(yè)務(wù)代碼。

如果你的項目是從一開始就寫單元測試,那么你寫起來應(yīng)該輕松又愉快,因為單元測試會促使你的代碼自身變成可測試的代碼。

但如果你接手了一個大項目,里面已經(jīng)有幾十萬行代碼了,那么給這些代碼補(bǔ)單元測試會讓你知道什么叫做痛不欲生。你會發(fā)現(xiàn)有一些函數(shù),它讓你不知道怎么寫測試代碼。但你又不能隨便修改代碼的結(jié)構(gòu),誰知道會引起什么連鎖反應(yīng)?

我們來看一個例子:

圖片

我想測試的是business_code?里面,check_data_dup分別返回True或者False的時候,下面代碼的邏輯。也就是說,我只關(guān)心第18-27行的邏輯。這個時候不關(guān)心MySQL和Redis。但是每次測試都要從他們里面讀取數(shù)據(jù),這樣就會導(dǎo)致測試代碼依賴外部環(huán)境。如果MySQL或者Redis掛了,那么測試代碼就會運(yùn)行失敗。

而且,就算Redis和MySQL沒有故障,你怎么知道你的data_id和pk,在數(shù)據(jù)庫中對應(yīng)的是什么數(shù)據(jù)?為了分別走到特定的分支,你還需要去檢測數(shù)據(jù)庫中特定數(shù)據(jù)的id。萬一是測試環(huán)境,別人修改了里面的數(shù)據(jù),你的測試也可能會掛掉。

如果直接使用Pytest來寫測試案例,代碼是這樣的:

圖片

可以看到,我運(yùn)行Pytest以后,成功了一個,失敗了一個。這里我模擬出數(shù)據(jù)庫中沒有數(shù)據(jù)能夠讓check_data_dup?走到返回True邏輯的情況。

難道為了讓單元測試進(jìn)行下去,我還要去數(shù)據(jù)庫構(gòu)造一條特定的數(shù)據(jù)?這只是單元測試,又不是集成測試。

為了解決這個問題,我們就可以使用mock模塊。這是Python自帶的一個模塊,可以動態(tài)替換函數(shù)。

它的寫法非常簡單:

圖片

我們只需要使用@mock.patch裝飾器,裝飾測試函數(shù)就可以了。這個裝飾器接收兩個參數(shù),第一個參數(shù)是被模擬的函數(shù)的路徑,以點(diǎn)分割;第二個參數(shù)是你想讓它返回的值。

從上圖可以看到,test_runner.py?運(yùn)行以后,原本在read_data_from_redis和read_data_from_mysql中打印的兩段文字都沒有打印,說明這兩個函數(shù)已經(jīng)被動態(tài)替換了,他們內(nèi)部的代碼不會運(yùn)行。只會直接返回我們預(yù)設(shè)的這個返回值。這樣一來就跟數(shù)據(jù)庫解耦了。

注意,在上圖中,由于我們已經(jīng)mock了check_data_dup?,因此read_data_from_redis和read_data_from_mysql?兩個函數(shù)隨便返回什么值都可以。如果你想順帶也測試一下check_data_dup,那么可以不mock它,如下圖所示。

圖片

在check_data_dup?函數(shù)的邏輯中,如果data?參數(shù)含有字符x?,并且user_id?是偶數(shù),就返回True?,否則返回False?。我們通過mock兩個讀數(shù)據(jù)的函數(shù),分別設(shè)置不同的返回值,就能滿足讓check_data_dup返回不同值的條件。

mock.path有一個小坑,一定要注意。我們來看看下面這個文件結(jié)構(gòu):

圖片

read_data_from_redis和read_data_from_mysql?兩個函數(shù)分布在了不同的文件里面。在runner.py?中導(dǎo)入并使用了他們。test_runner.py?中,我們使用@mock.patch對這兩個函數(shù)定義的路徑打補(bǔ)丁進(jìn)行替換。可是替換了以后,運(yùn)行Pytest,會發(fā)現(xiàn)這兩個函數(shù)竟然正常運(yùn)行了。也就是說我們的替換失敗了。

之所以會出現(xiàn)這種情況,是因為我們要打補(bǔ)丁的并不是這兩個函數(shù)定義的地方,而是使用的地方。我們在runner.py中,分別使用如下兩個語句:

from mysql_util.SqlUtil import read_data_from_mysql
from controller.lib.redis.RedisUtil import read_data_from_redis

導(dǎo)入了這兩個函數(shù),我們也是在runner.py?中使用他們的。因此,@mock.patch?的第一個參數(shù),依然應(yīng)該是runner.read_data_from_redis和runner.read_data_from_mysql。

正確的做法如下圖所示:

圖片

mock.patch?還有更多高級用法,例如替換類,替換實例方法等等。可以在unittest.mock中找到他。從Python 3.3開始,官方自帶了unittest.mock?,它跟直接import mock的效果是一樣的。

責(zé)任編輯:武曉燕 來源: 未聞Code
相關(guān)推薦

2024-07-30 08:16:18

Python代碼工具

2024-07-30 08:11:16

2021-04-12 21:19:01

PythonMakefile項目

2021-09-14 21:29:01

項目環(huán)境變量

2021-06-08 21:36:24

PyCharm爬蟲Scrapy

2021-10-15 21:08:31

PandasExcel對象

2025-05-28 03:15:00

Scrapy數(shù)據(jù)sleep

2020-12-04 06:39:25

爬蟲網(wǎng)頁

2023-10-29 09:16:49

代碼安全命令

2022-06-28 09:31:44

LinuxmacOS系統(tǒng)

2023-10-28 12:14:35

爬蟲JavaScriptObject

2022-03-12 20:38:14

網(wǎng)頁Python測試

2024-01-29 00:45:36

跨域后端接口

2024-11-11 00:38:13

Mypy靜態(tài)類型

2021-05-08 19:33:51

移除字符零寬

2021-11-12 05:00:43

裝飾器代碼功能

2021-04-27 22:15:02

Selenium瀏覽器爬蟲

2020-12-11 06:30:00

工具分組DataFrame

2024-05-29 00:00:01

字符串Python縮進(jìn)

2022-03-07 09:14:04

Selenium鼠標(biāo)元素
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 欧洲成人免费视频 | www.av在线 | 亚洲v日韩v综合v精品v | 337p日韩| 日本精品国产 | 精品无码久久久久久久动漫 | 亚洲精品高清视频 | 成人在线影视 | 久久男人 | 亚洲精品9999 | 久久久九九 | 日韩视频中文字幕 | 久久国产成人 | 亚洲一区二区精品视频 | 99reav| 亚洲精品久久国产高清情趣图文 | 大久| 久久青| 在线观看黄免费 | 午夜av成人 | 国产午夜精品一区二区三区嫩草 | 成人福利在线 | 国产精品成人一区二区 | 成人午夜视频在线观看 | 精品99久久| 精品免费国产一区二区三区四区 | 一级特黄色毛片 | 欧美日韩亚洲国产 | 国产精品视频一区二区三区不卡 | 国产免费a视频 | 久久手机在线视频 | 久久久www成人免费无遮挡大片 | av大全在线观看 | 国产精品99久久久久 | 亚洲国产一区视频 | 日韩精品亚洲专区在线观看 | 瑞克和莫蒂第五季在线观看 | 欧美一区二区在线播放 | 久久精品一区二区三区四区 | 欧美在线播放一区 | 日韩av一二三区 |