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

與 Coveralls 的不解之緣

開發 后端
如果是手工統計的,肯定都往高了寫,這樣的數據也就沒有價值,如果是程序自動測試出來的,想著都覺得復雜,是怎么實現的呢?帶著這些疑問,我點擊了那個 coverage 98%,跳轉到了 https://coveralls.io/ 的頁面。

[[403562]]

前兩天在 GitHub 瀏覽 Python 的三方庫時,看到了以下

就像 https 那個綠色鎖的標志一樣,看著很可信,讓人用著放心,很多開源項目都有這些圖標。

看到 coverage 是 98%,我產生了疑問,這是手工統計的,還是程序自動測試出來的呢?

如果是手工統計的,肯定都往高了寫,這樣的數據也就沒有價值,如果是程序自動測試出來的,想著都覺得復雜,是怎么實現的呢?帶著這些疑問,我點擊了那個 coverage 98%,跳轉到了 https://coveralls.io/ 的頁面。

探索了一番,發現原來這是叫 coveralls 的三方庫實現的,用于在線實時顯示單元測試的覆蓋率,測試數據是通過 coverage 來跑出來的。

好奇的我 pip install 安裝了下,拿自己之前的程序,寫了幾個單元測試,用了下這兩條命令:

  1. coverage run --source=dbinterface -m pytest tests/ 
  2. coverage report -m 

發現,這個單元測試的覆蓋率果然是程序自動統計出來的,coverage 真的太牛了,有了這個,寫單元測試就無法偷懶了,代碼質量就有了量化標準。

從上面的圖中可以看到文件的哪些代碼行沒有測試到,然后針對性的編寫單元測試。還可以生成 html 文件進行查詢,更為直觀。

猜測 coverage 應該是記錄了 pytest 調用的代碼行數,然后從全部代碼行記錄中去除已經測試過的行記錄,就是未測試的代碼行,從而統計覆蓋率。

當時,我不由自主發出了‘臥槽牛批’,不過仍然有疑問,程序是怎么檢測哪些代碼行被執行了呢?雖然我知道 debug 時可以看到,但是如何寫程序統計,我還一無所知。

好奇心驅使著我去探索。

首先看下這個 coverage 來自哪里,里面有什么內容:

  1. (py38env) ? dbinterface git:(master) ? which coverage 
  2.  
  3. /Users/aaron/py38env/bin/coverage 

可以看到 coverage 的內容:

  1. (py38env) ➜  dbinterface git:(master) ✗ cat /Users/aaron/py38env/bin/coverage 
  2. #!/Users/aaron/py38env/bin/python3 
  3. # -*- coding: utf-8 -*- 
  4. import re 
  5. import sys 
  6. from coverage.cmdline import main 
  7. if __name__ == '__main__'
  8.     sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$''', sys.argv[0]) 
  9.     sys.exit(main()) 
  10. (py38env) ➜  dbinterface git:(master) ✗ 

其實,在命令行執行 coverage,就相當于執行:

  1. /Users/aaron/py38env/bin/python3 coverage 

將該文件保存到一個目錄中,命名為 main.py,然后使用 PyCharm IDE 開始調試,調試的過程中,發現 coverage run --source=dbinterface -m pytest tests/ 命令會將測試的結果寫入到文件 .coverage 中,再執行 coverage report -m 時會從該文件統計出覆蓋率。

也就是說關鍵是要弄清楚命令 coverage run --source=dbinterface -m pytest tests/ 的執行過程。

繼續 Debug,這里說下,由于我們的命令是在路徑 /Users/aaron/github/somenzz/dbinterface 下執行的,在 Debug 前,先使用 os.chdir 改變程序的工作目錄:

main.py

  1. #!/Users/aaron/py38env/bin/python3 
  2. # -*- coding: utf-8 -*- 
  3. import re 
  4. import sys 
  5. from coverage.cmdline import main 
  6. import os 
  7. if __name__ == '__main__'
  8.     os.chdir('/Users/aaron/github/somenzz/dbinterface'
  9.     sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$''', sys.argv[0]) 
  10.     print(sys.argv[0]) 
  11.     sys.exit(main()) 

然后加入參數,打好斷點,追蹤。

最后追蹤到這里:

這里的 tracer 類就是 CTracer,其源頭可以從 collector.py 文件的這段代碼看出來:

可以看出 tracer 的原型要么是 CTracer, 要么是 PyTracer。

從作者的注釋中可以看到 CTracer 速度非??欤?PyTracer 相對較慢。

想看 CTracer 的源代碼,結果發現了這個文件

.so 文件相當于 windows 的 dll 文件,是動態鏈接庫,需要反編譯成匯編語言,然后再分析執行邏輯,這個對我來說太難了,自己又不熟悉匯編,于是放棄。

那就只剩下 PyTracer 了,原理應該是類似的,PyTracer 的源代碼就是 pytracer.py 文件,可以直接打開查看。

文件開始的地方,導入了以下三個庫:

  1. import atexit 
  2. import dis 
  3. import sys 
  4.  
  5. from coverage import env 

其中前三個都是標準庫,atexit 是退出處理器,可以注冊一個函數,在解釋器終止時執行。dis 是 Python 字節碼反匯編器,這兩個的使用只有一次,沒有派上大用處,可以忽略。

重點就是第三個 sys 模塊,這個模塊和 os 模塊可以說是博大精深,很多程序都會使用到,從包的名稱也可以總結規律,名字越短,就越重要,其使用頻率就越高。

看 PyTracer 源代碼, sys.settrace 是起決定作用的,是 coverage 能夠統計單元測試覆蓋率的關鍵。

下面是對 Python 官方文檔對 sys.settrace 的介紹:

sys.settrace(tracefunc) 用來設置系統的跟蹤函數,使得用戶在 Python 中就可以實現 Python 源代碼調試器。該函數是特定于單個線程的,所以要讓調試器支持多線程,必須為正在調試的每個線程都用 settrace() 注冊一個跟蹤函數,或使用 threading.settrace()。

跟蹤函數應接收三個參數:frame、event 和 arg。frame 是當前的堆棧幀。event 是一個字符串:'call'、'line'、'return'、'exception' 或 'opcode'。arg 取決于事件類型。

官方文檔 bb 這么多,說實話我也沒太懂,到底咋用呢?我網上找了一個例子,比如說文件 trace.py 內容如下:

  1. import sys 
  2.  
  3. def stuff(): 
  4.     print("calling stuff"
  5.  
  6. def printer(frame, event, arg): 
  7.     print(frame, event, arg) 
  8.     return printer # return itself to keep tracing 
  9.  
  10. sys.settrace(printer) 
  11. stuff() 

也就是說執行函數之前,加上 sys.settrace。執行該文件,可以得到以下結果:

  1. (py38env) ➜  tmp python trace.py 
  2. <frame at 0x7fa6bff5a440, file 'trace.py', line 3, code stuff> call None 
  3. <frame at 0x7fa6bff5a440, file 'trace.py', line 4, code stuff> line None 
  4. calling stuff 
  5. <frame at 0x7fa6bff5a440, file 'trace.py', line 4, code stuff> return None 
  6. (py38env) ➜  tmp 

程序執行的行數,執行的操作都完整的顯示了出來,將這些數據保存到文件中,就可以進行單元測試覆蓋率的統計了。

雖然無法方便的查詢 CTracer 源碼,但是從 PyTracer 這里還是學習到了 coverage 統計單元測試覆蓋率的統計方法。

一次偶遇 coveralls 讓我見識了 Python 原來還可以統計代碼的執行情況,真的太秀了。

趁熱打鐵,我用 coveralls 的狀態圖標也發布了一個工具庫:dbinterface,單元測試覆蓋率 89%:

這個一個數據庫操作的通用接口,使用起來是相當的簡單,從此讀寫各種數據庫都不是事:

  1. from dbinterface.database_client import DataBaseClientFactory 
  2.  
  3. client1 = DataBaseClientFactory.create
  4.             dbtype="postgres"
  5.             host="localhost"
  6.             port=5432, 
  7.             user="postgres"
  8.             pwd="121113"
  9.             database="postgres"
  10.         ) 
  11.  
  12. client2 = DataBaseClientFactory.create
  13.             dbtype="mysql"
  14.             host="localhost"
  15.             port=3306, 
  16.             user="aaron"
  17.             pwd="aaron"
  18.             database="information_schema"
  19.         ) 
  20.  
  21. result1 = client1.read("select current_date"
  22. rows_affeted = client1.write( 
  23.     "insert into tmp_test_table values(%s, %s)", ("1""aaron"
  24. rows_export = client.export( 
  25.             "select * from information_schema.TABLES"
  26.             params=(), 
  27.             file_path="/Users/aaron/tmp/mysql_tables.txt"
  28.             delimeter="0x02"
  29.             quote="0x03"
  30.             all_col_as_str=False
  31.         ) 
  32.  
  33. assert rows_export > 0 

項目地址:https://github.com/somenzz/dbinterface

本文轉載自微信公眾號「Python七號」,可以通過以下二維碼關注。轉載本文請聯系Python七號公眾號。

 

責任編輯:武曉燕 來源: Python七號
相關推薦

2010-03-18 19:06:35

Java socket

2010-03-15 18:03:18

Java線程

2023-11-07 12:30:38

數據結構紅黑樹

2016-05-27 11:43:06

2014-10-30 17:43:59

Android 5.0Android Wea

2013-03-26 10:27:32

社交游戲公司云存儲

2009-02-19 09:48:34

XP微軟降級

2021-08-02 10:40:45

機器人人工智能算法

2012-05-24 21:36:44

蘋果

2018-06-19 09:54:22

MySQLHBase存儲

2016-09-30 10:30:12

2018-11-13 14:41:35

溯源區塊鏈商場

2015-07-03 13:38:42

廖廠長

2014-10-30 14:47:37

2017-09-20 14:07:44

2016-12-12 14:05:29

戴爾

2010-03-10 17:43:41

Python編程語言

2016-07-18 10:36:22

華為

2009-11-06 09:39:40

WCF契約

2017-04-11 20:37:25

虛擬化存儲網絡
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品高潮呻吟久久 | 精品在线看 | 欧美日韩一卡二卡 | 欧美国产视频 | 亚洲中午字幕 | 国产视频线观看永久免费 | 毛片免费看 | 日韩超碰 | 久久久91精品国产一区二区三区 | 精品国产免费一区二区三区五区 | 亚洲一区二区三区四区五区中文 | 国产99免费视频 | 黄色片在线观看网址 | 亚洲 精品 综合 精品 自拍 | 国产欧美精品 | 精品亚洲视频在线 | 日韩成人 | 精品国产精品三级精品av网址 | 欧美在线视频免费 | 成人毛片视频在线播放 | 成人免费网站www网站高清 | 久久精品视频99 | 久久久精品网站 | 久久久久久国 | 亚洲3p| 国产精品成人69xxx免费视频 | 亚洲视频在线观看免费 | 黄色视频a级毛片 | 999久久久 | h肉视频 | av香港经典三级级 在线 | 国产精品久久9 | 国产亚洲日本精品 | 一区二区三区在线观看视频 | 999久久久免费精品国产 | 成人精品视频 | 国产黄色大片在线免费观看 | 久久成人国产精品 | 亚洲国产精品久久 | 国产精品高潮呻吟久久av黑人 | 亚洲一区二区三区欧美 |