棄用和移除¶
此頁面列出了目前已棄用或在過去主要版本中已移除的所有 pytest 功能。目的是讓使用者清楚了解特定功能被移除的原因,以及應該改用哪些替代方案。
已棄用的功能¶
以下是所有被認為已棄用的 pytest 功能的完整列表。使用這些功能將會發出 PytestWarning
或子類別,可以使用 標準警告過濾器 進行過濾。
pytest.importorskip
關於 ImportError
的預設行為¶
自版本 8.2 起已棄用。
傳統上,pytest.importorskip()
會捕獲 ImportError
,最初的目的是在未安裝相依模組時跳過測試,例如使用不同相依性進行測試。
然而,有些套件可能已安裝在系統中,但由於其他問題(例如編譯錯誤或安裝損壞)而無法導入。在這些情況下,pytest.importorskip()
仍然會靜默地跳過測試,但通常使用者更希望看到意外錯誤,以便可以修復根本問題。
在 8.2
版本中,新增了 exc_type
參數,讓使用者能夠傳遞 ModuleNotFoundError
,以便僅在模組確實找不到時才跳過測試,而不是因為其他錯誤。
預設情況下僅捕獲 ModuleNotFoundError
(並讓其他錯誤傳播)將是最佳解決方案,但為了向後兼容性,pytest 將保留現有行為,但在以下情況發出警告:
捕獲的異常類型為
ImportError
,且使用者未明確傳遞
exc_type
。
如果導入嘗試引發 ModuleNotFoundError
(通常情況),則模組將被跳過,且不會發出警告。
這樣一來,常見情況將保持相同的工作方式,而意外錯誤現在將發出警告,使用者可以通過明確傳遞 exc_type=ImportError
來抑制警告。
在 9.0
版本中,警告將轉變為錯誤,而在 9.1
版本中,pytest.importorskip()
預設情況下將僅捕獲 ModuleNotFoundError
,並且不再發出警告 – 但使用者仍然可以通過將 ImportError
傳遞給 exc_type
來捕獲它。
Node 建構函式的 fspath
參數已替換為 pathlib.Path
¶
自版本 7.0 起已棄用。
為了支持從 py.path.local
到 pathlib
的過渡,Node
建構函式(例如 pytest.Function.from_parent()
和 pytest.Class.from_parent()
)的 fspath
參數現在已被棄用。
建構節點的插件應傳遞類型為 pathlib.Path
的 path
參數,而不是 fspath
參數。
實作自訂項目和收集器的插件,建議將 fspath
參數 (py.path.local
) 替換為 path
參數 (pathlib.Path
),並盡可能放棄任何其他 py
庫的使用。
如果可能,具有自訂項目的插件應使用協作建構函式,以避免硬編碼它們僅傳遞給超類的參數。
注意
Node
參數和屬性的名稱(新屬性為 path
)與 hook 的情況相反,如下所述(舊參數為 path
)。
這是由於歷史原因造成的不幸產物,應在未來版本中解決,因為我們正在慢慢擺脫對 py 的依賴(有關更長的討論,請參閱 #9283)。
由於正在進行諸如 reportinfo()
等方法的遷移,這些方法仍預期返回 py.path.local
對象,因此節點仍然同時具有 fspath
(py.path.local
) 和 path
(pathlib.Path
) 屬性,無論在建構函式中使用哪個參數。我們預計在未來版本中棄用 fspath
屬性。
使用標記配置 hook 規範/實作¶
在 pluggy(pytest 的插件庫)成為獨立套件並具有清晰的 API 之前,pytest 僅使用 pytest.mark
來配置 hook。
pytest.hookimpl()
和 pytest.hookspec()
裝飾器已存在多年,應改為使用它們。
@pytest.mark.tryfirst
def pytest_runtest_call(): ...
# or
def pytest_runtest_call(): ...
pytest_runtest_call.tryfirst = True
應更改為
@pytest.hookimpl(tryfirst=True)
def pytest_runtest_call(): ...
已更改的 hookimpl
屬性
tryfirst
trylast
optionalhook
hookwrapper
已更改的 hookwrapper
屬性
firstresult
historic
hook 的 py.path.local
參數已替換為 pathlib.Path
¶
自版本 7.0 起已棄用。
為了支持從 py.path.local
到 pathlib
的過渡,以下 hook 現在接收額外參數
pytest_ignore_collect(collection_path: pathlib.Path)
作為path
的等效項pytest_collect_file(file_path: pathlib.Path)
作為path
的等效項pytest_pycollect_makemodule(module_path: pathlib.Path)
作為path
的等效項pytest_report_header(start_path: pathlib.Path)
作為startdir
的等效項pytest_report_collectionfinish(start_path: pathlib.Path)
作為startdir
的等效項
隨附的基於 py.path.local
的路徑已被棄用:手動調用這些 hook 的插件應僅傳遞新的 pathlib.Path
參數,使用者應更改其 hook 實作以使用新的 pathlib.Path
參數。
直接建構內部類別¶
自版本 7.0 起已棄用。
直接建構以下類別現在已被棄用
_pytest.mark.structures.Mark
_pytest.mark.structures.MarkDecorator
_pytest.mark.structures.MarkGenerator
_pytest.python.Metafunc
_pytest.runner.CallInfo
_pytest._code.ExceptionInfo
_pytest.config.argparsing.Parser
_pytest.config.argparsing.OptionGroup
_pytest.pytester.HookRecorder
這些建構函式一直被認為是私有的,但現在發出棄用警告,這可能會在 pytest 8 中變成硬錯誤。
pytest.Collector
和 pytest.Item
之間的菱形繼承¶
自版本 7.0 起已棄用。
定義一個同時為 Item
和 Collector
的自訂 pytest 節點類型(例如 File
)現在會發出警告。它從未得到合理的支援,並且會觸發難以調試的錯誤。
一些提供 linting/程式碼分析的插件一直將此作為一種 hack 使用。相反,應使用單獨的收集器節點,以收集項目。有關範例,請參閱使用非 Python 測試,以及修復繼承的範例 pr。
自訂 Node
子類的建構函式應接受 **kwargs
¶
自版本 7.0 起已棄用。
如果諸如 pytest.Item
之類的節點的自訂子類別覆寫 __init__
方法,則它們應接受 **kwargs
。因此,
class CustomItem(pytest.Item):
def __init__(self, name, parent, additional_arg):
super().__init__(name, parent)
self.additional_arg = additional_arg
應改為
class CustomItem(pytest.Item):
def __init__(self, *, additional_arg, **kwargs):
super().__init__(**kwargs)
self.additional_arg = additional_arg
以避免硬編碼 pytest 可以傳遞給超類的參數。有關完整範例,請參閱使用非 Python 測試。
對於沒有衝突的情況,不會發出棄用警告。對於有衝突的情況(例如,pytest.File
現在採用 path
而不是 fspath
,如上所述),現在會發出棄用警告。
將標記應用於 fixture 函數¶
自版本 7.4 起已棄用。
將標記應用於 fixture 函數從來沒有任何效果,但這是一個常見的使用者錯誤。
@pytest.mark.usefixtures("clean_database")
@pytest.fixture
def user() -> User: ...
使用者在此情況下預期 usefixtures
標記會產生預期的效果,即在調用 user
時使用 clean_database
fixture,但實際上它根本沒有任何效果。
現在,pytest 在遇到此問題時會發出警告,並將在未來版本中引發錯誤。
在測試函數中返回非 None 值¶
自版本 7.2 起已棄用。
如果測試函數返回除 None
以外的任何值,則現在會發出 pytest.PytestReturnNotNoneWarning
。
這可以防止初學者之間的一個常見錯誤,他們期望返回 bool
會導致測試通過或失敗,例如
@pytest.mark.parametrize(
["a", "b", "result"],
[
[1, 2, 5],
[2, 3, 8],
[5, 3, 18],
],
)
def test_foo(a, b, result):
return foo(a, b) == result
鑑於 pytest 忽略了返回值,這可能會令人驚訝,因為它永遠不會失敗。
正確的修復方法是將 return
更改為 assert
@pytest.mark.parametrize(
["a", "b", "result"],
[
[1, 2, 5],
[2, 3, 8],
[5, 3, 18],
],
)
def test_foo(a, b, result):
assert foo(a, b) == result
yield_fixture
函數/裝飾器¶
自版本 6.2 起已棄用。
pytest.yield_fixture
是 pytest.fixture()
的已棄用別名。
它已經這樣很長時間了,因此可以安全地搜索/替換。
已移除的功能和重大變更¶
正如我們的向後兼容性政策政策中所述,已棄用的功能僅在經過適當的棄用期後的主要版本中移除。
也列出了一些無法棄用的重大變更。
支援為 nose 編寫的測試¶
自版本 7.2 起已棄用。
在版本 8.0 中移除。
現在已棄用對運行為 nose 編寫的測試的支援。
nose
多年來一直處於僅維護模式,並且維護插件並非易事,因為它會蔓延到程式碼庫中(有關更多詳細信息,請參閱 #9886)。
setup/teardown¶
一件可能讓使用者感到驚訝的事情是,普通的 setup
和 teardown
方法不是 pytest 原生的,它們實際上是 nose
支援的一部分。
class Test:
def setup(self):
self.resource = make_resource()
def teardown(self):
self.resource.close()
def test_foo(self): ...
def test_bar(self): ...
原生 pytest 支援使用 setup_method
和 teardown_method
(請參閱方法和函數級別的 setup/teardown),因此上述應更改為
class Test:
def setup_method(self):
self.resource = make_resource()
def teardown_method(self):
self.resource.close()
def test_foo(self): ...
def test_bar(self): ...
這在整個程式碼庫中很容易做到,只需進行簡單的查找/替換即可。
@with_setup¶
使用 @with_setup 的程式碼,例如這樣
from nose.tools import with_setup
def setup_some_resource(): ...
def teardown_some_resource(): ...
@with_setup(setup_some_resource, teardown_some_resource)
def test_foo(): ...
也需要移植到受支援的 pytest 風格。一種方法是使用 fixture
import pytest
def setup_some_resource(): ...
def teardown_some_resource(): ...
@pytest.fixture
def some_resource():
setup_some_resource()
yield
teardown_some_resource()
def test_foo(some_resource): ...
compat_co_firstlineno
屬性¶
Nose 檢查函數對象上的此屬性,以允許覆寫函數的推斷行號。Pytest 不再遵守此屬性。
將 msg=
傳遞給 pytest.skip
、pytest.fail
或 pytest.exit
¶
自版本 7.0 起已棄用。
在版本 8.0 中移除。
現在已棄用將關鍵字參數 msg
傳遞給 pytest.skip()
、pytest.fail()
或 pytest.exit()
,應改為使用 reason
。此變更是為了使這些函數與已經接受 reason
參數的 @pytest.mark.skip
和 @pytest.mark.xfail
標記保持一致。
def test_fail_example():
# old
pytest.fail(msg="foo")
# new
pytest.fail(reason="bar")
def test_skip_example():
# old
pytest.skip(msg="foo")
# new
pytest.skip(reason="bar")
def test_exit_example():
# old
pytest.exit(msg="foo")
# new
pytest.exit(reason="bar")
pytest.Instance
收集器¶
在版本 7.0 中移除。
pytest.Instance
收集器類型已移除。
以前,Python 測試方法被收集為 Class
-> Instance
-> Function
。現在,Class
直接收集測試方法。
大多數引用 Instance
的插件這樣做是為了忽略或跳過它,使用諸如 if isinstance(node, Instance): return
之類的檢查。此類插件應僅在 pytest>=7 上移除對 Instance
的考慮。但是,為了保持此類用途的正常運作,已在 pytest.Instance
和 _pytest.python.Instance
中實例化一個虛擬類型,並且導入它會發出棄用警告。這在 pytest 8 中已移除。
使用 pytest.warns(None)
¶
自版本 7.0 起已棄用。
在版本 8.0 中移除。
pytest.warns(None)
現在已被棄用,因為它經常被誤用。其正確用法是檢查程式碼是否發出至少一個任何類型的警告 - 例如 pytest.warns()
或 pytest.warns(Warning)
。
有關範例,請參閱測試中警告的其他用例。
Parser.addoption
中的向後兼容性¶
自版本 2.4 起已棄用。
在版本 8.0 中移除。
Parser.addoption
的幾個行為現在已在 pytest 8 中移除(自 pytest 2.4.0 起已棄用)
parser.addoption(..., help=".. %default ..")
- 請改用%(default)s
。parser.addoption(..., type="int/string/float/complex")
- 請改用type=int
等。
--strict
命令列選項¶
自版本 6.2 起已棄用。
在版本 8.0 中移除。
--strict
命令列選項已被棄用,而改用 --strict-markers
,後者能更好地傳達該選項的作用。
我們計劃在未來可能會重新引入 --strict
,並使其成為所有與嚴格性相關的選項(目前為 --strict-markers
和 --strict-config
,未來可能會引入更多)的包容性標誌。
實作 pytest_cmdline_preparse
hook¶
自版本 7.0 起已棄用。
在版本 8.0 中移除。
實作 pytest_cmdline_preparse
hook 已被正式棄用。請改為實作 pytest_load_initial_conftests
hook。
def pytest_cmdline_preparse(config: Config, args: List[str]) -> None: ...
# becomes:
def pytest_load_initial_conftests(
early_config: Config, parser: Parser, args: List[str]
) -> None: ...
pytest 8 中的收集變更¶
新增了一個新的 pytest.Directory
基礎收集節點,預期所有文件系統目錄的收集器節點都將繼承自它。這類似於現有的文件節點 pytest.File
。
將 pytest.Package
更改為 pytest.Directory
的子類別。Package
代表一個文件系統目錄,它是一個 Python 套件,即包含一個 __init__.py
文件。
pytest.Package
現在僅收集其自身目錄中的文件;以前它是遞迴收集的。子目錄作為子收集器節點收集,從而創建一個反映文件系統層次結構的收集樹。
session.name
現在為 ""
;以前它是 rootdir 目錄名稱。這與 session.nodeid
一致,後者始終為 ""
。
新增了一個新的 pytest.Dir
具體收集節點,它是 pytest.Directory
的子類別。此節點代表一個文件系統目錄,它不是 pytest.Package
,即不包含 __init__.py
文件。與 Package
類似,它僅收集其自身目錄中的文件,同時將子目錄作為子收集器節點收集。
現在,文件和目錄以字母順序聯合收集,除非被插件更改。以前,文件在目錄之前收集。
現在,收集樹包含直到 rootdir 的目錄/套件,對於在 rootdir 中找到的初始參數。對於 rootdir 之外的文件,僅收集直接目錄/套件 – 但請注意,不鼓勵從 rootdir 外部收集。
例如,給定以下文件系統樹
myroot/
pytest.ini
top/
├── aaa
│ └── test_aaa.py
├── test_a.py
├── test_b
│ ├── __init__.py
│ └── test_b.py
├── test_c.py
└── zzz
├── __init__.py
└── test_zzz.py
收集樹,如 pytest --collect-only top/
所示,但為了清楚起見,添加了原本隱藏的 Session
節點,現在如下所示
<Session>
<Dir myroot>
<Dir top>
<Dir aaa>
<Module test_aaa.py>
<Function test_it>
<Module test_a.py>
<Function test_it>
<Package test_b>
<Module test_b.py>
<Function test_it>
<Module test_c.py>
<Function test_it>
<Package zzz>
<Module test_zzz.py>
<Function test_it>
以前是
<Session>
<Module top/test_a.py>
<Function test_it>
<Module top/test_c.py>
<Function test_it>
<Module top/aaa/test_aaa.py>
<Function test_it>
<Package test_b>
<Module test_b.py>
<Function test_it>
<Package zzz>
<Module test_zzz.py>
<Function test_it>
程式碼/外掛程式若依賴特定集合樹狀結構,可能需要更新。
pytest.Package
不再是 pytest.Module
或 pytest.File
¶
版本 8.0 已變更。
Package
收集器節點指定一個 Python 套件,也就是含有 __init__.py
檔案的目錄。 過去,Package
是 pytest.Module
(代表單一 Python 模組) 的子類型,而模組是 __init__.py
檔案。 這已被視為設計上的錯誤 (詳情請參閱 #11137 和 #7777)。
Package
節點的 path
屬性現在指向套件目錄,而不是 __init__.py
檔案。
請注意,__init__.py
的 Module
節點 (它不是 Package
) 仍然可能存在,如果在收集期間被選取 (例如,如果您設定 python_files
以包含 __init__.py
檔案)。
收集 __init__.py
檔案不再收集套件¶
在版本 8.0 中移除。
執行 pytest pkg/__init__.py
現在僅收集 pkg/__init__.py
檔案 (模組)。 以前,它會收集整個 pkg
套件,包含目錄中的其他測試檔案,但不包含 __init__.py
檔案本身中的測試 (除非 python_files
已變更為允許 __init__.py
檔案)。
若要收集整個套件,請僅指定目錄:pytest pkg
。
pytest.collect
模組¶
自版本 6.0 起已棄用。
在版本 7.0 中移除。
pytest.collect
模組不再是公共 API 的一部分,其所有名稱現在都應直接從 pytest
匯入。
pytest_warning_captured
hook¶
自版本 6.0 起已棄用。
在版本 7.0 中移除。
此 hook 有一個 item
參數,無法由 pytest-xdist
序列化。
請改用 pytest_warning_recorded
hook,它以 nodeid
參數取代 item
參數。
pytest._fillfuncargs
函數¶
自版本 6.0 起已棄用。
在版本 7.0 中移除。
保留此函數是為了與舊版外掛程式向後相容。
其功能不應直接使用,但如果您必須取代它,請改用 function._request._fillfixtures()
,但請注意這不是公共 API,未來可能會中斷。
--no-print-logs
命令列選項¶
自版本 5.4 起已棄用。
已在版本 6.0 中移除。
已移除 --no-print-logs
選項和 log_print
ini 設定。 如果您使用過它們,請改用 --show-capture
。
pytest 3.5.0
中新增了 --show-capture
命令列選項,可讓您指定在測試失敗時如何顯示擷取的輸出:no
、stdout
、stderr
、log
或 all
(預設值)。
結果記錄 (--result-log
)¶
自版本 4.0 起已棄用。
已在版本 6.0 中移除。
--result-log
選項會產生測試報告串流,可在執行階段分析,但它使用自訂格式,需要使用者實作自己的剖析器。
pytest-reportlog 外掛程式提供 --report-log
選項,這是一個更標準且可擴充的替代方案,每行產生一個 JSON 物件,並且應涵蓋相同的使用案例。 請試用看看並提供意見回饋。
pytest-reportlog
外掛程式甚至可能會在某個時間點合併到核心中,具體取決於外掛程式的計畫以及使用者的數量。
pytest_collect_directory
hook¶
已在版本 6.0 中移除。
pytest_collect_directory
hook 多年來一直無法正常運作 (它被呼叫但結果被忽略)。 使用者可以考慮改用 pytest_collection_modifyitems
。
TerminalReporter.writer¶
已在版本 6.0 中移除。
TerminalReporter.writer
屬性已被棄用,不應再使用。 這在無意中作為該外掛程式公共 API 的一部分公開,並將其與 py.io.TerminalWriter
綁定得太緊密。
直接使用 TerminalReporter.writer
的外掛程式應改用提供相同功能的 TerminalReporter
方法。
junit_family
預設值變更為 “xunit2”¶
版本 6.0 已變更。
junit_family
選項的預設值將在 pytest 6.0 中變更為 xunit2
,這是舊版 xunit1
格式的更新,並且在現代工具中預設支援,這些工具會操作此類型的檔案 (例如,Jenkins、Azure Pipelines 等)。
建議使用者試用新的 xunit2
格式,並查看其取用 JUnit XML 檔案的工具是否支援它。
若要使用新格式,請更新您的 pytest.ini
[pytest]
junit_family=xunit2
如果您發現您的工具不支援新格式,並且想要繼續使用舊版,請將選項設定為 legacy
。
[pytest]
junit_family=legacy
透過使用 legacy
,當升級到 pytest 6.0 時,您將繼續使用舊版/xunit1 格式,其中預設格式將為 xunit2
。
為了讓使用者了解過渡期,如果命令列中給定了 --junit-xml
選項,但 junit_family
未在 pytest.ini
中明確設定,pytest 將發出警告。
已知支援 xunit2
格式的服務
節點建構變更為 Node.from_parent
¶
版本 6.0 已變更。
現在節點的建構應使用具名建構函式 from_parent
。 API 介面中的此限制旨在實現更好/更簡單的集合樹狀結構重構。
這表示現在必須調用 MyItem.from_parent(collector, name="foo")
,而不是 MyItem(name="foo", parent=collector, obj=42)
。
希望支援舊版 pytest 並抑制警告的外掛程式可以使用 hasattr
來檢查該版本中是否存在 from_parent
def pytest_pycollect_makeitem(collector, name, obj):
if hasattr(MyItem, "from_parent"):
item = MyItem.from_parent(collector, name="foo")
item.obj = 42
return item
else:
return MyItem(name="foo", parent=collector, obj=42)
請注意,from_parent
應僅使用參數的關鍵字引數呼叫。
pytest.fixture
引數僅限關鍵字¶
已在版本 6.0 中移除。
已移除將引數作為位置引數傳遞給 pytest.fixture() 的功能 - 請改用關鍵字傳遞。
funcargnames
別名為 fixturenames
¶
已在版本 6.0 中移除。
FixtureRequest
、Metafunc
和 Function
類別會追蹤其相關聯 fixture 的名稱,並使用適當命名的 fixturenames
屬性。
在 pytest 2.3 之前,此屬性名為 funcargnames
,自那時起我們一直將其保留為別名。 它最終即將移除,因為在我們或外掛程式作者必須區分 fixture 名稱和非 fixture 物件 (例如 pytest.mark.parametrize
) 提供的名稱時,它通常會造成混淆。
pytest.config
全域變數¶
已在版本 5.0 中移除。
已棄用 pytest.config
全域物件。 請改用 request.config
(透過 request
fixture);如果您是外掛程式作者,請使用 pytest_configure(config)
hook。 請注意,許多 hook 也可以間接存取 config
物件,例如透過 session.config
或 item.config
。
pytest.raises
的 "message"
參數¶
已在版本 5.0 中移除。
常見的錯誤是認為此參數會比對例外訊息,但實際上它僅用於在 pytest.raises
檢查失敗時提供自訂訊息。 為了防止使用者犯此錯誤,並且因為認為它很少使用,pytest 正在棄用它,目前沒有提供替代方案。
如果您有此參數的有效使用案例,請考慮為了獲得相同的結果,您只需在 with
陳述式結尾手動呼叫 pytest.fail
即可。
例如
with pytest.raises(TimeoutError, message="Client got unexpected message"):
wait_for(websocket.recv(), 0.5)
變成
with pytest.raises(TimeoutError):
wait_for(websocket.recv(), 0.5)
pytest.fail("Client got unexpected message")
如果您仍然對此棄用和未來移除有疑慮,請在 #3974 上發表評論。
以字串作為第二個引數的 raises
/ warns
¶
已在版本 5.0 中移除。
請改用這些的上下文管理器形式。 必要時,直接調用 exec
。
範例
pytest.raises(ZeroDivisionError, "1 / 0")
pytest.raises(SyntaxError, "a $ b")
pytest.warns(DeprecationWarning, "my_function()")
pytest.warns(SyntaxWarning, "assert(1, 2)")
變成
with pytest.raises(ZeroDivisionError):
1 / 0
with pytest.raises(SyntaxError):
exec("a $ b") # exec is required for invalid syntax
with pytest.warns(DeprecationWarning):
my_function()
with pytest.warns(SyntaxWarning):
exec("assert(1, 2)") # exec is used to avoid a top-level warning
在自訂收集器中使用 Class
¶
已在版本 4.0 中移除。
已棄用使用名為 "Class"
的物件作為自訂在 Collector
子類別中收集的節點類型的方式。 使用者應改用 pytest_pycollect_makeitem
在收集期間自訂節點類型。
此問題應僅影響建立新集合類型的高階外掛程式,因此如果您看到此警告訊息,請聯絡作者,以便他們可以變更程式碼。
pytest.mark.parametrize
中的標記¶
已在版本 4.0 中移除。
現在已棄用將標記套用至 pytest.mark.parametrize
呼叫的值。 例如
@pytest.mark.parametrize(
"a, b",
[
(3, 9),
pytest.mark.xfail(reason="flaky")(6, 36),
(10, 100),
(20, 200),
(40, 400),
(50, 500),
],
)
def test_foo(a, b): ...
此程式碼將 pytest.mark.xfail(reason="flaky")
標記套用至上述參數化呼叫的 (6, 36)
值。
這被認為難以閱讀和理解,而且其實作也為程式碼帶來了問題,阻礙了標記架構的進一步內部改進。
若要更新程式碼,請使用 pytest.param
@pytest.mark.parametrize(
"a, b",
[
(3, 9),
pytest.param(6, 36, marks=pytest.mark.xfail(reason="flaky")),
(10, 100),
(20, 200),
(40, 400),
(50, 500),
],
)
def test_foo(a, b): ...
pytest_funcarg__
字首¶
已在版本 4.0 中移除。
在非常早期的 pytest 版本中,可以使用 pytest_funcarg__
字首定義 fixture
def pytest_funcarg__data():
return SomeData()
切換到 @pytest.fixture
裝飾器
@pytest.fixture
def data():
return SomeData()
setup.cfg 檔案中的 [pytest] 區段¶
已在版本 4.0 中移除。
現在應將 setup.cfg
檔案中的 [pytest]
區段命名為 [tool:pytest]
,以避免與其他 distutils 命令衝突。
Metafunc.addcall¶
已在版本 4.0 中移除。
Metafunc.addcall
是目前參數化機制的先驅。 使用者應改用 pytest.Metafunc.parametrize()
。
範例
def pytest_generate_tests(metafunc):
metafunc.addcall({"i": 1}, id="1")
metafunc.addcall({"i": 2}, id="2")
變成
def pytest_generate_tests(metafunc):
metafunc.parametrize("i", [1, 2], ids=["1", "2"])
cached_setup
¶
已在版本 4.0 中移除。
request.cached_setup
是 fixture 可用的 setup/teardown 機制的先驅。
範例
@pytest.fixture
def db_session():
return request.cached_setup(
setup=Session.create, teardown=lambda session: session.close(), scope="module"
)
應更新此機制以使用標準 fixture 機制
@pytest.fixture(scope="module")
def db_session():
session = Session.create()
yield session
session.close()
您可以查閱 文件中的 funcarg 比較章節 以取得更多資訊。
非最上層 conftest 檔案中的 pytest_plugins¶
已在版本 4.0 中移除。
在非最上層 conftest.py 檔案中定義 pytest_plugins
現在已被棄用,因為它們會全域啟用參考的外掛程式,這令人感到意外,因為對於所有其他 pytest 功能,conftest.py
檔案僅在位於或低於它的測試中有效。
Config.warn
和 Node.warn
¶
已在版本 4.0 中移除。
這些方法是內部 pytest 警告系統的一部分,但自 3.8
起,pytest 針對其自身的警告使用內建警告系統,因此這兩個函數現在已被棄用。
Config.warn
應替換為對標準 warnings.warn
的呼叫,例如
config.warn("C1", "some warning")
變成
warnings.warn(pytest.PytestWarning("some warning"))
Node.warn
現在支援兩種簽名
node.warn(PytestWarning("some message"))
:現在是呼叫此函數的建議方式。 警告實例必須是 PytestWarning 或子類別。node.warn("CI", "some message")
:此程式碼/訊息形式已被移除,應轉換為上述警告實例形式。
record_xml_property¶
已在版本 4.0 中移除。
現在已棄用 record_xml_property
fixture,改用更通用的 record_property
,後者可供其他消費者 (例如 pytest-html
) 用於取得有關測試執行的自訂資訊。
這只是重新命名 fixture 的問題,因為 API 是相同的
def test_foo(record_xml_property): ...
變更為
def test_foo(record_property): ...
將命令列字串傳遞至 pytest.main()
¶
已在版本 4.0 中移除。
已棄用將命令列字串傳遞至 pytest.main()
pytest.main("-v -s")
請改為傳遞清單
pytest.main(["-v", "-s"])
透過傳遞字串,使用者期望 pytest 將使用他們正在使用的 shell 規則 (例如 bash
或 Powershell
) 解釋該命令列,但這很難/不可能以可移植的方式完成。
直接呼叫 fixture¶
已在版本 4.0 中移除。
已棄用直接呼叫 fixture 函數,而不是在測試函數中請求它們。
例如
@pytest.fixture
def cell():
return ...
@pytest.fixture
def full_cell():
cell = cell()
cell.make_full()
return cell
這對新使用者來說是一個很大的困惑來源,他們經常會交替呼叫 fixture 函數並從測試函數中請求它們,這會破壞 fixture 解析模型。
在這些情況下,只需在相依 fixture 中直接請求函數即可
@pytest.fixture
def cell():
return ...
@pytest.fixture
def full_cell(cell):
cell.make_full()
return cell
或者,如果 fixture 函數在測試中被多次呼叫 (使其難以套用上述模式),或者如果您想要對程式碼進行最小的變更,您可以建立一個 fixture,該 fixture 使用 name
參數呼叫原始函數。
def cell():
return ...
@pytest.fixture(name="cell")
def cell_fixture():
return cell()
yield
測試¶
已在版本 4.0 中移除。
pytest 支援 yield
樣式的測試,其中測試函數實際上 yield
函數和值,然後將其轉換為適當的測試方法。 範例
def check(x, y):
assert x**x == y
def test_squared():
yield check, 2, 4
yield check, 3, 9
這將產生兩個實際產生的測試函數。
此形式的測試函數不正確地支援 fixture,使用者應切換到 pytest.mark.parametrize
@pytest.mark.parametrize("x, y", [(2, 4), (3, 9)])
def test_squared(x, y):
assert x**x == y
透過 Node
存取的內部類別¶
已在版本 4.0 中移除。
透過 Node
實例存取 Module
、Function
、Class
、Instance
、File
和 Item
現在會發出此警告
usage of Function.Module is deprecated, please use pytest.Module instead
使用者應僅 import pytest
並使用 pytest
模組存取這些物件。
這已記錄為棄用多年,但直到現在我們才實際發出棄用警告。
Node.get_marker
¶
已在版本 4.0 中移除。
作為大型標記改版和迭代的一部分,已移除 _pytest.nodes.Node.get_marker
。 請參閱關於如何更新程式碼的提示的文件。
somefunction.markname
¶
已在版本 4.0 中移除。
作為大型標記改版和迭代的一部分,我們已棄用使用 MarkInfo
,取得元素標記的唯一正確方法是透過 node.iter_markers(name)
。
pytest_namespace
¶
已在版本 4.0 中移除。
此 hook 已被棄用,因為它極大地複雜化了關於配置和初始化的 pytest 內部結構,使得某些錯誤修復和重構變得不可能。
使用範例
class MySymbol: ...
def pytest_namespace():
return {"my_symbol": MySymbol()}
依賴此 hook 的外掛程式作者應改為要求使用者現在直接匯入外掛程式模組 (使用適當的公共 API)。
作為權宜之計,外掛程式作者仍然可以將其名稱注入 pytest 的命名空間中,通常在 pytest_configure
期間進行
import pytest
def pytest_configure():
pytest.my_symbol = MySymbol()