如何編寫和使用 doctest 在 Python 中的 docstrings 中編寫測試代碼。

商業

Python 自帶一個標準的 doctest 模塊,用於測試 docstring 的內容,使得在 docstring 中編寫輸入和輸出示例變得容易,並使文檔更易於理解。

此處提供以下信息。

  • 使用 doctest 進行測試的簡單示例
    • 如果沒有錯誤
    • 如果有錯誤
  • 通過選項和參數控制輸出結果
    • -v選項
    • verbose參數(例如函數、程序、程序)
  • 從命令行運行 doctest 模塊
  • 在外部文本文件中編寫測試
    • 如何編寫文本文件
    • 從py文件調用
    • 直接執行一個文本文件

使用 doctest 進行測試的簡單示例

文檔字符串是包含在以下之一中的字符串:(1)要測試的函數的名稱,(2)要測試的函數的名稱,以及(3)Python 交互模式下的預期輸出值。

  • """
  • ''

如果沒有錯誤

確保函數和文檔字符串內容中的代碼正確。

def add(a, b):
    '''
    >>> add(1, 2)
    3
    >>> add(5, 10)
    15
    '''

    return a + b


if __name__ == '__main__':
    import doctest
    doctest.testmod()

運行這個文件。

$ python3 doctest_example.py

如果沒有錯誤,則不會輸出任何內容。

if __name__ == '__main__'這意味著“僅當從命令行執行相應的腳本文件時才執行後續處理。

如果有錯誤

如果創建並執行以下錯誤代碼,將輸出錯誤。

def add(a, b):
    '''
    >>> add(1, 2)
    3
    >>> add(5, 10)
    10
    '''

    return a * b


if __name__ == '__main__':
    import doctest
    doctest.testmod()
$ python3 doctest_example_error.py
**********************************************************************
File "doctest_example_error.py", line 3, in __main__.add
Failed example:
    add(1, 2)
Expected:
    3
Got:
    2
**********************************************************************
File "doctest_example_error.py", line 5, in __main__.add
Failed example:
    add(5, 10)
Expected:
    10
Got:
    50
**********************************************************************
1 items had failures:
   2 of   2 in __main__.add
***Test Failed*** 2 failures.

如下所示。

用 doctest 編寫的預期輸出值。Expected
實際輸出值Got

通過選項和參數控制輸出結果

-v選項

如果您希望即使沒有錯誤也能顯示輸出結果,請在命令行上運行帶有 -v 選項的命令。

$ python3 doctest_example.py -v
Trying:
    add(1, 2)
Expecting:
    3
ok
Trying:
    add(5, 10)
Expecting:
    15
ok
1 items had no tests:
    __main__
1 items passed all tests:
   2 tests in __main__.add
2 tests in 2 items.
2 passed and 0 failed.
Test passed.

verbose參數(例如函數、程序、程序)

如果要始終顯示輸出結果,請在 py 文件的 doctest.testmod() 中指定參數 verbose=True 。

if __name__ == '__main__':
    import doctest
    doctest.testmod(verbose=True)

輸出結果將始終在運行時不帶 -v 選項顯示。

$ python3 doctest_example_verbose.py
Trying:
    add(1, 2)
Expecting:
    3
ok
Trying:
    add(5, 10)
Expecting:
    15
ok
1 items had no tests:
    __main__
1 items passed all tests:
   2 tests in __main__.add
2 tests in 2 items.
2 passed and 0 failed.
Test passed.

從命令行運行 doctest 模塊

if __name__ == '__main__'如果你想在裡面做其他事情,你可以直接從命令行運行 doctest 模塊,而無需在 py 文件中調用 doctest.testmod()。

例如,在以下情況下

def add(a, b):
    '''
    >>> add(1, 2)
    3
    >>> add(5, 10)
    15
    '''

    return a + b


if __name__ == '__main__':
    import sys
    result = add(int(sys.argv[1]), int(sys.argv[2]))
    print(result)

它可以接收命令行參數並照常執行進程。

$ python3 doctest_example_without_import.py 3 4
7

如果您使用 -m 選項將 doctest 作為腳本運行,則測試將針對編寫 doctest 的函數運行。如果要顯示輸出結果,請像以前一樣添加 -v。

$ python3 -m doctest doctest_example_without_import.py

$ python3 -m doctest -v doctest_example_without_import.py
Trying:
    add(1, 2)
Expecting:
    3
ok
Trying:
    add(5, 10)
Expecting:
    15
ok
1 items had no tests:
    doctest_example_without_import
1 items passed all tests:
   2 tests in doctest_example_without_import.add
2 tests in 2 items.
2 passed and 0 failed.
Test passed.

在外部文本文件中編寫測試

您還可以在外部文本文件中而不是在文檔字符串中編寫測試代碼。

如何編寫文本文件

以 Python 交互模式格式編寫,如 docstring 中所述。需要導入要使用的函數。

如果你想把文本文件和要測試的.py文件放在同一個目錄下,直接按如下方式導入即可。

>>> from doctest_example import add
>>> add(1, 2)
3
>>> add(5, 10)
15

從py文件調用

在另一個 .py 文件中調用 doctest.testfile() 進行測試。

指定寫入測試代碼的文本文件的路徑作為 doctest.testfile() 的參數。

import doctest
doctest.testfile('doctest_text.txt')

運行這個py文件。

$ python3 doctest_example_testfile.py -v
Trying:
    from doctest_example import add
Expecting nothing
ok
Trying:
    add(1, 2)
Expecting:
    3
ok
Trying:
    add(5, 10)
Expecting:
    15
ok
1 items passed all tests:
   3 tests in doctest_text.txt
3 tests in 1 items.
3 passed and 0 failed.
Test passed.

直接執行一個文本文件

即使您沒有 py 文件,您也可以直接從命令行讀取文本文件並運行測試。

使用 -m 選項運行 Python 命令以將 doctest 作為腳本運行。您可以將文本文件路徑指定為命令行參數。

$ python3 -m doctest -v doctest_text.txt
Trying:
    from doctest_example import add
Expecting nothing
ok
Trying:
    add(1, 2)
Expecting:
    3
ok
Trying:
    add(5, 10)
Expecting:
    15
ok
1 items passed all tests:
   3 tests in doctest_text.txt
3 tests in 1 items.
3 passed and 0 failed.
Test passed.
Copied title and URL