Python 測試與除錯:打造高品質程式碼 (第 10 章)

站主自己的課程,請大家支持
揭秘站長的架站心法:如何利用 Hugo × AI 打造高質感個人品牌網站? 揭秘站長的架站心法:如何利用 Hugo × AI 打造高質感個人品牌網站?
  • Post by
  • Dec 24, 2023
post-thumb

「寫程式 10% 的時間在寫代碼,90% 的時間在除錯。」 這雖然是句玩笑話,但也反映了軟體開發的真實面貌。

Bug (臭蟲) 是無法避免的。新手與專家的差別,在於專家懂得使用工具來發現 (Detect)診斷 (Diagnose)修復 (Fix) 錯誤,以及如何透過自動化測試來預防未來的 Bug。

1. 告別 Print 大法:使用 logging

新手最愛用的除錯法是 print(variable)。這在小程式還可以,但在大型系統中,滿螢幕的 print 只會讓你崩潰。

Python 的 logging 模組提供了分級的日誌系統:

等級數值用途
DEBUG10詳細資訊,僅在診斷問題時感興趣。
INFO20確認程式按預期運作。
WARNING30表示發生了預期外的事,但程式仍可運行 (如磁碟空間不足)。
ERROR40嚴重問題,程式無法執行某些功能。
CRITICAL50嚴重錯誤,程式可能無法繼續運行。

1.1 實戰範例

import logging

# 設定日誌格式與等級
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

def divide(a, b):
    logging.debug(f"正在執行除法: {a} / {b}")
    if b == 0:
        logging.error("嘗試除以零!")
        return None
    return a / b

divide(10, 2)
divide(5, 0)

這樣我們可以隨時透過調整 level 來決定要不要看到詳細資訊,而不需要一行行刪除 print

2. 專業除錯:使用 pdb

Python 內建了互動式除錯器 pdb (The Python Debugger)。它允許你暫停程式執行 (Breakpoint),一行行檢查變數狀態。

常用指令:

  • n (next): 執行下一行。
  • s (step): 進入函數內部。
  • c (continue): 繼續執行直到下個斷點。
  • p variable: 列印變數值。
  • q (quit): 退出除錯。
import pdb

def complex_calculation(x):
    result = x * 2
    pdb.set_trace()  # 程式執行到這裡會暫停 (Python 3.7+ 可用 breakpoint())
    result += 10
    return result

print(complex_calculation(5))

現代開發:VS Code 或 PyCharm 等 IDE 已經整合了圖形介面的除錯器,原理與 pdb 相同,但操作更直覺。

3. 單元測試 (Unit Testing)

單元測試是指對軟體中的最小可測試單元 (通常是函數或類別) 進行驗證。

3.1 內建框架:unittest

Python 內建的測試框架,模仿 Java 的 JUnit。

import unittest

def add(x, y):
    return x + y

class TestMathOperations(unittest.TestCase):
    
    def test_add(self):
        # 斷言 (Assert):驗證結果是否符合預期
        self.assertEqual(add(1, 2), 3)
        self.assertEqual(add(-1, 1), 0)
        self.assertNotEqual(add(1, 1), 3)

if __name__ == '__main__':
    unittest.main()

3.2 現代主流:pytest

unittest 寫起來比較繁瑣 (Boilerplate code 多)。現在 Python 社群更推崇 pytest,它更簡潔強大。

# test_sample.py
def add(x, y):
    return x + y

def test_add():
    # 直接使用 assert 關鍵字,無需繼承類別
    assert add(1, 2) == 3
    assert add(-1, 1) == 0

只需在終端機輸入 pytest,它就會自動尋找所有 test_ 開頭的檔案並執行。

4. 測試驅動開發 (TDD) 簡介

TDD (Test-Driven Development) 是一種「先寫測試,再寫程式」的開發流程:

  1. Red: 寫一個會失敗的測試 (因為功能還沒寫)。
  2. Green: 寫出剛好能通過測試的程式碼。
  3. Refactor: 優化程式碼,並確保測試仍然通過。

這種方式能確保你的每一行程式碼都有測試覆蓋,且設計時會優先考慮「如何被使用」(Interface Design)。

5. 程式碼品質檢查 (Linting)

除了邏輯錯誤,我們也希望程式碼風格統一且符合 PEP 8 規範。

  • Pylint / Flake8: 檢查語法錯誤與風格問題。
  • Black: 自動格式化程式碼 (直接幫你改好)。
pip install black
black my_script.py  # 一鍵排版,專治排版強迫症

6. 總結

到此為止,我們已經完成了 Python 基礎語法核心觀念 的學習!

Batch 2 (Functions & Modules) 重點回顧:

  • Ch 6: 異常處理讓程式更強健。
  • Ch 7: 善用函式庫與虛擬環境。
  • Ch 8: 掌握檔案 I/O 與現代化 Path 操作。
  • Ch 9: 進入物件導向的世界。
  • Ch 10: 學會測試與除錯,寫出高品質代碼。

在接下來的章節中,我們將進入 資料結構與演算法 的深水區,探討如何處理更複雜的數據!


延伸閱讀

LATEST POST
TAG