更新於 2024/11/14閱讀時間約 9 分鐘

[Python教學] 中級:檢測與除錯

在這篇文章中,我們將介紹如何在 Python 中進行除錯與測試。初學者可以利用 print() 進行簡單除錯,進階則可以學習 logging 模組進行更詳細的記錄,並利用 unittestpytest 等單元測試工具進行自動化測試,以確保程式的穩定性。


1 使用 print() 進行簡單除錯

print() 是初學者最常使用的除錯工具。在程式碼執行過程中,可以用 print() 將變數值、運行步驟、函式回傳值等輸出,以便追蹤程式的執行狀況。

範例

def divide(a, b):
print("a:", a) # 印出變數 a 的值
print("b:", b) # 印出變數 b 的值
result = a / b
print("result:", result) # 印出結果
return result

divide(10, 2)

執行上述程式時,可以看到每一步驟的計算值。這樣的方式適合快速了解程式的執行情況,尤其在問題發生的地方插入 print() 即可檢查變數。

需要注意的是,使用 print() 有局限性,尤其在大規模程式中,太多的 print() 會造成混亂。此外,print() 無法記錄到文件中,無法長期保存記錄。


2 使用 logging 模組進行進階除錯

logging 是 Python 內建的記錄工具,提供比 print() 更高級的功能,適合於需要長期保存記錄的場景。透過 logging,可以將錯誤、重要信息寫入文件,便於後續分析。

2.1 基本使用

import logging

logging.basicConfig(level=logging.DEBUG) # 設定日誌等級為 DEBUG

def divide(a, b):
logging.debug(f"a: {a}, b: {b}")
try:
result = a / b
logging.info(f"Result: {result}")
except ZeroDivisionError:
logging.error("Division by zero!")
result = None
return result

divide(10, 2)
divide(10, 0)
  • logging.debug():記錄詳細資訊,常用於除錯。
  • logging.info():記錄一般資訊,常用於程式正常運行時的信息。
  • logging.warning():警告信息,用於非致命性錯誤或重要事件。
  • logging.error():錯誤信息,用於程序中出現的錯誤。
  • logging.critical():致命性錯誤,用於無法運行的狀況。

2.2 將記錄寫入文件

可以將日誌記錄到文件中,方便日後查看。

logging.basicConfig(filename='app.log', level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s')

def divide(a, b):
logging.debug(f"a: {a}, b: {b}")
try:
result = a / b
logging.info(f"Result: {result}")
except ZeroDivisionError:
logging.error("Division by zero!")
result = None
return result

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

此時,所有日誌會被寫入 app.log 文件中。format 參數可以控制日誌的格式,例如加上日期、時間、日誌等級等。


3 使用 unittest 模組進行單元測試

單元測試是測試程序中的最小單位,例如函式或方法。unittest 是 Python 內建的單元測試框架,可以快速檢測函式是否如預期運作。

3.1 基本使用

import unittest

def add(a, b):
return a + b

class TestAddFunction(unittest.TestCase):
def test_add_positive(self):
self.assertEqual(add(1, 2), 3) # 測試正整數相加
def test_add_negative(self):
self.assertEqual(add(-1, -1), -2) # 測試負整數相加
def test_add_zero(self):
self.assertEqual(add(0, 5), 5) # 測試包含零的相加

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

每個測試方法以 test_ 開頭。assertEqual() 用於檢查實際結果是否與預期結果相符。

3.2 常用的 unittest 斷言方法

  • assertEqual(a, b):檢查 a == b
  • assertNotEqual(a, b):檢查 a != b
  • assertTrue(x):檢查 x is True
  • assertFalse(x):檢查 x is False
  • assertRaises(exception, func, *args, **kwds):檢查執行 func 是否拋出指定異常

4 使用 pytest 進行單元測試

pytest 是一個強大且靈活的 Python 測試框架,提供簡潔的測試語法,並且支持多種測試需求。

4.1 安裝 pytest

pip install pytest

4.2 使用 pytest 進行測試

unittest 相比,pytest 不需要將測試函式寫在類別內,直接定義測試函式即可。

def add(a, b):
return a + b

def test_add_positive():
assert add(1, 2) == 3 # 測試正整數相加

def test_add_negative():
assert add(-1, -1) == -2 # 測試負整數相加

def test_add_zero():
assert add(0, 5) == 5 # 測試包含零的相加

執行 pytest

pytest

pytest 會自動執行所有以 test_ 開頭的函式,並報告測試結果。

4.3 pytest 的進階功能

pytest 提供更多進階功能,例如參數化測試和自定義測試配置:

參數化測試:可以測試同一個函式的多組參數。

import pytest

@pytest.mark.parametrize("a, b, expected",
[
(1, 2, 3),
(-1, -1, -2),
(0, 5, 5),
])

def test_add(a, b, expected):
assert add(a, b) == expected

使用 @pytest.mark.parametrize 可以指定多組測試數據,並自動測試每一組數據的結果。


總結

這篇文章詳細介紹了 Python 中的除錯和測試方法。初學者可以使用 print() 進行基本除錯,而 logging 則適合用於記錄並長期保存運行信息。當進入專案開發階段時,建議使用 unittestpytest 進行單元測試,以確保程式的穩定性和可靠性。透過這些方法,可以在開發過程中更快、更有效地發現並解決問題,提升程式碼的品質。


分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.