2009年9月22日 星期二

寫 Python 測試碼的好幫手

前陣子用 TDD 寫了個六千多行的工具,這篇記錄一下過程中惠我良多的好幫手。

unittest

內建模組。

用法見官網介紹《Dive into Python 3》的第九章 Unit Testing ( 有附帶介紹 TDD ) ,如同 Java 的 JUnit 3.x,用 unittest.TestCase 來寫 test case 很方便。

coverage

安裝方式:easy_install coverage。

Code coverage 是分析測試碼品質的方法,標示出測試碼沒有執行到那幾行程式碼。使用 Code coverage 的基本精神是:Code coverage 的數據高不表示測試碼有效,但數據低的話,測試品質必定不好。至於高低要如何界定?這得看專案的類型,比方科學計算型的程式,要求 80% 以上並不過份;而有一堆圖形介面的程式,可能連到 60% 都很難。

coverage 官網有簡單易懂的使用例子。由於 Python 的功能限制,coverage 無法作到像 Java 那麼全面。coverage 的限制以及 Code coverage 的注意事項,詳見作者的說明:“Coverage testing, the good and the bad.”

nose

安裝方式: easy_install nose。

寫 unittest 時,管理 test suit 是件很瑣碎又易犯錯的事,相信很多人會想說,能不能跑個程式,自行搜集目錄下全部的測試碼並自動執行。沒錯,大家的心聲 nose 聽到了!這裡直接用例子說明 nose 的使用方式:

  • 執行目前目錄下所有測試:
    1
    
    nosetests
  • 執行目前目錄下所有測試並附上子目錄 pkg1、pkg2 的 Code coverage 資訊:
    1
    
    nosetests --with-coverage --cover-package=pkg1,pkg2 --cover-erase
  • 不要執行 slow_test.py:
    1
    
    nosetests -e slow_test.py
  • 使用四個 CPU 平行執行測試:
    1
    
    nosetests --processes=4

–with-coverage 需要先裝 coverage;–process 得另裝 package multiprocessing ( easy_install multiprocessing ),相關說明詳見 Multiprocess: parallel testing

另外,若要讓 nose 跳過物件 A 的測試,就在程式裡寫上

1
A.__test__ = False

比方若不想測模組 mod,就在 mod.py 裡寫上

1
__test__ = False

sqlite3

內建模組。

用法見官網介紹。在測試資料庫時,個人覺得 local database 比 mock 好用,方便準備資料,測起來也比較踏實,而且使用 memory mode 可大幅減少執行時間。附帶一提,sqlite 跨 C、Python、Java 等語言,支援 SQL 92,執行速度又快,相當好用。

PyMox

安裝方式: 用 SVN 從官網 checkout 原始碼,再用 setup.py 安裝:

1
2
3
svn checkout http://pymox.googlecode.com/svn/trunk/ pymox-read-only
cd pymox-read-only/
sudo python setup.py install

用法見官網文件。PyMox 是 Google 開發的 Python 版 EasyMock,我試用過 Java 的 EasyMock 後覺得用法挺直覺的,就決定用它,如此一來學一套工具可以同時用在 Java 和 Python 上。使用 mock 的好處是簡化測試碼,更完備地測試程式,像是代換掉處理資料庫、網路連線的物件。如此一來,連測試「讀資料到一半卻斷網」的應對情形,都是輕而易舉的事。若想立即體會 mock 的功效,不妨配合 mock 用 top-down 的方式作 TDD,會發覺不同的程式開發思維。

2012-08-05 更新: 我現在改用 Mockito 了,更為簡單易用 。

沒有留言:

張貼留言