我要坦白一點。盡管我是一個應用相當廣泛的公共域 Python 庫的創造者,但在我的模塊中引入的單元測試是非常不系統的。實際上,那些測試大部分 是包括在 gnosis.xml.pickle 的 Gnosis Utilities 中的,并由該子軟件包(subpackage)的貢獻者所編寫。我還發現,我下載的絕大多數第三方 Python 包都缺少完備的單元測試集。
不僅如此,Gnosis Utilities 中現有的測試也受困于另一個缺陷:您經常需要在極其大量的細節中去推定期望的輸出,以確定測試的成敗。測試實際上 -- 在很多情況下 -- 更像是使用庫的某些部分的小實用工具。這些測試(或實用工具)支持來自任意數據源(類型正確)的輸入和/或描述性數據格式的輸出。實際上,當您需要調試一些細微的錯誤時,這些測試實用工具更有用。但是對于庫版本間變化的自解釋的完整性檢查(sanity checks)來說,這些類測試就不能勝任了。
在這一期文章中,我嘗試使用 Python 標準庫模塊 doctest 和 unittest 來改進我的實用工具集中的測試,并帶領您與我一起體驗(并指出一些最好的方法)。
腳本 gnosis/xml/objectify/test/test_basic.py 給出了一個關于當前測試的缺點及解決方案的典型示例。下面是該腳本的最新版本:
清單 1. test_basic.py
"Read and print and objectified XML file"import sysfrom gnosis.xml.objectify import XML_Objectify, pyobj_printerif len(sys.argv) > 1: for filename in sys.argv[1:]: for parser in ('DOM','EXPAT'): try: xml_obj = XML_Objectify(filename, parser=parser) py_obj = xml_obj.make_instance() print pyobj_printer(py_obj).encode('UTF-8') sys.stderr.write("++ SUCCESS (using "+parser+")/n") print "="*50 except: sys.stderr.write("++ FAILED (using "+parser+")/n") print "="*50else: print "Please specify one or more XML files to Objectify."
實用工具函數 pyobj_printer() 生成了任意 Python 對象(具體說是這樣一個對象,它既沒有用到 gnosis.xml.objectify 的任何其他實用工具,也沒有用到 Gnosis Utilities 中的 任何其他東西)的一個 非-XML 表示。在以后的版本中,我將可能會把這個函數移到 Gnosis 包內的其他地方。無論如何, pyobj_printer() 使用各種類-Python 的縮進和符號來描述對象和它們的屬性(類似于 pprint ,但是擴展了實例,而不僅限于擴展內置的數據類型)。
如果一些特別的 XML 可能不能正確被地“對象化(objectified)”, test_basic.py 腳本會提供一個很好的調試工具 -- 您可以可視化地查看結果對象的屬性和值。此外,如果您重定向了 STDOUT,您可以查看 STDERR 上的簡單消息,如這個例子中:
清單 2. 分析 STDERR 結果消息
$ python test_basic.py testns.xml > /dev/null++ SUCCESS (using DOM)++ FAILED (using EXPAT)
新聞熱點
疑難解答