test — Python 迴歸測試包

注意

test 包僅供 Python 內部使用。它的文件僅為 Python 的核心開發人員提供便利。不鼓勵在 Python 標準庫之外使用此包,因為此處提到的程式碼可能會在 Python 版本之間更改或刪除,恕不另行通知。


test 包包含 Python 的所有迴歸測試,以及模組 test.supporttest.regrtesttest.support 用於增強您的測試,而 test.regrtest 則驅動測試套件。

test 包中名稱以 test_ 開頭的每個模組都是特定模組或功能的測試套件。所有新測試都應使用 unittestdoctest 模組編寫。一些較舊的測試是使用“傳統”測試風格編寫的,該風格比較列印到 sys.stdout 的輸出;這種測試風格被認為是已棄用的。

另請參閱

模組 unittest

編寫 PyUnit 迴歸測試。

模組 doctest

嵌入在文件字串中的測試。

test 包編寫單元測試

首選使用 unittest 模組的測試遵循一些準則。其中之一是將測試模組的名稱以 test_ 開頭,並以被測試的模組的名稱結尾。測試模組中的測試方法應以 test_ 開頭,並以描述該方法正在測試的內容結尾。這是必需的,以便測試驅動程式將這些方法識別為測試方法。此外,不應包含該方法的文件字串。應使用註釋(例如 # 測試函式僅返回 True False)來為測試方法提供文件。這樣做是因為如果存在文件字串,它們會被打印出來,從而不會說明正在執行的測試。

通常使用基本的樣板程式碼

import unittest
from test import support

class MyTestCase1(unittest.TestCase):

    # Only use setUp() and tearDown() if necessary

    def setUp(self):
        ... code to execute in preparation for tests ...

    def tearDown(self):
        ... code to execute to clean up after tests ...

    def test_feature_one(self):
        # Test feature one.
        ... testing code ...

    def test_feature_two(self):
        # Test feature two.
        ... testing code ...

    ... more test methods ...

class MyTestCase2(unittest.TestCase):
    ... same structure as MyTestCase1 ...

... more test classes ...

if __name__ == '__main__':
    unittest.main()

此程式碼模式允許測試套件由 test.regrtest 執行,它本身作為一個支援 unittest CLI 的指令碼,或者透過 python -m unittest CLI 執行。

迴歸測試的目標是嘗試破壞程式碼。這導致需要遵循一些準則

  • 測試套件應覆蓋所有類、函式和常量。這不僅包括要呈現給外部的外部 API,還包括“私有”程式碼。

  • 首選白盒測試(在編寫測試時檢查被測程式碼)。黑盒測試(僅測試已釋出的用使用者介面)不足以確保所有邊界和邊緣情況都經過測試。

  • 確保測試所有可能的值,包括無效值。這不僅確保所有有效值都是可接受的,而且確保不正確的值得到正確處理。

  • 儘可能窮盡程式碼路徑。測試分支發生的地方,從而調整輸入以確保儘可能多地執行不同的程式碼路徑。

  • 為被測程式碼中發現的任何錯誤新增顯式測試。這將確保如果將來程式碼發生更改,錯誤不會再次出現。

  • 確保在測試後進行清理(例如關閉和刪除所有臨時檔案)。

  • 如果測試依賴於作業系統的特定條件,則在嘗試測試之前驗證該條件是否已存在。

  • 儘可能少地匯入模組,並儘快匯入。這最大限度地減少了測試的外部依賴性,也最大限度地減少了匯入模組的副作用可能造成的異常行為。

  • 儘量最大化程式碼重用。有時,測試的變化可能只在於使用的輸入型別。透過使用指定輸入的類對基本測試類進行子類化,從而儘量減少程式碼重複。

    class TestFuncAcceptsSequencesMixin:
    
        func = mySuperWhammyFunction
    
        def test_func(self):
            self.func(self.arg)
    
    class AcceptLists(TestFuncAcceptsSequencesMixin, unittest.TestCase):
        arg = [1, 2, 3]
    
    class AcceptStrings(TestFuncAcceptsSequencesMixin, unittest.TestCase):
        arg = 'abc'
    
    class AcceptTuples(TestFuncAcceptsSequencesMixin, unittest.TestCase):
        arg = (1, 2, 3)
    

    當使用此模式時,請記住,所有繼承自 unittest.TestCase 的類都作為測試執行。上面的示例中的 TestFuncAcceptsSequencesMixin 類沒有任何資料,因此不能單獨執行,因此它不繼承自 unittest.TestCase

另請參閱

測試驅動開發

Kent Beck 關於在編寫程式碼之前編寫測試的一本書。

使用命令列介面執行測試

由於 -m 選項,test 包可以作為指令碼執行來驅動 Python 的迴歸測試套件:python -m test。在底層,它使用 test.regrtest;以前 Python 版本中使用的呼叫 python -m test.regrtest 仍然有效。單獨執行指令碼會自動啟動執行 test 包中的所有迴歸測試。它透過查詢包中名稱以 test_ 開頭的所有模組,匯入它們,並執行函式 test_main() (如果存在)或透過 unittest.TestLoader.loadTestsFromModule 載入測試(如果 test_main 不存在)。要執行的測試名稱也可以傳遞給指令碼。指定單個迴歸測試 (python -m test test_spam) 將最小化輸出,並且只打印測試是透過還是失敗。

直接執行 test 允許設定可供測試使用的資源。您可以使用 -u 命令列選項來執行此操作。將 all 指定為 -u 選項的值將啟用所有可能的資源:python -m test -uall。如果需要除一個資源之外的所有資源(更常見的情況),可以在 all 之後列出以逗號分隔的不需要的資源列表。命令 python -m test -uall,-audio,-largefile 將執行 test,其中包含除 audiolargefile 資源之外的所有資源。有關所有資源和更多命令列選項的列表,請執行 python -m test -h

執行迴歸測試的其他一些方法取決於執行測試的平臺。在 Unix 上,您可以在構建 Python 的頂層目錄中執行 make test。在 Windows 上,從您的 PCbuild 目錄執行 rt.bat 將執行所有迴歸測試。

test.support — Python 測試套件的實用工具

test.support 模組為 Python 的迴歸測試套件提供了支援。

注意

test.support 不是公共模組。此處記錄它是為了幫助 Python 開發人員編寫測試。此模組的 API 可能會在版本之間更改,而無需考慮向後相容性。

此模組定義以下異常

exception test.support.TestFailed

當測試失敗時引發的異常。此異常已棄用,贊成使用基於 unittest 的測試和 unittest.TestCase 的斷言方法。

exception test.support.ResourceDenied

unittest.SkipTest 的子類。當資源(例如網路連線)不可用時引發。由 requires() 函式引發。

test.support 模組定義以下常量

test.support.verbose

啟用詳細輸出時為 True。當需要有關正在執行的測試的更多詳細資訊時,應檢查此項。verbosetest.regrtest 設定。

test.support.is_jython

如果正在執行的直譯器是 Jython,則為 True

test.support.is_android

如果系統是 Android,則為 True

test.support.unix_shell

如果不在 Windows 上,則為 shell 的路徑;否則為 None

test.support.LOOPBACK_TIMEOUT

使用在網路本地環回介面(如 127.0.0.1)上偵聽的網路伺服器進行測試的超時時間(以秒為單位)。

超時時間足夠長,可以防止測試失敗:它考慮到客戶端和伺服器可以在不同的執行緒甚至不同的程序中執行。

超時時間應足夠長,以允許 connect()recv()send() 方法的 socket.socket 方法。

其預設值為 5 秒。

另請參閱 INTERNET_TIMEOUT

test.support.INTERNET_TIMEOUT

向 Internet 傳送網路請求的超時時間(以秒為單位)。

超時時間足夠短,可以防止測試在因任何原因阻止 Internet 請求時等待太長時間。

通常,使用 INTERNET_TIMEOUT 的超時不應將測試標記為失敗,而是應跳過測試:請參閱 transient_internet()

其預設值為 1 分鐘。

另請參閱 LOOPBACK_TIMEOUT

test.support.SHORT_TIMEOUT

如果測試花費“太長時間”,則將測試標記為失敗的超時時間(以秒為單位)。

超時值取決於 regrtest --timeout 命令列選項。

如果使用 SHORT_TIMEOUT 的測試開始在較慢的構建機器人上隨機失敗,請改用 LONG_TIMEOUT

其預設值為 30 秒。

test.support.LONG_TIMEOUT

用於檢測測試何時掛起的超時時間(以秒為單位)。

它足夠長,可以降低在最慢的 Python 構建機器人上測試失敗的風險。 如果測試花費“太長時間”,則不應使用它將測試標記為失敗。 超時值取決於 regrtest --timeout 命令列選項。

其預設值為 5 分鐘。

另請參閱 LOOPBACK_TIMEOUTINTERNET_TIMEOUTSHORT_TIMEOUT

test.support.PGO

當測試對於 PGO 無用時,設定此項以便跳過測試。

test.support.PIPE_MAX_SIZE

一個常量,它可能大於底層作業系統管道緩衝區大小,以使寫入阻塞。

test.support.Py_DEBUG

如果 Python 是使用定義了 Py_DEBUG 宏構建的,即如果 Python 是以除錯模式構建的,則為 True

3.12 版本中新增。

test.support.SOCK_MAX_SIZE

一個常量,它可能大於底層作業系統套接字緩衝區大小,以使寫入阻塞。

test.support.TEST_SUPPORT_DIR

設定為包含 test.support 的頂層目錄。

test.support.TEST_HOME_DIR

設定為測試包的頂層目錄。

test.support.TEST_DATA_DIR

設定為測試包中的 data 目錄。

test.support.MAX_Py_ssize_t

對於大記憶體測試,設定為 sys.maxsize

test.support.max_memuse

set_memlimit() 設定為大記憶體測試的記憶體限制。受 MAX_Py_ssize_t 限制。

test.support.real_max_memuse

set_memlimit() 設定為大記憶體測試的記憶體限制。不受 MAX_Py_ssize_t 限制。

test.support.MISSING_C_DOCSTRINGS

如果 Python 是在沒有文件字串的情況下構建的(未定義 WITH_DOC_STRINGS 宏),則設定為 True。請參閱 configure --without-doc-strings 選項。

另請參閱 HAVE_DOCSTRINGS 變數。

test.support.HAVE_DOCSTRINGS

如果函式文件字串可用,則設定為 True。請參閱 python -OO 選項,該選項會刪除 Python 中實現的函式的文件字串。

另請參閱 MISSING_C_DOCSTRINGS 變數。

test.support.TEST_HTTP_URL

定義網路測試的專用 HTTP 伺服器的 URL。

test.support.ALWAYS_EQ

一個與任何事物都相等的物件。 用於測試混合型別比較。

test.support.NEVER_EQ

一個與任何事物都不相等的物件(甚至與 ALWAYS_EQ 也不相等)。 用於測試混合型別比較。

test.support.LARGEST

一個比任何事物都大的物件(除了它本身)。 用於測試混合型別比較。

test.support.SMALLEST

一個比任何事物都小的物件(除了它本身)。 用於測試混合型別比較。

test.support 模組定義了以下函式

test.support.busy_retry(timeout, err_msg=None, /, *, error=True)

執行迴圈體,直到 break 停止迴圈。

timeout 秒後,如果 error 為 true,則引發 AssertionError,如果 error 為 false,則僅停止迴圈。

示例

for _ in support.busy_retry(support.SHORT_TIMEOUT):
    if check():
        break

error=False 用法示例

for _ in support.busy_retry(support.SHORT_TIMEOUT, error=False):
    if check():
        break
else:
    raise RuntimeError('my custom error')
test.support.sleeping_retry(timeout, err_msg=None, /, *, init_delay=0.010, max_delay=1.0, error=True)

應用指數退避的等待策略。

執行迴圈體,直到 break 停止迴圈。 在每次迴圈迭代時休眠,但不在第一次迭代時休眠。 休眠延遲在每次迭代時加倍(最多 max_delay 秒)。

有關引數用法,請參閱 busy_retry() 文件。

在 SHORT_TIMEOUT 秒後引發異常的示例

for _ in support.sleeping_retry(support.SHORT_TIMEOUT):
    if check():
        break

error=False 用法示例

for _ in support.sleeping_retry(support.SHORT_TIMEOUT, error=False):
    if check():
        break
else:
    raise RuntimeError('my custom error')
test.support.is_resource_enabled(resource)

如果resource已啟用且可用,則返回 True。 只有在 test.regrtest 執行測試時,才會設定可用資源的列表。

test.support.python_is_optimized()

如果 Python 在構建時未使用 -O0-Og,則返回 True

test.support.with_pymalloc()

返回 _testcapi.WITH_PYMALLOC

test.support.requires(resource, msg=None)

如果 resource 不可用,則引發 ResourceDenied。 如果引發異常,msgResourceDenied 的引數。 如果由 __name__'__main__' 的函式呼叫,則始終返回 True。當測試由 test.regrtest 執行時使用。

test.support.sortdict(dict)

返回鍵已排序的 dict 的 repr。

test.support.findfile(filename, subdir=None)

返回名為 filename 的檔案的路徑。 如果未找到匹配項,則返回 filename。 這不等於失敗,因為它可能是檔案的路徑。

設定 subdir 表示要用於查詢檔案的相對路徑,而不是直接在路徑目錄中查詢。

test.support.get_pagesize()

獲取頁面的大小(以位元組為單位)。

3.12 版本中新增。

test.support.setswitchinterval(interval)

sys.setswitchinterval() 設定為給定的 interval。 為 Android 系統定義最小間隔,以防止系統掛起。

test.support.check_impl_detail(**guards)

使用此檢查來保護 CPython 的特定於實現的測試,或僅在由引數保護的實現上執行它們。 此函式根據主機平臺返回 TrueFalse。 用法示例

check_impl_detail()               # Only on CPython (default).
check_impl_detail(jython=True)    # Only on Jython.
check_impl_detail(cpython=False)  # Everywhere except CPython.
test.support.set_memlimit(limit)

為大記憶體測試設定 max_memusereal_max_memuse 的值。

test.support.record_original_stdout(stdout)

儲存來自 stdout 的值。 它旨在儲存 regrtest 開始時的標準輸出。

test.support.get_original_stdout()

返回由 record_original_stdout() 設定的原始標準輸出,如果未設定,則返回 sys.stdout

test.support.args_from_interpreter_flags()

返回一個命令列引數列表,用於重現 sys.flagssys.warnoptions 中的當前設定。

test.support.optim_args_from_interpreter_flags()

返回一個命令列引數列表,用於重現 sys.flags 中的當前最佳化設定。

test.support.captured_stdin()
test.support.captured_stdout()
test.support.captured_stderr()

一個上下文管理器,它臨時將命名流替換為 io.StringIO 物件。

輸出流的用法示例

with captured_stdout() as stdout, captured_stderr() as stderr:
    print("hello")
    print("error", file=sys.stderr)
assert stdout.getvalue() == "hello\n"
assert stderr.getvalue() == "error\n"

輸入流的用法示例

with captured_stdin() as stdin:
    stdin.write('hello\n')
    stdin.seek(0)
    # call test code that consumes from sys.stdin
    captured = input()
self.assertEqual(captured, "hello")
test.support.disable_faulthandler()

一個上下文管理器,臨時停用 faulthandler

test.support.gc_collect()

強制儘可能多地收集物件。 這是必需的,因為垃圾回收器不保證及時釋放。 這意味著 __del__ 方法可能會比預期的時間晚呼叫,並且弱引用可能會比預期的時間長地保持活動狀態。

test.support.disable_gc()

一個上下文管理器,在進入時停用垃圾回收器。 退出時,垃圾回收器將恢復到其先前的狀態。

test.support.swap_attr(obj, attr, new_val)

用於將屬性與新物件交換的上下文管理器。

用法

with swap_attr(obj, "attr", 5):
    ...

這將在 with 程式碼塊的持續時間內將 obj.attr 設定為 5,並在程式碼塊末尾恢復舊值。 如果 obj 上不存在 attr,它將被建立,然後在程式碼塊末尾刪除。

舊值(如果不存在,則為 None)將分配給“as”子句的目標(如果有)。

test.support.swap_item(obj, attr, new_val)

用於將項與新物件交換的上下文管理器。

用法

with swap_item(obj, "item", 5):
    ...

這將在 with 程式碼塊的持續時間內將 obj["item"] 設定為 5,並在程式碼塊結束時恢復舊值。如果 itemobj 上不存在,則會建立它,然後在程式碼塊結束時刪除它。

舊值(如果不存在,則為 None)將分配給“as”子句的目標(如果有)。

test.support.flush_std_streams()

呼叫 sys.stdout 上的 flush() 方法,然後再呼叫 sys.stderr 上的 flush() 方法。它可用於確保在寫入 stderr 之前日誌順序是一致的。

3.11 版本中新增。

test.support.print_warning(msg)

將警告列印到 sys.__stderr__。將訊息格式化為: f"Warning -- {msg}"。如果 msg 由多行組成,則在每行前面新增 "Warning -- " 字首。

3.9 版本中新增。

test.support.wait_process(pid, *, exitcode, timeout=None)

等待程序 pid 完成,並檢查程序退出程式碼是否為 exitcode

如果程序退出程式碼不等於 exitcode,則引發 AssertionError

如果程序執行時間超過 timeout 秒(預設為 SHORT_TIMEOUT),則終止該程序並引發 AssertionError。超時功能在 Windows 上不可用。

3.9 版本中新增。

test.support.calcobjsize(fmt)

返回 PyObject 的大小,其結構成員由 fmt 定義。返回的值包括 Python 物件頭的大小和對齊方式。

test.support.calcvobjsize(fmt)

返回 PyVarObject 的大小,其結構成員由 fmt 定義。返回的值包括 Python 物件頭的大小和對齊方式。

test.support.checksizeof(test, o, size)

對於測試用例 test,斷言 osys.getsizeof 加上 GC 頭部大小等於 size

@test.support.anticipate_failure(condition)

一個裝飾器,用於有條件地使用 unittest.expectedFailure() 標記測試。任何使用此裝飾器的地方都應附帶一條註釋,以標識相關的跟蹤器問題。

test.support.system_must_validate_cert(f)

一個裝飾器,在 TLS 證書驗證失敗時跳過被裝飾的測試。

@test.support.run_with_locale(catstr, *locales)

一個裝飾器,用於在不同的區域設定中執行函式,並在完成後正確重置它。catstr 是區域設定類別,以字串形式表示(例如 "LC_ALL")。將按順序嘗試傳入的 locales,並將使用第一個有效的區域設定。

@test.support.run_with_tz(tz)

一個裝飾器,用於在特定的時區中執行函式,並在完成後正確重置它。

@test.support.requires_freebsd_version(*min_version)

在 FreeBSD 上執行測試時,用於設定最低版本的裝飾器。如果 FreeBSD 版本小於最低版本,則跳過測試。

@test.support.requires_linux_version(*min_version)

在 Linux 上執行測試時,用於設定最低版本的裝飾器。如果 Linux 版本小於最低版本,則跳過測試。

@test.support.requires_mac_version(*min_version)

在 macOS 上執行測試時,用於設定最低版本的裝飾器。如果 macOS 版本小於最低版本,則跳過測試。

@test.support.requires_gil_enabled

一個裝飾器,用於在自由執行緒構建上跳過測試。如果 GIL 被停用,則跳過測試。

@test.support.requires_IEEE_754

一個裝飾器,用於在非 IEEE 754 平臺上跳過測試。

@test.support.requires_zlib

一個裝飾器,如果 zlib 不存在,則跳過測試。

@test.support.requires_gzip

一個裝飾器,如果 gzip 不存在,則跳過測試。

@test.support.requires_bz2

一個裝飾器,如果 bz2 不存在,則跳過測試。

@test.support.requires_lzma

一個裝飾器,如果 lzma 不存在,則跳過測試。

@test.support.requires_resource(resource)

一個裝飾器,如果 resource 不可用,則跳過測試。

@test.support.requires_docstrings

一個裝飾器,僅在 HAVE_DOCSTRINGS 時執行測試。

@test.support.requires_limited_api

一個裝飾器,僅在 有限 C API 可用時執行測試。

@test.support.cpython_only

僅適用於 CPython 的測試裝飾器。

@test.support.impl_detail(msg=None, **guards)

用於在 guards 上呼叫 check_impl_detail() 的裝飾器。如果返回 False,則使用 msg 作為跳過測試的原因。

@test.support.no_tracing

在測試期間臨時關閉跟蹤的裝飾器。

@test.support.refcount_test

用於涉及引用計數的測試的裝飾器。如果測試不是由 CPython 執行的,則裝飾器不會執行測試。在測試期間,任何跟蹤函式都會被取消設定,以防止跟蹤函式導致意外的引用計數。

@test.support.bigmemtest(size, memuse, dry_run=True)

用於 bigmem 測試的裝飾器。

size 是測試請求的大小(以任意、測試解釋的單位表示)。memuse 是測試的每個單位的位元組數,或其良好估計值。例如,一個需要兩個 4 GiB 位元組緩衝區的測試可以用 @bigmemtest(size=_4G, memuse=2) 進行裝飾。

size 引數通常作為額外的引數傳遞給被裝飾的測試方法。如果 dry_runTrue,則傳遞給測試方法的值可能小於請求的值。如果 dry_runFalse,則表示在未指定 -M 時,測試不支援虛擬執行。

@test.support.bigaddrspacetest

用於填充地址空間的測試的裝飾器。

test.support.check_syntax_error(testcase, statement, errtext='', *, lineno=None, offset=None)

透過嘗試編譯 statement 來測試 statement 中的語法錯誤。testcase 是測試的 unittest 例項。errtext 是應該與引發的 SyntaxError 的字串表示形式匹配的正則表示式。如果 lineno 不是 None,則與異常的行進行比較。如果 offset 不是 None,則與異常的偏移量進行比較。

test.support.open_urlresource(url, *args, **kw)

開啟 url。如果開啟失敗,則引發 TestFailed

test.support.reap_children()

每當啟動子程序時,在 test_main 的末尾使用此方法。這將有助於確保沒有額外的子程序(殭屍)滯留,佔用資源並在查詢記憶體洩漏時造成問題。

test.support.get_attribute(obj, name)

獲取屬性,如果引發 AttributeError,則引發 unittest.SkipTest

test.support.catch_unraisable_exception()

使用 sys.unraisablehook() 捕獲無法引發的異常的上下文管理器。

儲存異常值(cm.unraisable.exc_value)會建立引用迴圈。當上下文管理器退出時,引用迴圈會被顯式打破。

如果將物件設定為正在最終化的物件,則儲存物件(cm.unraisable.object)可以使其復活。退出上下文管理器會清除儲存的物件。

用法

with support.catch_unraisable_exception() as cm:
    # code creating an "unraisable exception"
    ...

    # check the unraisable exception: use cm.unraisable
    ...

# cm.unraisable attribute no longer exists at this point
# (to break a reference cycle)

在版本 3.8 中新增。

test.support.load_package_tests(pkg_dir, loader, standard_tests, pattern)

用於測試包的 unittest load_tests 協議的通用實現。pkg_dir 是包的根目錄;loaderstandard_testspatternload_tests 期望的引數。在簡單的情況下,測試包的 __init__.py 可以是以下內容

import os
from test.support import load_package_tests

def load_tests(*args):
    return load_package_tests(os.path.dirname(__file__), *args)
test.support.detect_api_mismatch(ref_api, other_api, *, ignore=())

返回 other_api 上未找到的 ref_api 的屬性、函式或方法的集合,除了 ignore 中指定的要在此檢查中忽略的已定義專案列表。

預設情況下,這會跳過以“_”開頭的私有屬性,但包括所有魔術方法,即以“__”開頭和結尾的方法。

在版本 3.5 中新增。

test.support.patch(test_instance, object_to_patch, attr_name, new_value)

使用 new_value 覆蓋 object_to_patch.attr_name。還向 test_instance 新增清理過程,以還原 object_to_patchattr_nameattr_name 應該是 object_to_patch 的有效屬性。

test.support.run_in_subinterp(code)

在子直譯器中執行 code。如果啟用了 tracemalloc,則引發 unittest.SkipTest

test.support.check_free_after_iterating(test, iter, cls, args=())

斷言在迭代後釋放 cls 的例項。

test.support.missing_compiler_executable(cmd_names=[])

檢查 cmd_names 中列出的編譯器可執行檔案是否存在,或者在 cmd_names 為空時檢查所有編譯器可執行檔案是否存在,並返回第一個缺失的可執行檔案,或者在未找到缺失的可執行檔案時返回 None

test.support.check__all__(test_case, module, name_of_module=None, extra=(), not_exported=())

斷言 模組__all__ 變數包含所有公共名稱。

模組的公共名稱(其 API)是根據它們是否符合公共名稱約定以及是否在 模組 中定義來自動檢測的。

name_of_module 引數可以指定(作為字串或字串元組)在哪些模組中可以定義 API,以便被檢測為公共 API。一種情況是當 模組 從其他模組匯入其部分公共 API 時,可能是 C 後端(如 csv 及其 _csv)。

extra 引數可以是一組名稱,這些名稱通常不會被自動檢測為“公共”,例如沒有適當 __module__ 屬性的物件。如果提供,它將被新增到自動檢測的名稱中。

not_exported 引數可以是一組名稱,即使它們的名稱另有指示,也不得將其視為公共 API 的一部分。

用法示例

import bar
import foo
import unittest
from test import support

class MiscTestCase(unittest.TestCase):
    def test__all__(self):
        support.check__all__(self, foo)

class OtherTestCase(unittest.TestCase):
    def test__all__(self):
        extra = {'BAR_CONST', 'FOO_CONST'}
        not_exported = {'baz'}  # Undocumented name.
        # bar imports part of its API from _bar.
        support.check__all__(self, bar, ('bar', '_bar'),
                             extra=extra, not_exported=not_exported)

在 3.6 版本中新增。

test.support.skip_if_broken_multiprocessing_synchronize()

如果缺少 multiprocessing.synchronize 模組,如果沒有可用的訊號量實現,或者建立鎖引發 OSError,則跳過測試。

在 3.10 版本中新增。

test.support.check_disallow_instantiation(test_case, tp, *args, **kwds)

斷言不能使用 argskwds 例項化型別 tp

在 3.10 版本中新增。

test.support.adjust_int_max_str_digits(max_digits)

此函式返回一個上下文管理器,該管理器將在上下文持續時間內更改全域性 sys.set_int_max_str_digits() 設定,以允許執行需要在整數和字串之間轉換時對位數進行不同限制的測試程式碼。

3.11 版本中新增。

test.support 模組定義了以下類

class test.support.SuppressCrashReport

一個上下文管理器,用於嘗試阻止在預期會使子程序崩潰的測試中彈出崩潰對話方塊。

在 Windows 上,它使用 SetErrorMode 停用 Windows 錯誤報告對話方塊。

在 UNIX 上,使用 resource.setrlimit()resource.RLIMIT_CORE 的軟限制設定為 0,以防止建立核心轉儲檔案。

在兩個平臺上,舊值都由 __exit__() 恢復。

class test.support.SaveSignals

用於儲存和恢復 Python 訊號處理程式註冊的訊號處理程式的類。

save(self)

將訊號處理程式儲存到將訊號編號對映到當前訊號處理程式的字典中。

restore(self)

save() 字典中的訊號編號設定為儲存的處理程式。

class test.support.Matcher
matches(self, d, **kwargs)

嘗試將單個字典與提供的引數匹配。

match_value(self, k, dv, v)

嘗試將單個儲存的值 (dv) 與提供的值 (v) 匹配。

test.support.socket_helper — 套接字測試的實用工具

test.support.socket_helper 模組為套接字測試提供支援。

3.9 版本中新增。

test.support.socket_helper.IPV6_ENABLED

如果在此主機上啟用 IPv6,則設定為 True,否則設定為 False

test.support.socket_helper.find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM)

返回一個適合繫結的未使用的埠。這是透過建立一個具有與 sock 引數相同的族和型別的臨時套接字(預設為 AF_INETSOCK_STREAM),並將其繫結到指定的主機地址(預設為 0.0.0.0),埠設定為 0,從而從作業系統獲取未使用的臨時埠來實現的。然後關閉並刪除臨時套接字,並返回臨時埠。

對於任何需要在測試期間將伺服器套接字繫結到特定埠的測試,應使用此方法或 bind_port()。使用哪一個取決於呼叫程式碼是建立 Python 套接字,還是需要在建構函式中提供未使用的埠或傳遞給外部程式(即 openssl 的 s_server 模式的 -accept 引數)。儘可能優先使用 bind_port() 而不是 find_unused_port()。不鼓勵使用硬編碼埠,因為它會使測試的多個例項無法同時執行,這對構建機器人來說是一個問題。

test.support.socket_helper.bind_port(sock, host=HOST)

將套接字繫結到一個空閒埠並返回埠號。依賴於臨時埠以確保我們使用的是未繫結的埠。這很重要,因為許多測試可能會同時執行,尤其是在構建機器人環境中。如果 sock.familyAF_INETsock.typeSOCK_STREAM,並且套接字上設定了 SO_REUSEADDRSO_REUSEPORT,此方法會引發異常。測試絕不應為 TCP/IP 套接字設定這些套接字選項。設定這些選項的唯一情況是透過多個 UDP 套接字測試多播。

此外,如果 SO_EXCLUSIVEADDRUSE 套接字選項可用(即在 Windows 上),它將被設定在套接字上。這將阻止其他人在測試期間繫結到我們的主機/埠。

test.support.socket_helper.bind_unix_socket(sock, addr)

繫結 Unix 套接字,如果引發 PermissionError,則引發 unittest.SkipTest

@test.support.socket_helper.skip_unless_bind_unix_socket

一個裝飾器,用於執行需要 Unix 套接字 bind() 功能的測試。

test.support.socket_helper.transient_internet(resource_name, *, timeout=30.0, errnos=())

一個上下文管理器,當網際網路連線的各種問題表現為異常時,會引發 ResourceDenied

test.support.script_helper — Python 執行測試的實用工具

test.support.script_helper 模組為 Python 的指令碼執行測試提供支援。

test.support.script_helper.interpreter_requires_environment()

如果 sys.executable interpreter 需要環境變數才能完全執行,則返回 True

此函式旨在與 @unittest.skipIf() 一起使用,以註釋需要使用 assert_python*() 函式來啟動隔離模式 (-I) 或無環境模式 (-E) 子直譯器程序的測試。

正常的構建和測試不會遇到這種情況,但在嘗試從沒有 Python 當前查詢邏輯的明顯主目錄的直譯器執行標準庫測試套件時可能會發生這種情況。

設定 PYTHONHOME 是使大多數測試套件在這種情況下執行的一種方法。 PYTHONPATHPYTHONUSERSITE 是其他可能影響直譯器是否可以啟動的常見環境變數。

test.support.script_helper.run_python_until_end(*args, **env_vars)

根據 *env_vars* 設定環境,以便在子程序中執行直譯器。這些值可以包括 __isolated__cleanenv__cwdTERM

在 3.9 版本中更改: 該函式不再從 *stderr* 中去除空格。

test.support.script_helper.assert_python_ok(*args, **env_vars)

斷言使用 *args* 和可選環境變數 *env_vars* 執行直譯器成功 (rc == 0) 並返回一個 (return code, stdout, stderr) 元組。

如果設定了僅限關鍵字的引數 *__cleanenv*,則 *env_vars* 將用作新的環境。

Python 在隔離模式下啟動(命令列選項 -I),除非將僅限關鍵字的引數 *__isolated* 設定為 False

在 3.9 版本中更改: 該函式不再從 *stderr* 中去除空格。

test.support.script_helper.assert_python_failure(*args, **env_vars)

斷言使用 *args* 和可選環境變數 *env_vars* 執行直譯器失敗 (rc != 0) 並返回一個 (return code, stdout, stderr) 元組。

有關更多選項,請參見 assert_python_ok()

在 3.9 版本中更改: 該函式不再從 *stderr* 中去除空格。

test.support.script_helper.spawn_python(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw)

使用給定的引數執行 Python 子程序。

kw 是傳遞給 subprocess.Popen() 的額外關鍵字引數。返回一個 subprocess.Popen 物件。

test.support.script_helper.kill_python(p)

執行給定的 subprocess.Popen 程序直到完成,並返回 stdout。

test.support.script_helper.make_script(script_dir, script_basename, source, omit_suffix=False)

在路徑 *script_dir* 和 *script_basename* 中建立包含 *source* 的指令碼。如果 *omit_suffix* 是 False,則將 .py 附加到名稱。返回完整的指令碼路徑。

test.support.script_helper.make_zip_script(zip_dir, zip_basename, script_name, name_in_zip=None)

zip_dirzip_basename 建立一個副檔名為 zip 的 zip 檔案,其中包含 script_name 中的檔案。name_in_zip 是壓縮包中的名稱。返回一個包含 (完整路徑, 壓縮包中名稱的完整路徑) 的元組。

test.support.script_helper.make_pkg(pkg_dir, init_source='')

建立一個名為 pkg_dir 的目錄,其中包含一個 __init__ 檔案,其內容為 init_source

test.support.script_helper.make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, source, depth=1, compiled=False)

建立一個 zip 包目錄,其路徑為 zip_dirzip_basename,其中包含一個空的 __init__ 檔案和一個包含 sourcescript_basename 檔案。如果 compiledTrue,則會將原始檔編譯並新增到 zip 包中。返回一個包含完整 zip 路徑和 zip 檔案壓縮包名稱的元組。

test.support.bytecode_helper — 用於測試正確位元組碼生成的支援工具

test.support.bytecode_helper 模組提供了用於測試和檢查位元組碼生成的支援。

3.9 版本中新增。

該模組定義了以下類

class test.support.bytecode_helper.BytecodeTestCase(unittest.TestCase)

此類具有用於檢查位元組碼的自定義斷言方法。

BytecodeTestCase.get_disassembly_as_string(co)

返回 co 的反彙編字串。

BytecodeTestCase.assertInBytecode(x, opname, argval=_UNSPECIFIED)

如果找到 opname,則返回指令,否則丟擲 AssertionError

BytecodeTestCase.assertNotInBytecode(x, opname, argval=_UNSPECIFIED)

如果找到 opname,則丟擲 AssertionError

test.support.threading_helper — 用於執行緒測試的實用工具

test.support.threading_helper 模組提供了對執行緒測試的支援。

在 3.10 版本中新增。

test.support.threading_helper.join_thread(thread, timeout=None)

timeout 時間內等待 thread 執行緒結束。如果執行緒在 timeout 秒後仍然存活,則丟擲 AssertionError

@test.support.threading_helper.reap_threads

裝飾器,用於確保即使測試失敗,執行緒也會被清理。

test.support.threading_helper.start_threads(threads, unlock=None)

上下文管理器,用於啟動 threads(一個執行緒序列)。unlock 是一個函式,線上程啟動後被呼叫,即使引發了異常也會被呼叫;一個例子是 threading.Event.set()start_threads 將嘗試在退出時等待已啟動的執行緒結束。

test.support.threading_helper.threading_cleanup(*original_values)

清理 original_values 中未指定的執行緒。旨在如果測試在後臺留下正在執行的執行緒,則發出警告。

test.support.threading_helper.threading_setup()

返回當前執行緒計數和懸掛執行緒的副本。

test.support.threading_helper.wait_threads_exit(timeout=None)

上下文管理器,用於等待 with 語句中建立的所有執行緒退出。

test.support.threading_helper.catch_threading_exception()

上下文管理器,使用 threading.excepthook() 捕獲 threading.Thread 異常。

捕獲到異常時設定的屬性

  • exc_type

  • exc_value

  • exc_traceback

  • thread

請參閱 threading.excepthook() 文件。

這些屬性在上下文管理器退出時被刪除。

用法

with threading_helper.catch_threading_exception() as cm:
    # code spawning a thread which raises an exception
    ...

    # check the thread exception, use cm attributes:
    # exc_type, exc_value, exc_traceback, thread
    ...

# exc_type, exc_value, exc_traceback, thread attributes of cm no longer
# exists at this point
# (to avoid reference cycles)

在版本 3.8 中新增。

test.support.os_helper — 用於作業系統測試的實用工具

test.support.os_helper 模組為 os 測試提供支援。

在 3.10 版本中新增。

test.support.os_helper.FS_NONASCII

一個可以透過 os.fsencode() 編碼的非 ASCII 字元。

test.support.os_helper.SAVEDCWD

設定為 os.getcwd()

test.support.os_helper.TESTFN

設定為一個可以安全用作臨時檔名稱的名稱。任何建立的臨時檔案都應該被關閉和取消連結(移除)。

test.support.os_helper.TESTFN_NONASCII

設定為一個包含 FS_NONASCII 字元的檔名(如果存在)。這保證瞭如果檔名存在,則可以使用預設的檔案系統編碼進行編碼和解碼。這允許在無法工作的平臺上輕鬆跳過需要非 ASCII 檔名的測試。

test.support.os_helper.TESTFN_UNENCODABLE

設定為一個檔名(str 型別),該檔名不應能夠以嚴格模式透過檔案系統編碼進行編碼。如果無法生成此類檔名,則可能為 None

test.support.os_helper.TESTFN_UNDECODABLE

設定為一個檔名(bytes 型別),該檔名不應能夠以嚴格模式透過檔案系統編碼進行解碼。如果無法生成此類檔名,則可能為 None

test.support.os_helper.TESTFN_UNICODE

設定為臨時檔案的非 ASCII 名稱。

class test.support.os_helper.EnvironmentVarGuard

用於臨時設定或取消設定環境變數的類。例項可以用作上下文管理器,並且具有完整的字典介面,用於查詢/修改底層的 os.environ。退出上下文管理器後,所有透過此例項對環境變數所做的更改都將被回滾。

在 3.1 版本中更改: 添加了字典介面。

class test.support.os_helper.FakePath(path)

簡單的 路徑類物件。它實現了 __fspath__() 方法,該方法僅返回 path 引數。如果 path 是一個異常,它將在 __fspath__() 中引發。

EnvironmentVarGuard.set(envvar, value)

臨時將環境變數 envvar 設定為 value 的值。

EnvironmentVarGuard.unset(envvar)

臨時取消設定環境變數 envvar

如果作業系統支援符號連結,則返回 True,否則返回 False

test.support.os_helper.can_xattr()

如果作業系統支援 xattr,則返回 True,否則返回 False

test.support.os_helper.change_cwd(path, quiet=False)

一個上下文管理器,將當前工作目錄臨時更改為 path 並返回目錄。

如果 quietFalse,則上下文管理器會在出錯時引發異常。否則,它僅發出警告並保持當前工作目錄不變。

test.support.os_helper.create_empty_file(filename)

建立一個名為 filename 的空檔案。如果它已經存在,則將其截斷。

test.support.os_helper.fd_count()

計算開啟的檔案描述符的數量。

test.support.os_helper.fs_is_case_insensitive(directory)

如果 directory 的檔案系統不區分大小寫,則返回 True

test.support.os_helper.make_bad_fd()

透過開啟和關閉臨時檔案並返回其描述符來建立無效的檔案描述符。

test.support.os_helper.rmdir(filename)

filename 上呼叫 os.rmdir()。在 Windows 平臺上,這會包裝一個等待迴圈,該迴圈會檢查檔案是否存在,這是由於防病毒程式可能會保持檔案開啟並阻止刪除。

test.support.os_helper.rmtree(path)

path 上呼叫 shutil.rmtree() 或呼叫 os.lstat()os.rmdir() 來刪除路徑及其內容。與 rmdir() 一樣,在 Windows 平臺上,這會包裝一個等待迴圈,該迴圈會檢查檔案是否存在。

一個用於執行需要符號連結支援的測試的裝飾器。

@test.support.os_helper.skip_unless_xattr

一個用於執行需要 xattr 支援的測試的裝飾器。

test.support.os_helper.temp_cwd(name='tempcwd', quiet=False)

一個上下文管理器,它臨時建立一個新目錄並更改當前工作目錄 (CWD)。

此上下文管理器在臨時更改當前工作目錄之前,在當前目錄中建立一個名為 name 的臨時目錄。如果 nameNone,則使用 tempfile.mkdtemp() 建立臨時目錄。

如果 quietFalse 且無法建立或更改 CWD,則會引發錯誤。否則,只會引發警告並使用原始 CWD。

test.support.os_helper.temp_dir(path=None, quiet=False)

一個上下文管理器,它在 path 處建立一個臨時目錄並生成該目錄。

如果 pathNone,則使用 tempfile.mkdtemp() 建立臨時目錄。如果 quietFalse,則上下文管理器會在出錯時引發異常。否則,如果指定了 path 且無法建立,則只會發出警告。

test.support.os_helper.temp_umask(umask)

一個上下文管理器,它臨時設定程序 umask。

filename 上呼叫 os.unlink()。與 rmdir() 一樣,在 Windows 平臺上,它被包裝在一個等待迴圈中,該迴圈檢查檔案是否存在。

test.support.import_helper — 用於匯入測試的實用程式

test.support.import_helper 模組為匯入測試提供支援。

在 3.10 版本中新增。

test.support.import_helper.forget(module_name)

sys.modules 中刪除名為 module_name 的模組,並刪除該模組的任何位元組編譯檔案。

test.support.import_helper.import_fresh_module(name, fresh=(), blocked=(), deprecated=False)

此函式透過在執行匯入之前從 sys.modules 中刪除指定的模組,來匯入並返回指定 Python 模組的全新副本。 請注意,與 reload() 不同,原始模組不受此操作的影響。

fresh 是一個額外的模組名稱的可迭代物件,在執行匯入之前也會從 sys.modules 快取中刪除。

blocked 是模組名稱的可迭代物件,在匯入期間,這些模組名稱在模組快取中被替換為 None,以確保嘗試匯入它們會引發 ImportError

在開始匯入之前,會儲存指定模組和 freshblocked 引數中指定的任何模組,然後在全新匯入完成後,將其重新插入到 sys.modules 中。

如果 deprecatedTrue,則在此匯入期間會抑制模組和包的棄用訊息。

如果無法匯入指定的模組,則此函式將引發 ImportError

用法示例

# Get copies of the warnings module for testing without affecting the
# version being used by the rest of the test suite. One copy uses the
# C implementation, the other is forced to use the pure Python fallback
# implementation
py_warnings = import_fresh_module('warnings', blocked=['_warnings'])
c_warnings = import_fresh_module('warnings', fresh=['_warnings'])

在版本 3.1 中新增。

test.support.import_helper.import_module(name, deprecated=False, *, required_on=())

此函式會匯入並返回指定的模組。 與正常的匯入不同,如果無法匯入模組,此函式會引發 unittest.SkipTest

如果 deprecatedTrue,則在此匯入期間會抑制模組和包的棄用訊息。 如果模組在某個平臺上是必需的,但在其他平臺上是可選的,請將 required_on 設定為平臺字首的可迭代物件,這些字首將與 sys.platform 進行比較。

在版本 3.1 中新增。

test.support.import_helper.modules_setup()

返回 sys.modules 的副本。

test.support.import_helper.modules_cleanup(oldmodules)

刪除除 oldmodulesencodings 之外的模組,以保留內部快取。

test.support.import_helper.unload(name)

sys.modules 中刪除 name

test.support.import_helper.make_legacy_pyc(source)

PEP 3147/PEP 488 pyc 檔案移動到其舊的 pyc 位置,並返回舊的 pyc 檔案的檔案系統路徑。 source 值是原始檔的檔案系統路徑。 它不需要存在,但是 PEP 3147/488 pyc 檔案必須存在。

class test.support.import_helper.CleanImport(*module_names)

一個上下文管理器,用於強制匯入返回新的模組引用。 這對於測試模組級行為非常有用,例如在匯入時發出 DeprecationWarning。 用法示例

with CleanImport('foo'):
    importlib.import_module('foo')  # New reference.
class test.support.import_helper.DirsOnSysPath(*paths)

一個上下文管理器,用於臨時將目錄新增到 sys.path

這將複製 sys.path,追加任何作為位置引數給定的目錄,然後在上下文結束時將 sys.path 恢復為複製的設定。

請注意,上下文管理器主體中所有sys.path 的修改,包括物件的替換,都將在程式碼塊結束時恢復。

test.support.warnings_helper — 警告測試的實用工具

test.support.warnings_helper 模組為警告測試提供支援。

在 3.10 版本中新增。

test.support.warnings_helper.ignore_warnings(*, category)

抑制屬於 category 例項的警告,category 必須是 Warning 或其子類。大致等同於呼叫 warnings.catch_warnings() 並設定 warnings.simplefilter('ignore', category=category)。例如:

@warning_helper.ignore_warnings(category=DeprecationWarning)
def test_suppress_warning():
    # do something

在版本 3.8 中新增。

test.support.warnings_helper.check_no_resource_warning(testcase)

檢查沒有引發 ResourceWarning 的上下文管理器。您必須在上下文管理器結束之前刪除可能發出 ResourceWarning 的物件。

test.support.warnings_helper.check_syntax_warning(testcase, statement, errtext='', *, lineno=1, offset=None)

透過嘗試編譯 statement 來測試 statement 中的語法警告。同時測試 SyntaxWarning 是否只發出一次,以及在轉化為錯誤時是否會被轉換為 SyntaxErrortestcase 是測試的 unittest 例項。errtext 是應該匹配發出的 SyntaxWarning 和引發的 SyntaxError 的字串表示形式的正則表示式。如果 lineno 不是 None,則與警告和異常的行進行比較。如果 offset 不是 None,則與異常的偏移量進行比較。

在版本 3.8 中新增。

test.support.warnings_helper.check_warnings(*filters, quiet=True)

一個方便的 warnings.catch_warnings() 包裝器,可以更輕鬆地測試是否正確引發了警告。它大致等同於呼叫 warnings.catch_warnings(record=True) 並將 warnings.simplefilter() 設定為 always,並可以選擇自動驗證記錄的結果。

check_warnings 接受形如 ("message regexp", WarningCategory) 的 2 元組作為位置引數。如果提供了一個或多個 filters,或者可選關鍵字引數 quietFalse,它會檢查以確保警告符合預期:每個指定的過濾器必須至少匹配封閉程式碼引發的一個警告,否則測試將失敗;如果引發了任何不匹配任何指定過濾器的警告,則測試將失敗。要停用第一個檢查,請將 quiet 設定為 True

如果沒有指定引數,則預設為

check_warnings(("", Warning), quiet=True)

在這種情況下,所有警告都會被捕獲,且不會引發錯誤。

在進入上下文管理器時,會返回一個 WarningRecorder 例項。可以透過記錄器物件的 warnings 屬性訪問來自 catch_warnings() 的底層警告列表。為了方便起見,也可以透過記錄器物件直接訪問表示最近警告的物件的屬性(請參見下面的示例)。如果沒有引發警告,則任何在表示警告的物件上可能存在的屬性都將返回 None

記錄器物件還有一個 reset() 方法,該方法會清除警告列表。

上下文管理器設計為這樣使用

with check_warnings(("assertion is always true", SyntaxWarning),
                    ("", UserWarning)):
    exec('assert(False, "Hey!")')
    warnings.warn(UserWarning("Hide me!"))

在這種情況下,如果未引發任一警告,或者引發了其他一些警告,check_warnings() 將會引發錯誤。

當測試需要更深入地檢視警告時,而不僅僅是檢查是否發生警告時,可以使用如下程式碼

with check_warnings(quiet=True) as w:
    warnings.warn("foo")
    assert str(w.args[0]) == "foo"
    warnings.warn("bar")
    assert str(w.args[0]) == "bar"
    assert str(w.warnings[0].args[0]) == "foo"
    assert str(w.warnings[1].args[0]) == "bar"
    w.reset()
    assert len(w.warnings) == 0

這裡會捕獲所有警告,並且測試程式碼會直接測試捕獲的警告。

在 3.2 版本中更改: 新增可選引數 filtersquiet

class test.support.warnings_helper.WarningsRecorder

用於記錄單元測試警告的類。有關更多詳細資訊,請參見上面 check_warnings() 的文件。