Python 速查手冊

12.10 發展工具 2to3 pydoc unittest

本書已有新版,請參考 Python 簡易手冊 - 目錄

2to3 是命令列工具,用來檢測 Python 2 的程式檔案並提供轉換到 Python 3 語法的建議, pydoc 同樣是命令列工具,可在命令列直接查詢 Python 文件,或是啟動文件伺服器,可以用瀏覽器查詢文件,至於 unittest 是進行單元測試的模組 (module) 。

使用 2to3 很簡單,例如有以下的 Python 2 檔案

#!/usr/bin/python
# -*- coding: utf-8 -*-

print "Hello Python!"

#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:py2demo.py
# 功能:示範 2to3 工具
# 作者:張凱慶

於命令列用 2to3 ,如下

$ python3 2to3 py2demo.py
RefactoringTool: Skipping optional fixer: buffer
RefactoringTool: Skipping optional fixer: idioms
RefactoringTool: Skipping optional fixer: set_literal
RefactoringTool: Skipping optional fixer: ws_comma
RefactoringTool: Refactored py2demo.py
--- py2demo.py (original)
+++ py2demo.py (refactored)
@@ -1,7 +1,7 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-print "Hello Python!"
+print("Hello Python!")
#《程式語言教學誌》的範例程式
# http://kaiching.org/
RefactoringTool: Files that need to be modified:
RefactoringTool: py2demo.py
$

- 號表示原始的程式碼, + 號則表示應該修改成的程式碼

-print "Hello Python!"
+print("Hello Python!")

使用 pydoc (或 pydoc3)可在後面接想查詢的模組,例如

$ pydoc3 sys

這樣就可以在命令列叫出 sys 模組的文件。

如果要啟動文件伺服器 (server) 需要加上參數 -b ,例如

$ pydoc3 -b
Server ready at http://localhost:51899/
Server commands: [b]rowser, [q]uit
server>

如果是 Python 3 ,基本上會自動用預設瀏覽器跳出文件網站,如下

如果要結束文件伺服器,請回到終端機按下 qEnter

unittest 是進行單元測試 (unit testing) 的模組,單元測試是對整個程式拆開成個別獨立的單元進行測試,這些獨立單元如函數 (function) 、方法 (method) 等等,雖然開發的時候通常寫好一段程式碼就會測試是否正確無誤,然而組織在一起,例如原本寫的是函數變成類別 (class) 中的方法,有些地方就得做適當的改寫,為了確保語義是正確的,也就是重新組織或是後續修改都可能犯下語義錯誤,這時候對整個拆開成個別的獨立單元測試就比較容易找出錯誤。

換句話說,單元測試是針對開發好的程式做一次性的測試驗證,確保執行結果會跟預期結果一致。

使用 unittest 的步驟為

  1. 建立繼承自 TestCase 的類別 (class) 。
  2. 建立與測試程式命名相似方法,字首加上 test_ ,然後利用 TestCase 的類別的測試方法進行測試。
  3. 呼叫 unittest.main() ,跑出測試結果。

其中 TestCase 有以下的測試方法

方法功能
assertEqual(a, b)a == b
assertNotEqual(a, b)a != b
assertTrue(x)bool(x) is True
assertFalse(x)bool(x) is False
assertIs(a, b)a is b
assertIsNot(a, b)a is not b
assertIsNone(x)x is None
assertIn(a, b)x is not None
assertNotIn(a, b)a not in b
assertIsInstance(a, b)isinstance(a, b)
assertNotIsInstance(a, b)not isinstance(a, b)

例如有以下的程式

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

def subtract(a, b):
    return a - b

def multiply(a, b):
    return a * b

def divide(a, b):
    return a // b
  
#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:utdemo01.py
# 功能:示範 unittest 模組
# 作者:張凱慶

可用以下的程式進行單元測試

import unittest
from utdemo01 import add, subtract, multiply, divide

class TestDemo(unittest.TestCase):    
    def test_add(self):
        self.assertEqual(add(1, 3), 4)
    
    def test_subtract(self):
        self.assertEqual(subtract(5, 2), 3)
    
    def test_multiply(self):
        self.assertEqual(multiply(3, 2), 6)
        
    def test_divide(self):
        self.assertEqual(divide(6, 2), 3)
        
if __name__ == "__main__":
    unittest.main()

#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:utdemo02.py
# 功能:示範 unittest 模組
# 作者:張凱慶

注意 TestDemo 為自訂類別,這要繼承 unittest.TestCase

class TestDemo(unittest.TestCase):

assertEqual() 是判斷測試程式的結果是否與預期結果相同。

於命令列執行 utdemo02.py ,如下

$ python3 utdemo02.py
....
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
$

測試結果 OK

相關教學影片

上一頁: 12.9 圖形介面 tkinter
Python 速查手冊 - 目錄
回 Python 教材首頁
回程式語言教材首頁