通過官方網(wǎng)站介紹我們可以了解到,pytest是一個非常成熟的全功能的python測試框架,主要有
創(chuàng)新互聯(lián)公司主要從事成都網(wǎng)站設計、成都做網(wǎng)站、網(wǎng)頁設計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務。立足成都服務婁底,十余年網(wǎng)站建設經(jīng)驗,價格優(yōu)惠、服務專業(yè),歡迎來電咨詢建站服務:13518219792
以下幾個特點:
1.直接使用pip命令安裝
2.驗證安裝結果
3.在pytest測試框架中,要遵循以下約束:
pytest進行測試比較簡單,我們來看一個實例:
這里我們定義了了兩個測試函數(shù),直接打印出結果,下面執(zhí)行測試:
輸出結果中顯示執(zhí)行了多少條案例、對應的測試模塊、通過條數(shù)以及執(zhí)行耗時。
pytest斷言主要使用Python原生斷言方法,主要有以下幾種:
可以看到運行結果中明確指出了錯誤原因是"AssertionError",因為PHP不在str1中。
1.運行指定案例
2.運行當前文件夾包括子文件夾所有用例
3.運行指定文件夾(code目錄下所有用例)
4.運行模塊中指定用例(運行模塊中test_add用例)
5.執(zhí)行失敗的最大次數(shù)
使用表達式"--maxfail=num"來實現(xiàn)( 注意:表達式中間不能存在空格 ),表示用例失敗總數(shù)等于num 時停止運行。
6.錯誤信息在一行展示
在實際項目中如果有很多用例執(zhí)行失敗,查看報錯信息將會很麻煩。使用"--tb=line"命令,可以很好解決這個問題。
本地寫一個查詢用戶信息的接口,通過pytest來調用,并進行接口斷言。
目錄
pytest是Python的單元測試框架,同自帶的unittest框架類似,但pytest框架使用起來更簡潔,效率更高。
pytest特點
安裝
測試
在測試之前要做的準備
我的演示腳本處于這樣一個的目錄中:
踩坑:你創(chuàng)建的pytest腳本名稱中不允許含有 . ,比如 1.簡單上手.py ,這樣會報錯。當然,可以這么寫 1-簡單上手.py
demo1.py :
上例中,當我們在執(zhí)行(就像Python解釋器執(zhí)行普通的Python腳本一樣)測試用例的時候, pytest.main(["-s", "demo1.py"]) 中的傳參需要是一個元組或者列表(我的pytest是5.2.2版本),之前的版本可能需要這么調用 pytest.main("-s demo1.py") ,傳的參數(shù)是str的形式,至于你使用哪種,取決于報不報錯:
遇到上述報錯,就是參數(shù)需要一個列表或者元組的形式,而我們使用的是str形式。
上述代碼正確的執(zhí)行結果是這樣的:
大致的信息就是告訴我們:
pytest.main(["-s", "demo1.py"])參數(shù)說明
除了上述的函數(shù)這種寫法,也可以有用例類的寫法:
用法跟unittest差不多,類名要以 Test 開頭,并且其中的用例方法也要以 test 開頭,然后執(zhí)行也一樣。
執(zhí)行結果:
那么,你這個時候可能會問,我記得unittest中有setup和teardown的方法,難道pytest中沒有嘛?你怎么提都不提?穩(wěn)住,答案是有的。
接下來,我們來研究一下pytest中的setup和teardown的用法。
我們知道,在unittest中,setup和teardown可以在每個用例前后執(zhí)行,也可以在所有的用例集執(zhí)行前后執(zhí)行。那么在pytest中,有以下幾種情況:
來一一看看各自的用法。
模塊級別setup_module/teardown_module
執(zhí)行結果:
類級別的setup_class/teardown_class
執(zhí)行結果:
類中方法級別的setup_method/teardown_method
執(zhí)行結果:
函數(shù)級別的setup_function/teardown_function
執(zhí)行結果:
小結
該腳本有多種運行方式,如果處于PyCharm環(huán)境,可以使用右鍵或者點擊運行按鈕運行,也就是在pytest中的主函數(shù)中運行:
也可以在命令行中運行:
這種方式,跟使用Python解釋器執(zhí)行Python腳本沒有什么兩樣。也可以如下面這么執(zhí)行:
當然,還有一種是使用配置文件運行,來看看怎么用。
在項目的根目錄下,我們可以建立一個 pytest.ini 文件,在這個文件中,我們可以實現(xiàn)相關的配置:
那這個配置文件中的各項都是什么意思呢?
首先, pytest.ini 文件必須位于項目的根目錄,而且也必須叫做 pytest.ini 。
其他的參數(shù):
OK,來個示例。
首先,(詳細目錄參考開頭的目錄結構)在 scripts/test_case_01.py 中:
在 scripts/test_case_dir1/test_case02.py 中:
那么,在不同的目錄或者文件中,共有5個用例將被執(zhí)行,而結果則是兩個失敗三個成功。來執(zhí)行驗證一下,因為有了配置文件,我們在終端中(前提是在項目的根目錄),直接輸入 pytest 即可。
由執(zhí)行結果可以發(fā)現(xiàn), 2 failed, 3 passed ,跟我們的預期一致。
后續(xù)執(zhí)行相關配置都來自配置文件,如果更改,會有相應說明,終端都是直接使用 pytest 執(zhí)行。
我們知道在unittest中,跳過用例可以用 skip ,那么這同樣是適用于pytest。
來看怎么使用:
跳過用例,我們使用 @pytest.mark.skipif(condition, reason) :
然后將它裝飾在需要被跳過用例的的函數(shù)上面。
效果如下:
上例執(zhí)行結果相對詳細,因為我們在配置文件中為 addopts 增加了 -v ,之前的示例結果中,沒有加!
另外,此時,在輸出的控制臺中, 還無法打印出 reason 信息,如果需要打印,則可以在配置文件中的 addopts 參數(shù)的 -s 變?yōu)?-rs :
如果我們事先知道測試函數(shù)會執(zhí)行失敗,但又不想直接跳過,而是希望顯示的提示。
Pytest 使用 pytest.mark.xfail 實現(xiàn)預見錯誤功能::
需要掌握的必傳參數(shù)的是:
那么關于預期失敗的幾種情況需要了解一下:
結果如下:
pytest 使用 x 表示預見的失?。╔FAIL)。
如果預見的是失敗,但實際運行測試卻成功通過,pytest 使用 X 進行標記(XPASS)。
而在預期失敗的兩種情況中,我們不希望出現(xiàn)預期失敗,結果卻執(zhí)行成功了的情況出現(xiàn),因為跟我們想的不一樣嘛,我預期這條用例失敗,那這條用例就應該執(zhí)行失敗才對,你雖然執(zhí)行成功了,但跟我想的不一樣,你照樣是失敗的!
所以,我們需要將預期失敗,結果卻執(zhí)行成功了的用例標記為執(zhí)行失敗,可以在 pytest.ini 文件中,加入:
這樣就就把上述的情況標記為執(zhí)行失敗了。
pytest身為強大的單元測試框架,那么同樣支持DDT數(shù)據(jù)驅動測試的概念。也就是當對一個測試函數(shù)進行測試時,通常會給函數(shù)傳遞多組參數(shù)。比如測試賬號登陸,我們需要模擬各種千奇百怪的賬號密碼。
當然,我們可以把這些參數(shù)寫在測試函數(shù)內部進行遍歷。不過雖然參數(shù)眾多,但仍然是一個測試,當某組參數(shù)導致斷言失敗,測試也就終止了。
通過異常捕獲,我們可以保證程所有參數(shù)完整執(zhí)行,但要分析測試結果就需要做不少額外的工作。
在 pytest 中,我們有更好的解決方法,就是參數(shù)化測試,即每組參數(shù)都獨立執(zhí)行一次測試。使用的工具就是 pytest.mark.parametrize(argnames, argvalues) 。
使用就是以裝飾器的形式使用。
只有一個參數(shù)的測試用例
來看(重要部分)結果::
可以看到,列表內的每個手機號,都是一條測試用例。
多個參數(shù)的測試用例
(重要部分)結果:
可以看到,每一個手機號與每一個驗證碼都組合一起執(zhí)行了,這樣就執(zhí)行了4次。那么如果有很多個組合的話,用例數(shù)將會更多。我們希望手機號與驗證碼一一對應組合,也就是只執(zhí)行兩次,怎么搞呢?
在多參數(shù)情況下,多個參數(shù)名是以 , 分割的字符串。參數(shù)值是列表嵌套的形式組成的。
固件(Fixture)是一些函數(shù),pytest 會在執(zhí)行測試函數(shù)之前(或之后)加載運行它們,也稱測試夾具。
我們可以利用固件做任何事情,其中最常見的可能就是數(shù)據(jù)庫的初始連接和最后關閉操作。
Pytest 使用 pytest.fixture() 定義固件,下面是最簡單的固件,訪問主頁前必須先登錄:
結果:
在之前的示例中,你可能會覺得,這跟之前的setup和teardown的功能也類似呀,但是,fixture相對于setup和teardown來說更靈活。pytest通過 scope 參數(shù)來控制固件的使用范圍,也就是作用域。
比如之前的login固件,可以指定它的作用域:
很多時候需要在測試前進行預處理(如新建數(shù)據(jù)庫連接),并在測試完成進行清理(關閉數(shù)據(jù)庫連接)。
當有大量重復的這類操作,最佳實踐是使用固件來自動化所有預處理和后處理。
Pytest 使用 yield 關鍵詞將固件分為兩部分, yield 之前的代碼屬于預處理,會在測試前執(zhí)行; yield 之后的代碼屬于后處理,將在測試完成后執(zhí)行。
以下測試模擬數(shù)據(jù)庫查詢,使用固件來模擬數(shù)據(jù)庫的連接關閉:
結果:
可以看到在兩個測試用例執(zhí)行前后都有預處理和后處理。
pytest中還有非常多的插件供我們使用,我們來介紹幾個常用的。
先來看一個重要的,那就是生成測試用例報告。
想要生成測試報告,首先要有下載,才能使用。
下載
如果下載失敗,可以使用PyCharm下載,怎么用PyCharm下載這里無需多言了吧。
使用
在配置文件中,添加參數(shù):
效果很不錯吧!
沒完,看我大招
Allure框架是一個靈活的輕量級多語言測試報告工具,它不僅以web的方式展示了簡潔的測試結果,而且允許參與開發(fā)過程的每個人從日常執(zhí)行的測試中最大限度的提取有用信息。
從開發(fā)人員(dev,developer)和質量保證人員(QA,Quality Assurance)的角度來看,Allure報告簡化了常見缺陷的統(tǒng)計:失敗的測試可以分為bug和被中斷的測試,還可以配置日志、步驟、fixture、附件、計時、執(zhí)行 歷史 以及與TMS和BUG管理系統(tǒng)集成,所以,通過以上配置,所有負責的開發(fā)人員和測試人員可以盡可能的掌握測試信息。
從管理者的角度來看,Allure提供了一個清晰的“大圖”,其中包括已覆蓋的特性、缺陷聚集的位置、執(zhí)行時間軸的外觀以及許多其他方便的事情。allure的模塊化和可擴展性保證了我們總是能夠對某些東西進行微調。
少扯點,來看看怎么使用。
Python的pytest中allure下載
但由于這個 allure-pytest 插件生成的測試報告不是 html 類型的,我們還需要使用allure工具再“加工”一下。所以說,我們還需要下載這個allure工具。
allure工具下載
在現(xiàn)在allure工具之前,它依賴Java環(huán)境,我們還需要先配置Java環(huán)境。
注意,如果你的電腦已經(jīng)有了Java環(huán)境,就無需重新配置了。
配置完了Java環(huán)境,我們再來下載allure工具,我這里直接給出了百度云盤鏈接,你也可以去其他鏈接中自行下載:
下載并解壓好了allure工具包之后,還需要將allure包內的 bin 目錄添加到系統(tǒng)的環(huán)境變量中。
完事后打開你的終端測試:
返回了版本號說明安裝成功。
使用
一般使用allure要經(jīng)歷幾個步驟:
來看配置 pytest.ini :
就是 --alluredir ./report/result 參數(shù)。
在終端中輸入 pytest 正常執(zhí)行測試用例即可:
執(zhí)行完畢后,在項目的根目下,會自動生成一個 report 目錄,這個目錄下有:
接下來需要使用allure工具來生成HTML報告。
此時我們在終端(如果是windows平臺,就是cmd),路徑是項目的根目錄,執(zhí)行下面的命令。
PS:我在pycharm中的terminal輸入allure提示'allure' 不是內部或外部命令,也不是可運行的程序或批處理文件。但windows的終端沒有問題。
命令的意思是,根據(jù) reportresult 目錄中的數(shù)據(jù)(這些數(shù)據(jù)是運行pytest后產(chǎn)生的)。在 report 目錄下新建一個 allure_html 目錄,而這個目錄內有 index.html 才是最終的allure版本的HTML報告;如果你是重復執(zhí)行的話,使用 --clean 清除之前的報告。
結果很漂亮:
allure open
默認的,allure報告需要HTTP服務器來打開,一般我們可以通過pycharm來完成,另外一種情況就是通過allure自帶的open命令來完成。
allure的其他用法
當然,故事還是沒有完!在使用allure生成報告的時候,在編寫用例階段,還可以有一些參數(shù)可以使用:
allure.title與allure.description
feature和story
由上圖可以看到,不同的用例被分為不同的功能中。
allure.severity
allure.severity 用來標識測試用例或者測試類的級別,分為blocker,critical,normal,minor,trivial5個級別。
severity的默認級別是normal,所以上面的用例5可以不添加裝飾器了。
allure.dynamic
在之前,用例的執(zhí)行順序是從上到下依次執(zhí)行:
正如上例的執(zhí)行順序是 3 1 2 。
現(xiàn)在,來看看我們如何手動控制多個用例的執(zhí)行順序,這里也依賴一個插件。
下載
使用
手動控制用例執(zhí)行順序的方法是在給各用例添加一個裝飾器:
那么, 現(xiàn)在的執(zhí)行順序是 2 1 3 ,按照order指定的排序執(zhí)行的。
如果有人較勁傳個0或者負數(shù)啥的,那么它們的排序關系應該是這樣的:
失敗重試意思是指定某個用例執(zhí)行失敗可以重新運行。
下載
使用
需要在 pytest.ini 文件中, 配置:
給 addopts 字段新增(其他原有保持不變) --reruns=3 字段,這樣如果有用例執(zhí)行失敗,則再次執(zhí)行,嘗試3次。
來看示例:
結果:
我們也可以從用例報告中看出重試的結果:
上面演示了用例失敗了,然后重新執(zhí)行多少次都沒有成功,這是一種情況。
接下來,來看另一種情況,那就是用例執(zhí)行失敗,重新執(zhí)行次數(shù)內通過了,那么剩余的重新執(zhí)行的次數(shù)將不再執(zhí)行。
通過 random 模塊幫助我們演示出在某次執(zhí)行中出現(xiàn)失敗的情況,而在重新執(zhí)行的時候,會出現(xiàn)成功的情況,看結果:
可以看到,用例 02 重新執(zhí)行了一次就成功了,剩余的兩次執(zhí)行就終止了。
一條一條用例的執(zhí)行,肯定會很慢,來看如何并發(fā)的執(zhí)行測試用例,當然這需要相應的插件。
下載
使用
在配置文件中添加:
就是這個 -n=auto :
并發(fā)的配置可以寫在配置文件中,然后其他正常的執(zhí)行用例腳本即可。另外一種就是在終端中指定,先來看示例:
結果:
pytest-sugar 改變了 pytest 的默認外觀,添加了一個進度條,并立即顯示失敗的測試。它不需要配置,只需 下載插件即可,用 pytest 運行測試,來享受更漂亮、更有用的輸出。
下載
其他照舊執(zhí)行用例即可。
pytest-cov 在 pytest 中增加了覆蓋率支持,來顯示哪些代碼行已經(jīng)測試過,哪些還沒有。它還將包括項目的測試覆蓋率。
下載
使用
在配置文件中:
也就是配置 --cov=./scripts ,這樣,它就會統(tǒng)計所有 scripts 目錄下所有符合規(guī)則的腳本的測試覆蓋率。
執(zhí)行的話,就照常執(zhí)行就行。
結果:
更多插件參考:
有的時候,在 pytest.ini 中配置了 pytest-html 和 allure 插件之后,執(zhí)行后報錯:
出現(xiàn)了這個報錯,檢查你配置的解釋器中是否存在 pytest-html 和 allure-pytest 這兩個模塊。如果是使用的pycharm ide,那么你除了檢查settings中的解釋器配置之外,還需要保證運行腳本的編輯器配置是否跟settings中配置一致。
第一段:
if(pos in fre_dist.keys()):
newvalue= fre_dist[pos]
第二段:
if(pos in fre_dist):
newValue=fre_dist[pos]
在處理3萬條數(shù)據(jù)時,第二段代碼的速度是第一段代碼速度的上千倍。
原因是:第一段代碼 fre_dist.keys()變成了list,python在檢索list的時候是比較慢的,第二段代碼 fre_dist是字典,python在檢索字典的時候速度是比較快的。
測試函數(shù)是用于自動化測試,使用python模塊中的unittest中的工具來測試
附上書中摘抄來的代碼:
#coding=utf-8import unittestfrom name_function import get_formatted_nameclass NamesTestCase(unittest.TestCase): def test_first_last_name(self): formatted_name=get_formatted_name('janis','joplin') self.assertEqual(formatted_name,'Janis Joplin') def test_first_last_middle_name(self): formatted_name=get_formatted_name('wolfgang','mozart','amadeus') self.assertEqual(formatted_name,'Wolfgang Amadeus Mozart')#注意下面這行代碼,不寫會報錯哦~~~書中沒有這行if __name__=="__main__": unittest.main()
Python中有許多內置函數(shù),不像print、len那么廣為人知,但它們的功能卻異常強大,用好了可以大大提高代碼效率,同時提升代碼的簡潔度,增強可閱讀性
Counter
collections在python官方文檔中的解釋是High-performance container datatypes,直接的中文翻譯解釋高性能容量數(shù)據(jù)類型。這個模塊實現(xiàn)了特定目標的容器,以提供Python標準內建容器 dict , list , set , 和 tuple 的替代選擇。在python3.10.1中它總共包含以下幾種數(shù)據(jù)類型:
容器名簡介
namedtuple() 創(chuàng)建命名元組子類的工廠函數(shù)
deque 類似列表(list)的容器,實現(xiàn)了在兩端快速添加(append)和彈出(pop)
ChainMap 類似字典(dict)的容器類,將多個映射集合到一個視圖里面
Counter 字典的子類,提供了可哈希對象的計數(shù)功能
OrderedDict 字典的子類,保存了他們被添加的順序
defaultdict 字典的子類,提供了一個工廠函數(shù),為字典查詢提供一個默認值
UserDict 封裝了字典對象,簡化了字典子類化
UserList 封裝了列表對象,簡化了列表子類化
UserString 封裝了字符串對象,簡化了字符串子類化
其中Counter中文意思是計數(shù)器,也就是我們常用于統(tǒng)計的一種數(shù)據(jù)類型,在使用Counter之后可以讓我們的代碼更加簡單易讀。Counter類繼承dict類,所以它能使用dict類里面的方法
舉例
#統(tǒng)計詞頻
fruits = ['apple', 'peach', 'apple', 'lemon', 'peach', 'peach']
result = {}
for fruit in fruits:
if not result.get(fruit):
result[fruit] = 1
else:
result[fruit] += 1
print(result)
#{'apple': 2, 'peach': 3, 'lemon': 1}下面我們看用Counter怎么實現(xiàn):
from collections import Counter
fruits = ['apple', 'peach', 'apple', 'lemon', 'peach', 'peach']
c = Counter(fruits)
print(dict(c))
#{'apple': 2, 'peach': 3, 'lemon': 1}顯然代碼更加簡單了,也更容易閱讀和維護了。
elements()
返回一個迭代器,其中每個元素將重復出現(xiàn)計數(shù)值所指定次。元素會按首次出現(xiàn)的順序返回。如果一個元素的計數(shù)值小于1,elements()將會忽略它。
c = Counter(a=4, b=2, c=0, d=-2)
sorted(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']most_common([n])
返回一個列表,其中包含n個最常見的元素及出現(xiàn)次數(shù),按常見程度由高到低排序。如果n被省略或為None,most_common()將返回計數(shù)器中的所有元素。計數(shù)值相等的元素按首次出現(xiàn)的順序排序:
Counter('abracadabra').most_common(3)
[('a', 5), ('b', 2), ('r', 2)]這兩個方法是Counter中最常用的方法,其他方法可以參考 python3.10.1官方文檔
實戰(zhàn)
Leetcode 1002.查找共用字符
給你一個字符串數(shù)組words,請你找出所有在words的每個字符串中都出現(xiàn)的共用字符(包括重復字符),并以數(shù)組形式返回。你可以按任意順序返回答案。
輸入:words = ["bella", "label", "roller"]
輸出:["e", "l", "l"]
輸入:words = ["cool", "lock", "cook"]
輸出:["c", "o"]看到統(tǒng)計字符,典型的可以用Counter完美解決。這道題是找出字符串列表里面每個元素都包含的字符,首先可以用Counter計算出每個元素每個字符出現(xiàn)的次數(shù),依次取交集最后得出所有元素共同存在的字符,然后利用elements輸出共用字符出現(xiàn)的次數(shù)
class Solution:
def commonChars(self, words: List[str]) - List[str]:
from collections import Counter
ans = Counter(words[0])
for i in words[1:]:
ans = Counter(i)
return list(ans.elements())提交一下,發(fā)現(xiàn)83個測試用例耗時48ms,速度還是不錯的
sorted
在處理數(shù)據(jù)過程中,我們經(jīng)常會用到排序操作,比如將列表、字典、元組里面的元素正/倒排序。這時候就需要用到sorted(),它可以對任何可迭代對象進行排序,并返回列表
對列表升序操作:
a = sorted([2, 4, 3, 7, 1, 9])
print(a)
# 輸出:[1, 2, 3, 4, 7, 9]對元組倒序操作:
sorted((4,1,9,6),reverse=True)
print(a)
# 輸出:[9, 6, 4, 1]使用參數(shù):key,根據(jù)自定義規(guī)則,按字符串長度來排序:
fruits = ['apple', 'watermelon', 'pear', 'banana']
a = sorted(fruits, key = lambda x : len(x))
print(a)
# 輸出:['pear', 'apple', 'banana', 'watermelon']all
all() 函數(shù)用于判斷給定的可迭代參數(shù)iterable中的所有元素是否都為 TRUE,如果是返回 True,否則返回 False。元素除了是 0、空、None、False外都算True。注意:空元組、空列表返回值為True。
all(['a', 'b', 'c', 'd']) # 列表list,元素都不為空或0
True
all(['a', 'b', '', 'd']) # 列表list,存在一個為空的元素
False
all([0, 1,2, 3]) # 列表list,存在一個為0的元素
False
all(('a', 'b', 'c', 'd')) # 元組tuple,元素都不為空或0
True
all(('a', 'b', '', 'd')) # 元組tuple,存在一個為空的元素
False
all((0, 1, 2, 3)) # 元組tuple,存在一個為0的元素
False
all([]) # 空列表
True
all(()) # 空元組
Trueany函數(shù)正好和all函數(shù)相反:判斷一個tuple或者list是否全為空,0,F(xiàn)alse。如果全為空,0,F(xiàn)alse,則返回False;如果不全為空,則返回True。
F-strings
在python3.6.2版本中,PEP 498提出一種新型字符串格式化機制,被稱為 “字符串插值” 或者更常見的一種稱呼是F-strings,F(xiàn)-strings提供了一種明確且方便的方式將python表達式嵌入到字符串中來進行格式化:
s1='Hello'
s2='World'
print(f'{s1} {s2}!')
# Hello World!在F-strings中我們也可以執(zhí)行函數(shù):
def power(x):
return x*x
x=4
print(f'{x} * {x} = {power(x)}')
# 4 * 4 = 16而且F-strings的運行速度很快,比傳統(tǒng)的%-string和str.format()這兩種格式化方法都快得多,書寫起來也更加簡單。
本文主要講解了python幾種冷門但好用的函數(shù),更多內容以后會陸陸續(xù)續(xù)更新~
1. 使用裝飾器來衡量函數(shù)執(zhí)行時間
有一個簡單方法,那就是定義一個裝飾器來測量函數(shù)的執(zhí)行時間,并輸出結果:
import time
from functoolsimport wraps
import random
def fn_timer(function):
@wraps(function)
def function_timer(*args, **kwargs):
? t0= time.time()
? result= function(*args, **kwargs)
? t1= time.time()
? print("Total time running %s: %s seconds" %
? ? ? (function.__name__, str(t1- t0))
)
? return result
return function_timer
@fn_timer
def random_sort(n):
return sorted([random.random() for i in range(n)])
if __name__== "__main__":
random_sort(2000000)
輸出:Total time running random_sort: 0.6598007678985596 seconds
使用方式的話,就是在要監(jiān)控的函數(shù)定義上面加上 @fn_timer 就行了
或者
# 可監(jiān)控程序運行時間
import time
import random
def clock(func):
def wrapper(*args, **kwargs):
? ? start_time= time.time()
? ? result= func(*args, **kwargs)
? ? end_time= time.time()
? ? print("共耗時: %s秒" % round(end_time- start_time, 5))
? ? return result
return wrapper
@clock
def random_sort(n):
return sorted([random.random() for i in range(n)])
if __name__== "__main__":
random_sort(2000000)
輸出結果:共耗時: 0.65634秒
2. 使用timeit模塊
另一種方法是使用timeit模塊,用來計算平均時間消耗。
執(zhí)行下面的腳本可以運行該模塊。
這里的timing_functions是Python腳本文件名稱。
在輸出的末尾,可以看到以下結果:4?loops, best of?5:?2.08?sec per loop
這表示測試了4次,平均每次測試重復5次,最好的測試結果是2.08秒。
如果不指定測試或重復次數(shù),默認值為10次測試,每次重復5次。
3. 使用Unix系統(tǒng)中的time命令
然而,裝飾器和timeit都是基于Python的。在外部環(huán)境測試Python時,unix time實用工具就非常有用。
運行time實用工具:
輸出結果為:
Total?time running random_sort:?1.3931210041?seconds
real?1.49
user?1.40
sys?0.08
第一行來自預定義的裝飾器,其他三行為:
real表示的是執(zhí)行腳本的總時間
user表示的是執(zhí)行腳本消耗的CPU時間。
sys表示的是執(zhí)行內核函數(shù)消耗的時間。
注意:根據(jù)維基百科的定義,內核是一個計算機程序,用來管理軟件的輸入輸出,并將其翻譯成CPU和其他計算機中的電子設備能夠執(zhí)行的數(shù)據(jù)處理指令。
因此,Real執(zhí)行時間和User+Sys執(zhí)行時間的差就是消耗在輸入/輸出和系統(tǒng)執(zhí)行其他任務時消耗的時間。
4. 使用cProfile模塊
5. 使用line_profiler模塊
6. 使用memory_profiler模塊
7. 使用guppy包
當前名稱:包含python測試函數(shù)耗時的詞條
當前鏈接:http://www.rwnh.cn/article16/higodg.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營銷、做網(wǎng)站、用戶體驗、定制網(wǎng)站、手機網(wǎng)站建設、服務器托管
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)