正如引言中提到的,doctest已經(jīng)發(fā)展到三個主要用途:
這些用途具有不同的要求,區(qū)分它們很重要。特別是,用不明確的測試用例填充文檔字符串會導致錯誤的文檔。
在編寫文檔字符串時,請小心選擇文檔字符串示例。有一個學問需要學習 - 起初可能并不自然。示例應該為文檔增加真正的價值。一個很好的例子往往可以說很多話。如果謹慎處理,這些示例對您的用戶來說將是非常寶貴的,并且會隨著時間的推移和事情的變化而回報多次收集它們所需的時間。我仍然驚訝于我的一個doctest示例在“無害”更改后停止工作的頻率。
Doctest也是回歸測試的絕佳工具,特別是如果你不吝嗇解釋性文本。通過插入散文和例子,跟蹤實際正在測試的內(nèi)容以及為什么更容易。當一個測試失敗時,好的散文可以使得更容易找出問題所在,以及應該如何解決問題。的確,您可以在基于代碼的測試中編寫大量的評論,但很少有程序員會這樣做。許多人已經(jīng)發(fā)現(xiàn)使用doctest方法會導致更清晰的測試。也許這只是因為doctest使編寫散文比編寫代碼容易一些,而在代碼中編寫注釋有點困難。我認為它比以上更深刻:編寫基于doctest的測試時的自然態(tài)度是您想解釋軟件的優(yōu)點,并用示例來說明它們。這反過來自然會導致以最簡單的功能開始的測試文件,并在邏輯上進展到復雜性和邊緣情況。一個連貫的敘述是結果,而不是一組孤立的函數(shù),它們似乎隨機地測試孤立的功能位。這是一種不同的態(tài)度,產(chǎn)生不同的結果,模糊了測試和解釋之間的區(qū)別。
回歸測試最好局限于專用對象或文件。有幾種組織測試的選項:
當您將測試放入模塊中時,模塊本身可以成為測試運行者。當測試失敗時,您可以安排測試運行者在調(diào)試問題時僅重新運行失敗的doctest。這是一個這樣的測試運行者的最小例子:
if __name__ == '__main__':
import doctest
flags = doctest.REPORT_NDIFF|doctest.REPORT_ONLY_FIRST_FAILURE
if len(sys.argv) > 1:
name = sys.argv[1]
if name in globals():
obj = globals()[name]
else:
obj = __test__[name]
doctest.run_docstring_examples(obj, globals(), name=name,
optionflags=flags)
else:
fail, total = doctest.testmod(optionflags=flags)
print("{} failures out of {} tests".format(fail, total))
不支持包含預期輸出和異常的示例。試圖猜測一個結束和另一個開始的地方太容易出錯,這也會導致一個令人困惑的測試。
更多建議: