pytest8.x版本 中文使用文档-------30.示例:改变标准(Python)测试发现机制

目录

在测试收集期间忽略路径

在测试收集期间取消选择测试

命令行中指定重复路径的处理

修改目录递归

更改命名约定

将命令行参数解释为Python包

找出收集的内容

自定义测试收集


在测试收集期间忽略路径

你可以通过在命令行上传递--ignore=path选项来轻松地在收集期间忽略某些测试目录和模块。pytest 允许使用多个 --ignore 选项。以下是一个示例:

tests/  
|-- example  
|   |-- test_example_01.py  
|   |-- test_example_02.py  
|   '-- test_example_03.py  
|-- foobar  
|   |-- test_foobar_01.py  
|   |-- test_foobar_02.py  
|   '-- test_foobar_03.py  
'-- hello  
    '-- world  
        |-- test_world_01.py  
        |-- test_world_02.py  
        '-- test_world_03.py

现在,如果你使用 --ignore=tests/foobar/test_foobar_03.py --ignore=tests/hello/ 调用 pytest,你会看到 pytest 只收集那些不匹配指定模式的测试模块:

=========================== test session starts ============================  
platform linux -- Python 3.x.y, pytest-5.x.y, py-1.x.y, pluggy-0.x.y  
rootdir: $REGENDOC_TMPDIR, inifile:  
collected 5 items  
  
tests/example/test_example_01.py .                                   [ 20%]  
tests/example/test_example_02.py .                                   [ 40%]  
tests/example/test_example_03.py .                                   [ 60%]  
tests/foobar/test_foobar_01.py .                                     [ 80%]  
tests/foobar/test_foobar_02.py .                                     [100%]  
  
========================= 5 passed in 0.02 seconds =========================

在测试收集期间取消选择测试

通过传递 --deselect=item 选项,可以在收集过程中单独取消选择测试。例如,假设 tests/foobar/test_foobar_01.py 包含 test_a 和 test_b。你可以通过调用 pytest 并使用 --deselect tests/foobar/test_foobar_01.py::test_a 来运行 tests/ 目录下的所有测试,但除了 tests/foobar/test_foobar_01.py 中的 test_a。pytest 允许使用多个 --deselect 选项。

命令行中指定重复路径的处理

pytest 的默认行为是忽略从命令行中指定的重复路径。例如:

pytest path_a path_a

...
collected 1 item
...

在上述命令中,尽管 path_a 被指定了两次,但 pytest 只会收集并运行该路径下的测试一次。

要收集重复的测试,你可以在命令行界面(CLI)上使用--keep-duplicates选项。以下是一个例子:

pytest --keep-duplicates path_a path_a

...
collected 2 items
...

由于测试收集器主要工作于目录上,但如果你两次指定了同一个测试文件,那么无论是否指定了--keep-duplicates选项,pytest 都会将其收集两次。这是因为当你直接指定测试文件时,pytest 会将它们视为独立的输入项。以下是一个例子:

pytest test_a.py test_a.py

...
collected 2 items
...

修改目录递归

你可以在项目的根目录下的配置文件(如pytest.ini)中设置norecursedirs选项,以指示pytest在递归查找测试时不进入某些特定的目录。例如:

# pytest.ini 文件的内容  
[pytest]  
norecursedirs = .svn _build tmp*

这将会告诉pytest不要递归进入如.svn(Subversion版本控制系统目录)、_build(Sphinx构建目录的常用名称)或任何以tmp为前缀的目录。

更改命名约定

在pytest中,你可以通过配置文件(如pytest.ini)来设置不同的命名约定,以自定义pytest如何查找和识别测试文件、测试类和测试函数。以下是如何通过配置python_filespython_classespython_functions来改变命名约定的一个例子:

# pytest.ini 文件的内容  
# 示例 1: 让pytest查找以"check"开头的文件,而不是默认的"test"  
[pytest]  
python_files = check_*.py  
python_classes = Check  
python_functions = *_check

这个配置会使得pytest在匹配check_*.py这个glob模式(通配符模式)的文件中查找测试,在类名以Check为前缀的类中查找测试,以及在函数名或方法名匹配*_check模式的函数和方法中查找测试。以下是一个具体的例子来说明这一点:

# check_myapp.py 文件的内容  
class CheckMyApp:  
    def simple_check(self):  
        pass  
  
    def complex_check(self):  
        pass

测试收集(Test Collection)的结果看起来会像这样:

$ pytest --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
configfile: pytest.ini
collected 2 items

<Dir pythoncollection.rst-201>
  <Module check_myapp.py>
    <Class CheckMyApp>
      <Function simple_check>
      <Function complex_check>

======================== 2 tests collected in 0.12s ========================

你可以通过在模式之间添加一个空格来检查多个glob模式:

# Example 2: have pytest look for files with "test" and "example"
# content of pytest.ini
[pytest]
python_files = test_*.py example_*.py

注意

python_functions 和 python_classes 选项对于 unittest.TestCase 的测试发现没有影响,因为pytest将测试用例方法的发现委托给了unittest代码。

将命令行参数解释为Python包

你可以使用--pyargs选项来让pytest尝试将参数解释为Python包名,从而推导出它们的文件系统路径,并运行测试。例如,如果你已经安装了unittest2,你可以输入:

pytest --pyargs unittest2.test.test_skipping -q

pytest尝试将unittest2.test.test_skipping解释为Python中的一个包(或模块)路径,并自动找到该包在文件系统上的位置,然后运行该包中的测试。

和其他选项一样,你可以通过在ini文件中使用addopts选项来使这个更改更加持久化:

# pytest.ini 文件的内容  
[pytest]  
addopts = --pyargs

现在,简单地调用 pytest NAME 将检查 NAME 是否作为一个可导入的包/模块存在,如果不存在,则将其视为文件系统路径。

找出收集的内容

你可以在不运行测试的情况下,通过以下方式窥探收集到的测试树:

. $ pytest --collect-only pythoncollection.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
configfile: pytest.ini
collected 3 items

<Dir pythoncollection.rst-201>
  <Dir CWD>
    <Module pythoncollection.py>
      <Function test_function>
      <Class TestClass>
        <Function test_method>
        <Function test_anothermethod>

======================== 3 tests collected in 0.12s ========================

自定义测试收集

你可以通过简单地修改pytest的配置文件(如pytest.ini),来指示pytest从每个Python文件中发现测试。

# content of pytest.ini
[pytest]
python_files = *.py

然而在许多项目中,可能会有一个setup.py文件,这个文件通常不希望被当作测试文件来导入。此外,还可能有只能由特定Python版本导入的文件。对于这样的情况,你可以在conftest.py文件中动态定义要忽略的文件列表,从而避免这些文件被pytest作为测试文件收集。

# conftest.py 文件的内容  
import sys  
  
collect_ignore = ["setup.py"]  # 始终忽略 setup.py  
  
# 根据Python版本动态添加要忽略的文件  
if sys.version_info[0] > 2:  # 如果Python主版本号大于2(即Python 3及更高版本)  
    collect_ignore.append("pkg/module_py2.py")  # 忽略只能在Python 2中导入的文件

然后如果你有一个这样的模块文件:

# content of pkg/module_py2.py
def test_only_on_python2():
    try:
        assert 0
    except Exception, e:
        pass

还有一个setup.py文件,像这样:

# content of setup.py
0 / 0  # will raise exception if imported

如果你使用Python 2解释器运行pytest,那么pytest将只会发现找到一个测试,并且会忽略setup.py文件。

#$ pytest --collect-only
====== test session starts ======
platform linux2 -- Python 2.7.10, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 1 items
<Module 'pkg/module_py2.py'>
  <Function 'test_only_on_python2'>

====== 1 tests found in 0.04 seconds ======

如果使用Python 3解释器运行,则测试文件和setup.py文件将被忽略

$ pytest --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
configfile: pytest.ini
collected 0 items

======================= no tests collected in 0.12s ========================

还可以通过向collect_ignore_glob添加模式来基于Unix shell样式的通配符忽略文件。

以下是一个conftest.py文件的示例,它会在使用Python 3解释器执行时忽略setup.py文件以及所有以_py2.py结尾的文件:

# conftest.py 文件的内容  
import sys  
  
collect_ignore = ["setup.py"]  # 始终忽略 setup.py 文件  
if sys.version_info[0] > 2:   # 如果Python主版本号大于2(即Python 3)  
    collect_ignore_glob = ["*_py2.py"]  # 则忽略所有以 _py2.py 结尾的文件

自Pytest 2.6版本以来,用户可以通过将布尔类型的__test__属性设置为False来阻止pytest发现以Test开头的类作为测试用例。

# Will not be discovered as a test
class TestClass:
    __test__ = False

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值