弃用和移除¶
此页面列出了当前已弃用或在过去的主要版本中已移除的所有 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
参数对于 Node 构造函数已替换为 pathlib.Path
¶
自版本 7.0 起弃用。
为了支持从 py.path.local
到 pathlib
的过渡,Node
构造函数(如 pytest.Function.from_parent()
和 pytest.Class.from_parent()
)的 fspath
参数现已弃用。
构造节点的插件应传递 path
参数(类型为 pathlib.Path
),而不是 fspath
参数。
鼓励实现自定义项和收集器的插件用 path
参数(pathlib.Path
)替换 fspath
参数(py.path.local
),并在可能的情况下放弃对 py
库的任何其他使用。
如果可能,带有自定义项的插件应使用协作构造函数来避免硬编码它们仅传递给超类的参数。
注意
Node
参数和属性(新属性为path
)的名称与钩子的情况相反,如下所述(旧参数为path
)。
这是一个不幸的人工制品,由于历史原因,随着我们逐渐摆脱py依赖项,它应该在未来版本中得到解决(请参阅问题 #9283以进行更长的讨论)。
由于仍在预期返回py.path.local
对象的reportinfo()
等方法的持续迁移,节点仍然同时具有fspath
(py.path.local
)和path
(pathlib.Path
)属性,无论在构造函数中使用了什么参数。我们希望在未来的版本中弃用fspath
属性。
使用标记配置钩子规范/实现¶
在 pytest 的插件库 pluggy 成为其自己的包并拥有明确的 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/代码分析的插件已将其用作一种 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 样式。一种方法是使用固定装置
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 不再尊重此属性。
向 pytest.skip
、pytest.fail
或 pytest.exit
传递 msg=
¶
自版本 7.0 起弃用。
在版本 8.0 中移除。
现在弃用向 pytest.skip()
、pytest.fail()
或 pytest.exit()
传递关键字参数 msg
,而应改用 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
挂钩¶
自版本 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
现在是 ""
;以前它是根目录目录名称。这与 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 中移除。
pytest.collect
模块不再是公共 API 的一部分,现在应直接从 pytest
导入其所有名称。
pytest_warning_captured
钩子¶
自 6.0 版本起不推荐使用。
在版本 7.0 中移除。
此钩子有一个 item
参数,该参数无法由 pytest-xdist
序列化。
请改用 pytest_warning_recorded
钩子,它将 item
参数替换为 nodeid
参数。
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
钩子¶
在 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
类跟踪其关联 fixture 的名称,具有恰当命名的 fixturenames
属性。
在 pytest 2.3 之前,此属性名为 funcargnames
,并且自那以后,我们一直将其保留为别名。它最终会被删除,因为它通常在插件作者必须区分 fixture 名称和非 fixture 事物(例如 pytest.mark.parametrize
)提供的名称的地方造成混淆。
pytest.config
全局¶
在版本 5.0 中已删除。
pytest.config
全局对象已弃用。请改用 request.config
(通过 request
固定装置)或者如果您是插件作者,请使用 pytest_configure(config)
挂钩。请注意,许多挂钩也可以通过 session.config
或 item.config
间接访问 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()