已棄用和已移除功能¶
此頁面列出所有目前已棄用或在過去主要版本中已移除的 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
,且不再發出任何警告 – 但使用者仍可以透過傳遞給 exc_type
來捕捉 ImportError
。
fspath
參數用於節點建構函式,已替換為 pathlib.Path
¶
自版本 7.0 起已標示為已棄用。
為了支援從 py.path.local
轉換到 pathlib
,Node
建構函式(例如 pytest.Function.from_parent()
和 pytest.Class.from_parent()
)的 fspath
參數現已棄用。
建構節點的外掛程式應傳遞 path
參數(類型為 pathlib.Path
),而不是 fspath
參數。
建議實作自訂項目和收集器的外掛程式將 fspath
參數 (py.path.local
) 取代為 path
參數 (pathlib.Path
),並盡可能捨棄其他使用 py
函式庫的用法。
如果可能,具有自訂項目的外掛程式應使用 合作建構函式,以避免硬編碼僅傳遞給超類別的參數。
注意
Node
參數和屬性的名稱(新屬性為 path
)與勾子(如下所述,舊參數為 path
)的情況相反。
這是由於歷史原因而產生的不幸結果,隨著我們逐漸擺脫 py 相依性,應該會在未來版本中解決(有關更詳細的討論,請參閱 問題 #9283)。
由於 reportinfo()
等方法正在進行遷移,預計仍會傳回 py.path.local
物件,因此節點仍同時具有 fspath
(py.path.local
) 和 path
(pathlib.Path
) 屬性,無論建構函式中使用哪個參數。我們預計會在未來的版本中棄用 fspath
屬性。
使用標記設定掛鉤規範/實作¶
在 pluggy(pytest 的外掛程式庫)成為其自己的套件並擁有明確的 API 之前,pytest 僅使用 pytest.mark
來設定掛鉤。
裝飾器 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
py.path.local
已由 pathlib.Path
取代,用於掛鉤的參數¶
自版本 7.0 起已標示為已棄用。
為了支援從 py.path.local
轉換至 pathlib
,下列掛鉤現在會接收額外的參數
pytest_ignore_collect(collection_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
路徑已標示為不建議使用:手動呼叫這些掛鉤的外掛程式應只傳遞新的 pathlib.Path
參數,而使用者應變更其掛鉤實作以使用新的 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 起已標示為已棄用。
定義一個自訂的 pytest 節點類型,同時是 Item
和 Collector
(例如 File
),現在會發出警告。它從未獲得明智的支持,而且會觸發難以除錯的錯誤。
提供 linting/程式碼分析的一些外掛程式已將此用作一種技巧。相反地,應該使用一個獨立的收集器節點,來收集項目。請參閱 使用非 Python 測試 以取得範例,以及 修正繼承的範例公關。
自訂 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
,如 上述所述),現在會提出不建議使用的警告。
將標記套用至固定裝置函式¶
自版本 7.4 起不建議使用。
將標記套用至固定裝置函式從未產生任何效果,但這是一個常見的使用者錯誤。
@pytest.mark.usefixtures("clean_database")
@pytest.fixture
def user() -> User: ...
在這種情況下,使用者預期 usefixtures
標記會產生預期的效果,即在呼叫 user
時使用 clean_database
固定裝置,但實際上它根本沒有任何效果。
現在,當 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
方法並非 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
(請參閱 方法和函式層級設定/清除),因此上述內容應變更為
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 樣式。執行此操作的方法之一是使用固定裝置
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
。此變更旨在讓這些函式與 @pytest.mark.skip
和 @pytest.mark.xfail
標記保持一致性,這些標記已接受 reason
引數。
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 中移除。
在 pytest 8 中,已移除 Parser.addoption
的多種行為(自 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
掛鉤¶
自版本 7.0 起已標示為已棄用。
已在版本 8.0 中移除。
實作 pytest_cmdline_preparse
掛鉤已正式棄用。請改為實作 pytest_load_initial_conftests
掛鉤。
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
(非 Package
)的 Module
節點仍可能存在,如果它在蒐集期間被選取(例如,如果您將 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 中移除。
模組不再是公開 API 的一部分,現在應直接從 pytest.collect
匯入所有名稱。pytest
pytest_warning_captured
掛鉤¶
pytest_warning_captured
自版本 6.0 起已棄用。
已在版本 7.0 中移除。
此掛鉤有一個
參數,無法由 item
序列化。pytest-xdist
請改用
掛鉤,它會以 pytest_warning_recorded
參數取代 nodeid
參數。item
pytest._fillfuncargs
函式¶
pytest._fillfuncargs
自版本 6.0 起已棄用。
已在版本 7.0 中移除。
保留此函式是為了與較舊的外掛程式保持向後相容性。
其功能並非供直接使用,但如果您必須取代它,請改用
,但請注意這不是公開 API,未來可能會中斷。function._request._fillfixtures()
--no-print-logs
命令列選項¶
--no-print-logs
自版本 5.4 起已棄用。
已於版本 6.0 中移除。
選項和 --no-print-logs
ini 設定已移除。如果您使用它們,請改用 log_print
。--show-capture
命令列選項已新增至 --show-capture
,允許在測試失敗時指定如何顯示擷取的輸出:pytest 3.5.0
、no
、stdout
、stderr
或 log
(預設值)。all
結果記錄 (--result-log
)¶
自版本 4.0 起已棄用。
已於版本 6.0 中移除。
選項會產生一串測試報告,可以在執行期間進行分析,但它使用自訂格式,要求使用者實作自己的剖析器。--result-log
pytest-reportlog 外掛程式提供
選項,這是一個更標準且可擴充的替代方案,每行產生一個 JSON 物件,且應涵蓋相同的使用案例。請試用並提供意見回饋。--report-log
外掛程式甚至可能在某個時間點合併到核心,具體取決於外掛程式的計畫和使用它的使用者數量。pytest-reportlog
pytest_collect_directory
掛鉤¶
pytest_collect_directory
已於版本 6.0 中移除。
掛鉤多年來一直無法正常運作(它已被呼叫,但結果遭到忽略)。使用者可以考慮改用 pytest_collect_directory
pytest_collection_modifyitems
。
TerminalReporter.writer¶
已於版本 6.0 中移除。
屬性 TerminalReporter.writer
已過時,且不應再使用。這是該外掛程式公開 API 的一部分,但無意間公開,並與 py.io.TerminalWriter
綁定過於緊密。
直接使用 TerminalReporter.writer
的外掛程式應改用 TerminalReporter
方法,以提供相同的功能。
junit_family
預設值變更為「xunit2」¶
在版本 6.0 中變更。
在 pytest 6.0 中,junit_family
選項的預設值將變更為 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
選項,但未在 pytest.ini
中明確設定 junit_family
,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
類別會追蹤其關聯固定裝置的名稱,並使用適切命名的 fixturenames
屬性。
在 pytest 2.3 之前,此屬性名為 funcargnames
,而我們從那時起就將其保留為別名。由於在我們或外掛作者必須區分固定裝置名稱和非固定裝置項目(例如 pytest.mark.parametrize
)提供的名稱的地方,這通常會造成混淆,因此最終會將其移除。
pytest.config
全域¶
已在版本 5.0 中移除。
全局物件 pytest.config
已棄用。請改用 request.config
(透過 request
固定裝置),或者如果您是外掛程式作者,請使用 pytest_configure(config)
掛鉤。請注意,許多掛鉤也可以間接存取 config
物件,例如透過 session.config
或 item.config
。
"message"
參數 pytest.raises
¶
已在版本 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__
前綴來定義固定裝置
def pytest_funcarg__data():
return SomeData()
切換至 @pytest.fixture
裝飾器
@pytest.fixture
def data():
return SomeData()
[pytest] 部分在 setup.cfg 檔案中¶
已在版本 4.0 中移除。
[pytest]
部分在 setup.cfg
檔案中現在應命名為 [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
是提供給固定裝置的設定/清除機制的先驅。
範例
@pytest.fixture
def db_session():
return request.cached_setup(
setup=Session.create, teardown=lambda session: session.close(), scope="module"
)
這應該更新為使用標準固定裝置機制
@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
固定裝置現在已過時,取而代之的是更通用的 record_property
,其他消費者(例如 pytest-html
)可以使用它來取得關於測試執行的自訂資訊。
這只是重新命名固定裝置,因為 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
),但這在可攜式方式中非常困難/不可能。
直接呼叫固定裝置¶
已在版本 4.0 中移除。
直接呼叫固定裝置函式(而非在測試函式中要求它們)已過時。
例如
@pytest.fixture
def cell():
return ...
@pytest.fixture
def full_cell():
cell = cell()
cell.make_full()
return cell
這會讓新使用者感到非常困惑,他們經常會交替呼叫固定裝置函式和從測試函式要求它們,這會中斷固定裝置解析模型。
在這些情況下,只要直接在相依固定裝置中要求函式即可
@pytest.fixture
def cell():
return ...
@pytest.fixture
def full_cell(cell):
cell.make_full()
return cell
或者,如果在測試中多次呼叫固定裝置函式(這使得難以套用上述模式),或者如果您想對程式碼進行最小的變更,您可以建立一個固定裝置,它會呼叫原始函式以及 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
這將導致產生兩個實際的測試函式。
這種形式的測試函式無法適當地支援固定裝置,使用者應改用 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 中移除。
此掛鉤已棄用,因為它極大地複雜化了 pytest 內部關於組態和初始化的內容,使得一些錯誤修正和重構變得不可能。
使用範例
class MySymbol: ...
def pytest_namespace():
return {"my_symbol": MySymbol()}
依賴此掛鉤的外掛作者應該要求使用者現在直接匯入外掛模組(具有適當的公開 API)。
作為權宜措施,外掛作者仍可以在 pytest_configure
期間將其名稱注入 pytest 的命名空間。
import pytest
def pytest_configure():
pytest.my_symbol = MySymbol()