Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

除錯、測試與效能

1,120 views

Published on

《Python 3.5 技術手冊》第 12 章投影片

Published in: Software

除錯、測試與效能

  1. 1. 12. 除錯、測試與效能 • 學習目標 – 使用 pdb 模組除錯 – 對程式進行單元測試 – 使用 timeit 評測程式片段 – 使用 cProfile (profile)察看評測數 據
  2. 2. 除錯 • 檢測錯誤的時候,有個順手的工具可以加 速錯誤的檢出,其中 Debugger 是最常使 用也是最基本的工具之一 – 中斷點 – 檢視變數 – 逐步執行
  3. 3. • Step Over 就是執行程式碼的下一步,如 果下步是個函式,會執行完該函式至返回 • 使用 Step Into,若下一步是個函式呼叫, 就會進入函式逐步執行,以便查看函式中 的演算與每一步執行結果 • 如果目前正在某個函式之中,接下來不想 逐步檢視函式中剩餘之程式碼,可以執行 Step Out
  4. 4. 使用 pdb 模組 • 如果手邊正好沒有整合開發環境,只能在 文字模式下執行程式進行除錯,那麼可以 使用 Python 內建的 pdb 模組 • 直接使用 python -m pdb,指定想要除 錯的 .py 檔案
  5. 5. • 如果想要單點針對某個函式進行除錯,可 以使用 pdb.run()函式,通常可以在 REPL 中進行這類動作
  6. 6. • 可以將 pdb.set_trace() 直接撰寫在原 始碼中,當程式執行到 pdb.set_trace() 時,就會進入 (Pdb) 指令提示 • 若程式因為例外而無法繼續下去的話,可 以再使用 pdb.pm() 回到例外發生時的上 一步
  7. 7. 測試 • Python 變數沒有型態,如果有型態上的操 作錯誤,基本上會是在執行時期運行至該 段程式碼時,才會產生錯誤訊息 • 檢查出型態不正確的任務,必須由開發者 來承擔,而減輕這個負擔的最好方式之一, 就是撰寫良好的測試程式
  8. 8. • 撰寫測試的相關工具 – assert – doctest – unittest – 第三方測試工具(像是 nose、pytest 等)
  9. 9. • 要在程式中安插斷言,可以使用 assert • 使用 assert expression 的話,相當於 以下的程式片段: • 如果有兩個 expression,例如 assert expression1, expression2:
  10. 10. • __debug__ 是個內建變數,一般情況下會 是 True • 如果執行時需要最佳化時(在執行時加上- O 引數)則會是 False
  11. 11. • 何時該使用斷言呢? – 前置條件斷言客戶端呼叫函式前,已經準備好 某些條件。 – 後置條件驗證客戶端呼叫函式後,具有函式承 諾之結果。 – 類別不變量(Class invariant)驗證物件某個 時間點下的狀態。 – 內部不變量(Internal invariant)使用斷言取 代註解。 – 流程不變量(Control-flow invariant)斷言程 式流程中絕不會執行到的程式碼部份。
  12. 12. 撰寫 doctest • doctest 模組一方面是測試程式碼,一方 面也用來確認 DocStrings 的內容沒有過期 • 使用互動式的範例來執行驗證,開發者只 要為套件撰寫 REPL 形式的文件就可以
  13. 13. • 獨立地撰寫在另一個文字檔案中
  14. 14. 使用 unittest 單元測試 • unittest 模組有時亦稱為"PyUnit",是 JUnit 的Python 語言實現 • JUnit 是個 Java 實現的單元測試(Unit test)框架 • 單元測試指的是測試一個工作單元(a unit of work)的行為
  15. 15. • 測試一個單元,基本上要與其他的單元獨 立,否則會是在同時測試兩個單元的正確 性,或是兩個單元之間的合作行為 • 就軟體測試而言,單元測試通常指的是測 試某個函式(或方法)
  16. 16. • unittest 模組主要包括四個部份: – 測試案例(Test case) – 測試設備(Test fixture) – 測試套件(Test suite) – 測試執行器(Test runner)
  17. 17. 測試案例
  18. 18. 測試設備 • 如果有定義 setUp() 方法,那麼執行每個 test 開頭的方法前,都會呼叫一次 setUp() • 如果有定義 tearDown()方法,那麼執行 每個 test 開頭的方法後,都會呼叫一次 tearDown() • 可以使用 setUp()、tearDown()來分別 定義每次單元測試前後的資源建立與銷毀
  19. 19. 測試套件 • 想要將不同的測試組合在一起 • 想要自動載入某個 TestCase 子類別中所 有 test_xxx 方法
  20. 20. • 將某個測試套件與某個 TestCase 中的 test_xxx 方法組合為另一個測試套件: • 將許多測試套件再全部組合為另一個測試 套件:
  21. 21. 測試執行器 • 在程式碼中直接使用 TextTestRunner: • 在命令列中使用 unittest 模組來運行模 組、類別或甚至個別的測試方法:
  22. 22. timeit 模組 • 用來量測一個小程式片段的執行時間
  23. 23. • 到底是使用 + 時比較快,還是 join() 比 較快呢?
  24. 24. • 效能是整體程式結合之後的執行考量,並 不是單一元素快慢的問題,也不是憑空猜 測,而是要有實際的評測作為依據 • timeit 預設是執行程式片段 1,000,000 次, 然後取平均時間 • 執行次數可透過 number 參數控制
  25. 25. • 以下是幾個直接透過 API 運行的範例:
  26. 26. 使用 cProfile(profile) • cProfile 用來收集程式執行時的一些時 間數據,提供各種統計數據,對大多數的 使用者來說是不錯的工具 • 這是用 C 撰寫的擴充模組,在評測時有較 低的額外成本,不過並不是所有系統上都 有提供 • profile 介面上仿造了cProfile,是用 純Python 來實現的模組,因此有較高的互 通性
  27. 27. • ncalls:"number of calls"的縮寫,也就是對 特定函式的呼叫次數。 • tottime:"total time"的縮寫,花費在函式上 的執行時間(不包括子函數 • 呼叫的時間)。 • percall:tottime 除以ncalls 的結果。 • cumtime:"cumulative time"的縮寫,花費 在函式與所有子函式的時間 • (從呼叫至離開)。 • percall:cumtime 除以ncalls 的結果。 • filename:lineno(function):提供程式碼執行 時的位置資訊。
  28. 28. • 可以使用 pstats 對 cProfile 的結果, 進行各種運算與排序

×