test
— Python 的迴歸測試包¶
備註
test
包僅供 Python 內部使用。它的文件是為了核心 Python 開發人員的利益。不建議在 Python 標準庫之外使用此包,因為此處提到的程式碼可能會在 Python 版本之間更改或刪除,恕不另行通知。
test
包包含 Python 的所有迴歸測試以及模組 test.support
和 test.regrtest
。test.support
用於增強您的測試,而 test.regrtest
驅動測試套件。
test
包中所有名稱以 test_
開頭的模組都是特定模組或功能的測試套件。所有新測試都應使用 unittest
或 doctest
模組編寫。一些較舊的測試是使用“傳統”測試風格編寫的,該風格比較列印到 sys.stdout
的輸出;這種測試風格被認為是已棄用的。
為 test
包編寫單元測試¶
建議使用 unittest
模組的測試遵循一些指導原則。其中之一是測試模組的名稱以 test_
開頭,並以被測試模組的名稱結尾。測試模組中的測試方法應以 test_
開頭,並以描述該方法正在測試什麼的內容結尾。這是必要的,以便測試驅動程式將這些方法識別為測試方法。此外,不應包含方法的文件字串。應使用註釋(例如 # Tests function returns only True or 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()
(如果存在)或在 test_main
不存在時透過 unittest.TestLoader.loadTestsFromModule 載入測試來完成此操作。要執行的測試名稱也可以傳遞給指令碼。指定單個迴歸測試(python -m test test_spam)將最小化輸出,並且只打印測試是透過還是失敗。
直接執行 test
允許設定測試可用的資源。您可以透過使用 -u
命令列選項來做到這一點。將 all
指定為 -u
選項的值將啟用所有可能的資源:python -m test -uall。如果需要除一個資源之外的所有資源(更常見的情況),可以在 all
之後列出逗號分隔的不需要的資源列表。命令 python -m test -uall,-audio,-largefile 將執行 test
,其中包含除 audio
和 largefile
資源之外的所有資源。有關所有資源和更多命令列選項的列表,請執行 python -m test -h。
執行迴歸測試的其他一些方法取決於測試正在執行的平臺。在 Unix 上,您可以在構建 Python 的頂層目錄中執行 make test。在 Windows 上,從 PCbuild
目錄執行 rt.bat 將執行所有迴歸測試。
3.14 版本新增: 輸出預設著色,並且可以使用 環境變數控制。
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
。當需要有關正在執行的測試的更詳細資訊時,應檢查此項。verbose 由test.regrtest
設定。
- test.support.is_jython¶
如果正在執行的直譯器是 Jython,則為
True
。
- test.support.is_android¶
如果
sys.platform
是android
,則為True
。
- test.support.is_emscripten¶
如果
sys.platform
是emscripten
,則為True
。
- test.support.is_wasi¶
如果
sys.platform
是wasi
,則為True
。
- test.support.is_apple_mobile¶
如果
sys.platform
是ios
、tvos
或watchos
,則為True
。
- test.support.is_apple¶
如果
sys.platform
是darwin
或is_apple_mobile
是True
,則為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_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 分鐘。
- test.support.PGO¶
當測試對 PGO 無用時,可以跳過它們。
- test.support.PIPE_MAX_SIZE¶
一個常量,可能大於底層作業系統管道緩衝區大小,以使寫入阻塞。
- 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.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
。如果引發,msg 是ResourceDenied
的引數。如果由__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 的特定於實現的測試,或僅在由引數保護的實現上執行它們。此函式根據主機平臺返回
True
或False
。使用示例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_memuse
和real_max_memuse
的值。
- test.support.record_original_stdout(stdout)¶
儲存 stdout 的值。它旨在儲存 regrtest 開始時的 stdout。
- test.support.get_original_stdout()¶
返回由
record_original_stdout()
設定的原始 stdout,如果未設定,則返回sys.stdout
。
- test.support.args_from_interpreter_flags()¶
返回一個命令列引數列表,該列表複製了
sys.flags
和sys.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,並在塊結束時恢復舊值。如果obj
上不存在item
,它將被建立,並在塊結束時刪除。舊值(如果不存在則為
None
)將被分配給“as”子句的目標(如果存在)。
- test.support.flush_std_streams()¶
首先在
sys.stdout
上呼叫flush()
方法,然後在sys.stderr
上呼叫。它可以用於確保在寫入 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.calcvobjsize(fmt)¶
返回其結構成員由 fmt 定義的
PyVarObject
的大小。返回的值包括 Python 物件頭和對齊的大小。
- test.support.checksizeof(test, o, size)¶
對於測試用例 test,斷言 o 的
sys.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_IEEE_754¶
用於在非 IEEE 754 平臺上跳過測試的裝飾器。
- @test.support.requires_resource(resource)¶
如果 resource 不可用,則跳過測試的裝飾器。
- @test.support.requires_docstrings¶
僅當
HAVE_DOCSTRINGS
時才執行測試的裝飾器。
- @test.support.cpython_only¶
僅適用於 CPython 的測試的裝飾器。
- @test.support.impl_detail(msg=None, **guards)¶
用於在 guards 上呼叫
check_impl_detail()
的裝飾器。如果返回False
,則使用 msg 作為跳過測試的原因。
- @test.support.thread_unsafe(reason=None)¶
用於將測試標記為執行緒不安全的裝飾器。即使使用
--parallel-threads
呼叫,此測試也始終在一個執行緒中執行。
- @test.support.no_tracing¶
在測試期間臨時關閉跟蹤的裝飾器。
- @test.support.refcount_test¶
用於涉及引用計數的測試的裝飾器。如果測試不是由 CPython 執行的,則裝飾器不會執行測試。在測試期間,任何跟蹤函式都將取消設定,以防止由跟蹤函式引起的意外引用計數。
- @test.support.bigmemtest(size, memuse, dry_run=True)¶
大記憶體測試的裝飾器。
size 是測試的請求大小(以任意的、測試解釋的單位表示)。memuse 是測試中每單位的位元組數,或其良好估計。例如,一個需要兩個 4 GiB 位元組緩衝區的測試可以用
@bigmemtest(size=_4G, memuse=2)
進行裝飾。size 引數通常作為額外引數傳遞給被裝飾的測試方法。如果 dry_run 為
True
,則傳遞給測試方法的值可能小於請求值。如果 dry_run 為False
,則表示在未指定-M
時,測試不支援空執行。
- @test.support.bigaddrspacetest¶
用於填充地址空間的測試的裝飾器。
- test.support.linked_to_musl()¶
如果無法證明直譯器是使用
musl
編譯的,則返回False
,否則返回一個版本三元組,如果版本未知則返回(0, 0, 0)
,如果版本已知則返回實際版本。此函式旨在用於skip
裝飾器。emscripten
和wasi
被假定為使用musl
編譯;否則會檢查platform.libc_ver
。
- 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 是包的根目錄;loader、standard_tests 和 pattern 是load_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 新增清理過程,以恢復 attr_name 的 object_to_patch。attr_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=())¶
斷言 module 的
__all__
變數包含所有公共名稱。模組的公共名稱(其 API)是根據它們是否符合公共名稱約定並在 module 中定義而自動檢測的。
name_of_module 引數可以指定(作為字串或其元組)API 可能在哪些模組中定義才能被檢測為公共 API。一個例子是當 module 從其他模組(可能是 C 後端,如
csv
及其_csv
)匯入其部分公共 API 時。extra 引數可以是一組否則不會自動檢測為“公共”的名稱,例如沒有 proper
__module__
屬性的物件。如果提供,它將新增到自動檢測到的名稱中。not_exported 引數可以是一組名稱,即使它們的名稱表示它們是公共 API 的一部分,也不應將其視為公共 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)¶
斷言型別 tp 不能使用 args 和 kwds 例項化。
在 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__()
恢復。
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_INET
,SOCK_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)¶
將套接字繫結到空閒埠並返回埠號。依賴臨時埠以確保我們使用未繫結埠。這很重要,因為許多測試可能同時執行,尤其是在 buildbot 環境中。如果
sock.family
是AF_INET
且sock.type
是SOCK_STREAM
,並且套接字上設定了SO_REUSEADDR
或SO_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
是在這種情況下使大多數測試套件執行的一種方法。PYTHONPATH
或PYTHONUSERSITE
是其他可能影響直譯器是否可以啟動的常見環境變數。
- test.support.script_helper.run_python_until_end(*args, **env_vars)¶
根據 env_vars 設定環境,以便在子程序中執行直譯器。這些值可以包括
__isolated
、__cleanenv
、__cwd
和TERM
。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
程序直到完成並返回標準輸出。
- 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_dir 和 zip_basename 建立副檔名為
zip
的 zip 檔案,其中包含 script_name 中的檔案。name_in_zip 是存檔名稱。返回一個包含(full path, full path of archive name)
的元組。
- 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_dir 和 zip_basename 的 zip 包目錄,其中包含一個空的
__init__
檔案和一個包含 source 的檔案 script_basename。如果 compiled 為True
,則兩個原始檔都將被編譯並新增到 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,則返回 instr,否則引發
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.threading_helper.run_concurrently(worker_func, nthreads, args=(), kwargs={})¶
在多個執行緒中併發執行工作函式。如果任何執行緒引發異常,則在所有執行緒完成後重新引發該異常。
test.support.os_helper
— os 測試的實用工具¶
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¶
設定為一個檔名(字串型別),在嚴格模式下檔案系統編碼不應該能夠編碼。如果無法生成這樣的檔名,則可能為
None
。
- test.support.os_helper.TESTFN_UNDECODABLE¶
設定為一個檔名(位元組型別),在嚴格模式下檔案系統編碼不應該能夠解碼。如果無法生成這樣的檔名,則可能為
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, *others)¶
暫時取消設定一個或多個環境變數。
3.14 版本中已更改: 可以取消設定多個環境變數。
- test.support.os_helper.can_symlink()¶
如果作業系統支援符號連結,則返回
True
,否則返回False
。
- test.support.os_helper.can_xattr()¶
如果作業系統支援 xattr,則返回
True
,否則返回False
。
- test.support.os_helper.change_cwd(path, quiet=False)¶
一個上下文管理器,它臨時將當前工作目錄更改為 path 並生成該目錄。
如果 quiet 為
False
,則上下文管理器會在出錯時引發異常。否則,它只發出警告並保持當前工作目錄不變。
- 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_symlink¶
一個裝飾器,用於執行需要符號連結支援的測試。
- @test.support.os_helper.skip_unless_xattr¶
一個裝飾器,用於執行需要 xattr 支援的測試。
- test.support.os_helper.temp_cwd(name='tempcwd', quiet=False)¶
一個上下文管理器,它臨時建立一個新目錄並更改當前工作目錄 (CWD)。
此上下文管理器在臨時更改當前工作目錄之前,會在當前目錄中建立一個名為 name 的臨時目錄。如果 name 為
None
,則使用tempfile.mkdtemp()
建立臨時目錄。如果 quiet 為
False
,並且無法建立或更改 CWD,則會引發錯誤。否則,只發出警告並使用原始 CWD。
- test.support.os_helper.temp_dir(path=None, quiet=False)¶
一個上下文管理器,它在 path 建立一個臨時目錄並生成該目錄。
如果 path 為
None
,則使用tempfile.mkdtemp()
建立臨時目錄。如果 quiet 為False
,則上下文管理器在出錯時引發異常。否則,如果指定了 path 且無法建立,則只發出警告。
- test.support.os_helper.temp_umask(umask)¶
一個上下文管理器,它臨時設定程序 umask。
- test.support.os_helper.unlink(filename)¶
在 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
。在開始匯入之前,指定模組以及 fresh 和 blocked 引數中指定的任何模組都會被儲存,然後在新的匯入完成後重新插入到
sys.modules
中。如果 deprecated 為
True
,則在此匯入期間會抑制模組和包棄用訊息。如果無法匯入指定模組,此函式將引發
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
。如果 deprecated 為
True
,則在匯入期間會抑制模組和包棄用訊息。如果某個模組在某個平臺上是必需的,但在其他平臺上是可選的,請將 required_on 設定為平臺字首的可迭代物件,該物件將與sys.platform
進行比較。在 3.1 版本加入。
- test.support.import_helper.modules_setup()¶
返回
sys.modules
的副本。
- test.support.import_helper.modules_cleanup(oldmodules)¶
刪除模組,除了 oldmodules 和
encodings
,以保留內部快取。
- 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.
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
只發出一次,並且當它被轉換為錯誤時,它將被轉換為SyntaxError
。testcase 是用於測試的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,或者可選的關鍵字引數 quiet 為False
,它會檢查以確保警告符合預期:每個指定的過濾器必須至少匹配封閉程式碼引發的一個警告,否則測試失敗;如果引發的任何警告不匹配任何指定的過濾器,測試也會失敗。要停用第一個檢查,請將 quiet 設定為True
。如果沒有指定引數,則預設為
check_warnings(("", Warning), quiet=True)
在這種情況下,所有警告都會被捕獲,並且不會引發任何錯誤。
進入上下文管理器時,會返回一個
WarningRecorder
例項。catch_warnings()
中的底層警告列表可透過記錄器物件的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 版本中已更改: 新增可選引數 filters 和 quiet。
- class test.support.warnings_helper.WarningsRecorder¶
用於記錄單元測試警告的類。更多詳情請參見上文
check_warnings()
的文件。