關于Python 模塊發現之旅
本文進行著重講述有關Python 模塊的問題和技巧,在講解Python 模快之前首先先讓大家了解下什么是Python語言,所謂Python:是一種面向對象、直譯式計算機程序設計語言,也是一種功能強大而完善的通用型語言。
但是,它們采用的測試發現規則不太一樣,在選擇框架時需要考慮到這一點。測試框架執行的第一步是,選擇將在哪些目錄中搜索包含測試的文件。注意,這三種框架都從整個項目的基目錄開始搜索;如果要測試名為 example 的包,那么它們會從包含 example 的父目錄開始搜索測試。
但是,這三種框架在選擇搜索哪些目錄方面有所差異:zope.testing 工具向下遞歸地搜索是 Python 包的所有目錄,也就是包含 __init__.py 文件的目錄(對于Python 模塊,這說明可以用 import 語句導入它們)。
這意味著不檢查非包目錄中的數據和代碼,但是另一方面,這也意味著從理論上說程序員可以用 import 語句導入您編寫的每個測試。一些程序員覺得這讓人不舒服,希望能夠把測試放在包的一般用戶看不到的地方。
py.test 命令向下遞歸地搜索項目的每個目錄和子目錄,無論目錄是否是 Python 包。注意,當兩個相鄰目錄包含同名的測試時,它似乎有一個 bug。例如,如果相鄰的dir1/test.py 和 dir2/test.py 文件都包含名為 test_example 的測試,那么 py.test 將運行第一個測試兩次。
而完全忽略第二個測試!如果為 py.test 編寫測試并把它們放在非包目錄中,就要注意保持名稱是惟一的。nose 測試運行器采用的實現方式介于另兩種工具之間:它向下遞歸地搜索每個 Python 包,但是只檢查目錄名中包含單詞 test 的目錄。
這意味著,如果不想讓 nose 搜索某個目錄,那么只需注意不在目錄名中包含 test 即可。與 py.test 不同,nose 可以正確地處理包含同名測試的相鄰目錄(但是保持測試名稱惟一仍然是有幫助的,這樣在用 -v 選項顯示測試結果時不容易混淆)。
選擇了要搜索的目錄之后,這三種測試工具的做法就非常相似了:它們都尋找與某一模式匹配的 Python 模塊(也就是以 .py 結尾的文件)。zope.testing 工具在默認情況下使用正則表達式 "tests",也就是只尋找名為 tests.py 的文件,忽略其他所有文件。可以使用命令行選項或 buildout.cfg 指定另一個正則表達式
:
- # Snippet of a buildout.cfg file that searches for tests
- # in any Python module starting with "test" or "ftest".
- [test]
- recipe = zc.recipe.testrunner
- eggs = my_package
- defaults = ['--tests-pattern', 'f?test']
py.test 更死板,總是尋找名稱以 `test_ 開頭或以 _test 結尾的 Python 模塊。nosetests 命令更靈活,它使用一個正則表達式(“((?:^|[\b_\.-])[Tt]est)”)選擇以 test 或 Test 開頭或這個單詞處于單詞邊界后面的模塊。通過在命令行上使用 -m 選項或在項目的 .noserc 文件中設置這個選項,可以指定另一個正則表達式。
哪種方法最好?盡管一些開發人員喜歡有靈活性,而且許多人認為 zope.testing 工具的搜索范圍應該更寬,不應該只限于文件名為 tests.py 的模塊,但是我實際上更喜歡 py.test 采用的方式。
所有使用 py.test 的項目必須在測試命名方面采用一致的約定,這讓其他程序員更容易閱讀和維護測試。在使用另外兩種框架時。閱讀或創建測試文件需要兩步:首先,必須了解這個項目使用的正則表達式,然后才能檢查它的代碼。如果您同時從事多個項目,就必須記住幾種不同的測試文件命名約定。