Pytest官方教程-06-使用Marks标记测试用例

目录:

  1. 安装及入门
  2. 使用和调用方法
  3. 原有TestSuite使用方法
  4. 断言的编写和报告
  5. Pytest fixtures:清晰 模块化 易扩展
  6. 使用Marks标记测试用例
  7. Monkeypatching/对模块和环境进行Mock
  8. 使用tmp目录和文件
  9. 捕获stdout及stderr输出
  10. 捕获警告信息
  11. 模块及测试文件中集成doctest测试
  12. skip及xfail: 处理不能成功的测试用例
  13. Fixture方法及测试用例的参数化
  14. 缓存: 使用跨执行状态
  15. unittest.TestCase支持
  16. 运行Nose用例
  17. 经典xUnit风格的setup/teardown
  18. 安装和使用插件
  19. 插件编写
  20. 编写钩子(hook)方法
  21. 运行日志
  22. API参考
    1. 方法(Functions)
    2. 标记(Marks)
    3. 钩子(Hooks)
    4. 装置(Fixtures)
    5. 对象(Objects)
    6. 特殊变量(Special Variables)
    7. 环境变量(Environment Variables)
    8. 配置选项(Configuration Options)
  23. 优质集成实践
  24. 片状测试
  25. Pytest导入机制及sys.path/PYTHONPATH
  26. 配置选项
  27. 示例及自定义技巧
  28. Bash自动补全设置

使用Marks标记测试用例

通过使用pytest.mark你可以轻松地在测试方法上设置元数据。例如, 一些常用的内置标记:

  • skip - 始终跳过该测试方法
  • skipif - 遇到特定情况跳过该测试方法
  • xfail - 遇到特定情况,产生一个“期望失败”输出
  • parametrize - 在同一个测试方法上运行多次调用

创建自定义标记或将标记应用于整个测试类或模块很容易。 文档中包含有关标记的示例,详情可参阅使用自定义标记。

注意:
标记只对测试方法有效,对fixtures方法无效。

在未知标记上引发异常: -strict

当使用--strict命令行参数时,未在pytest.ini文件中注册的任何标记都将引发异常。

标记可以通过以下方式注册:

[pytest]
markers =
    slow
    serial

这可用于防止用户意外输错标记名称。 想要强制执行此操作的测试套件应将--strict添加到addopts

[pytest]
addopts = --strict
markers =
    slow
    serial

标记改造和迭代

3.6版本新功能
pytest的标记传统地实现是通过简单地在测试函数的__dict__中添加属性来进行标记。结果,标记意外的随着类的集成而传递。此外,使用@pytest.mark装饰器应用的标记和通过node.add_marker添加的标记存储的位置不同,用于检索它们的API也
不一致。

这样,如果不深入了解测试代码内部结构,技术上几乎无法正确使用参数化数据,从而导致在高级的用法中出现细微且难以理解的bug。

根据标记声明/更改的方式,你都可以获得一个MarkerInfo对象,其中也可能会包含来自同级类的标记。当使用参数化标记,或node.add_marker时,会丢弃之前的使用装饰器声明的MarkDecorators标记。MarkerInfo对象实际上是使用同一标记名的多个标记的合并视图,当然,MarkerInfo也可以像单个标记一样使用。

最重要的是,即使标记是在类/模块上声明的,实际上,标记只能在函数中访问。原因是模块,类和函数/方法无法以相同的方式访问标记。

在pytest 3.6版本中引入了一个访问标记的新API,以解决初始设计中的问题,提供_pytest.nodes.Node.iter_markers()方法以一致的方式迭代标记并重新进行内部处理,这很好地解决了初始设计的问题。

升级代码

不推荐使用原有的Node.get_marker(name)函数,因为它返回一个内部MarkerInfo对象,该对象包含应用于该节点的所有标记的合并名称和所有参数。

通常,有两种方案可以处理标记:

  1. 标记互相覆盖。 顺序很重要,但你只需要将你的标记视为单独的标记即可。 例如。 对于测试方法中的log_level('debug')会覆盖模块级别的log_level('info')

在这种情况下,可以使用Node.get_closest_marker(name)

# 替换这个:
marker = item.get_marker("log_level")
if marker:
    level = marker.args[0]

# 通过这个:
marker = item.get_closest_marker("log_level")
if marker:
    level = marker.args[0]
  1. 在特定条件下使用标记。 例如,skipif(condition)标记,意味着你只想测试所有非condition条件的用例,顺序不重要。你可以将这个标记视为一个满足该条件的集合使用。

在这种情况下,迭代每个标记并单独处理它们的*args**kwargs参数。

# 替换这个:
skipif = item.get_marker("skipif")
if skipif:
    for condition in skipif.args:
        # eval condition
        ...

# 通过这个:
for skipif in item.iter_markers("skipif"):
    condition = skipif.args[0]
    # eval condition

如果您不确定或遇到任何难题,你可以考虑提出一个待解决问题。

相关问题

以下是新修复问题的详细列表:

  • 标记不会选择嵌套类(#199)。
  • 标记在所有相关类别上染色(#568)。
  • 组合标记 - args和kwargs计算(#2897)。
  • request.node.get_marker('name')为类中应用的标记返回None(#902)。
  • 在参数化中应用的标记存储为markdecorator(#2400)。
  • 以向后不兼容的方式修复标记交互(#1670)。
  • 重构标记以摆脱当前的“标记转移”机制(#2363)。
  • 介绍FunctionDefinition节点,在generate_tests中使用它(#2522)。
  • 删除命名标记属性并收集项目中的标记(#891)。
  • 来自参数化的跳过标记隐藏模块级跳过标记(#1540)。
  • skipif + parametrize不跳过测试(#1296)。
  • 标记转移与继承不兼容(#535)。

注意:
在未来的pytest主要版本中,我们将引入基于类的标记,在这些标记处,标记将不再局限于Mark的实例。

你可能感兴趣的:(Pytest官方教程-06-使用Marks标记测试用例)