功能強大的Python 測試框架說明
我對 FP 的所有描述都是使用Python 測試框架做到的。但最重要的特性 -- 可能也是具體情況中最有用的特性 -- 是它消除了副作用(或者至少對一些特殊領域,例如單一體,有一些牽制作用)。
絕大部分程序錯誤 -- 和促使程序員求助于調(diào)試來解決的問題 -- 之所以會發(fā)生,是因為在程序執(zhí)行過程期間,變量包含了意外的值。函數(shù)程序只不過根本就不為變量分配值,從而避免了這一特殊問題。
讓我們看一段相當普通的命令代碼。它的目的是打印出乘積大于 25 的幾對數(shù)字的列表。組成各對的數(shù)字本身是從另外兩個列表中挑選出的。這種操作與程序員在他們程序段中實際執(zhí)行的操作差不多。實現(xiàn)這一目的的命令方法如下:
這個項目太小,以至于沒有什么可能出錯。但我們的目的可能嵌在要同時實現(xiàn)許多其它目的的代碼中。用 "more stuff" 注釋的那些部分是副作用可能導致錯誤發(fā)生的地方。在這些地方中的任何一處,變量 xs、ys、bigmuls、x、 y 有可能獲得假設節(jié)略代碼中的意外值。而且,在執(zhí)行完這一段代碼后,所有變量都可能具有稍后代碼可能需要也可能不需要的一些值。
很明顯,可以使用函數(shù)/實例形式的封裝和有關作用域的考慮來防止出現(xiàn)這種類型的錯誤。而且,您總是可以在執(zhí)行完變量后 del 它們。但在實際中,這些指出類型的錯誤非常普遍。
對于 Python 測試框架,您會發(fā)現(xiàn) Zope 社區(qū)有一些有意思的現(xiàn)象。Zope 社區(qū)并不為解決每個問題構建大型工具,而是構建小型的功能有限的工具,這些工具能夠連接在一起。目前,zope.testing 模塊本身實際上根本沒有提供檢測測試的機制!
相反,zope.testing 讓程序員自己尋找每個模塊中需要運行的測試并把它們集中在一個列表中。它在每個測試模塊中只尋找一個東西:test_suite() 函數(shù),這個函數(shù)應該返回標準 unittest.TestSuite 類的實例,其中包含模塊定義的測試。
使用 zope.testing 的一些程序員在 test_suite() 函數(shù)中手工地創(chuàng)建和維護測試列表。其他程序員通過編寫定制代碼發(fā)現(xiàn)已經(jīng)定義的可用測試。但是,最有意思的方法是使用另一個 Zope 包 z3c.testsetup,它能夠像其他現(xiàn)代 Python 測試框架一樣自動地發(fā)現(xiàn)包中的測試。
這一現(xiàn)象再次說明 Zope 程序員傾向于編寫小型代碼塊,然后使用它們構建框架,而不是編寫大型的全面解決方案。z3c.testsetup 包不包含可以選擇測試的命令行界面,也不包含可以顯示測試結(jié)果的輸出模塊;它完全依靠 zope.testing 實現(xiàn)這些功能。
實際上,z3c.testsetup 用戶一般不使用 zope.testing 的測試模塊發(fā)現(xiàn)功能。相反,他們繞開 zope.testing 的算法,按照它的默認行為只尋找名為 test.py 的模塊,然后在整個源代碼樹中只提供一個采用此名稱的模塊。在最簡單的情況下,他們的 test.py 像下面這樣:
【編輯推薦】