当前位置: 首页 > news >正文

全网最牛自动化测试框架系列之pytest(9)-标记用例(指定执行、跳过用例、预期失败)

【文章末尾给大家留下了大量的福利】

pytest中提供的mark模块,可以实现很多功能,如:

  1. 标记用例,即打标签
  2. skipskipif标记跳过,skip跳过当前用例,skipif符合情况则跳过当前用例
  3. xfail标记为预期失败

标记用例

有时候我们可能并不需要执行项目中的所有用例,而只执行其中的某些用例,即指定执行某一类或某个场景的测试用例,比如只执行冒烟用例,那么这个时候就需要使用@pytest.mark.标签名来进行打标签过滤。标签名需要先注册,然后才能使用。

注册标签

官方文档里提供了三种注册标签的方法,这里只介绍pytest.iniconftest.py,有兴趣的可以去查看官方文档。

方法一,在项目根目录新建pytest.ini,并在其中注册、管理标签。示例如下:

[pytest]

markers =
    smoke: marks test as smoke
    login
    order: 下单场景

这里定义了三个标签,分别是:smoke、login、order,冒号后面的是标签说明,可不加。

方法二,在conftest.py中定义钩子函数进行标签注册,格式如下:

def pytest_configure(config):
    marker_list = [
        "smoke: marks test as smoke",
        "login",
        "order: 下单场景"
    ]
    for marker in marker_list:
        config.addinivalue_line("markers", marker)

方法二需注意定义的格式,不能轻易修改函数名及入参。

使用方法

import pytest

# 标记测试函数
@pytest.mark.smoke
def test_01():
    print("执行test_01")

def test_02():
    print("执行test_02")

    
# 标记测试类
@pytest.mark.order
class TestOrder:
    
    def test_order(self):
        print("下单")

    def test_pay(self):
        print("支付")

        
# 多个标签 
@pytest.mark.smoke
@pytest.mark.login
def test_login():
    print("登录")

给测试类打标签,还有另外一种方式,如下:

# 标记测试类(单个标签)
class TestOrder:
    
    # 给类中的所有测试方法打上order标签
    pytestmark = pytest.mark.order
    
    def test_order(self):
        print("下单")

    def test_pay(self):
        print("支付")
    
    
# 标记测试类(多个标签)
class TestOrder:
    
    # 给类中的所有测试方法打上order、smoke标签
    pytestmark = [pytest.mark.order, pytest.mark.smoke]
    
    def test_order(self):
        print("下单")

    def test_pay(self):
        print("支付")

同样可以使用pytestmark标记模块,给模块中所有的测试类、测试函数打上标签,如下:

import pytest

# 模块中的所有测试函数、测试类都会被打上order、smoke标签
pytestmark = [pytest.mark.order, pytest.mark.smoke]

def test_01():
    print("执行test_01")

def test_02():
    print("执行test_02")


class TestOrder:
    def test_order(self):
        print("下单")

    def test_pay(self):
        print("支付")

执行方法

执行的时候加上参数-m标签名即可。

命令行

# 执行被标记为smoke的用例
pytest -m smoke

# 执行被标记为smoke且被标记为login的用例
pytest -m "smoke and login"

# 执行被标记为smoke或login的用例
pytest -m "smoke or login"

代码执行

# 执行被标记为smoke的用例
pytest.main(['-m smoke'])

# 执行被标记为smoke或order的用例
pytest.main(["-m", "smoke or order"])

# 执行被标记为smoke同时被标记为login的用例
pytest.main(["-m", "smoke and login"])

# 执行被标记为smoke且不被标记为login的用例
pytest.main(["-m", "smoke and not login"])

这里需要注意,在测试模块中直接使用pytest.main()执行当前模块中的被打标签的用例是无效的,这样会执行当前模块中的所有测试用例。如下示例:

import pytest

# 标记测试函数
@pytest.mark.smoke
def test_01():
    print("执行test_01")

def test_02():
    print("执行test_02")

    
# 标记测试类
@pytest.mark.order
class TestOrder:
    
    def test_order(self):
        print("下单")

    def test_pay(self):
        print("支付")

        
# 多个标签 
@pytest.mark.smoke
@pytest.mark.login
def test_login():
    print("登录")
    
if __name__ == '__main__':
    pytest.main(['-s', '-m smoke'])

运行该模块,结果如下:

从结果中可以看出,虽然代码中写了只执行标记为smoke的用例,但所有5条用例都被执行了,不能进行过滤。

我们需要将执行代码分离出来,放在单独的执行模块里面,如放在run.py,代码如下:

# run.py

import pytest

if __name__ == '__main__':
    pytest.main(["-s", "-m", "smoke or order"])

运行结果如下:

从结果可以看出来,这里只运行了标记为smokeorder的测试用例。

标记跳过

有时候我们需要跳过某些测试用例不去执行,如代码更新后老的用例不需要执行了,或者在某些特定场景下不需要执行某些用例,这时就需要给对应的测试用例做标记跳过处理。

pytest中提供了两种标记跳过的方法,如下:

  1. 直接跳过,@pytest.mark.skip(reason="跳过原因"),reason可写可不写。
  2. 条件跳过,即满足某个条件则跳过不执行,@pytest.mark.skipif(b>3, reason="跳过原因")

示例如下:

import pytest

@pytest.mark.skip(reason="不需要执行test_01")
def test_01():
    print("执行test_01")

@pytest.mark.skip(2>1, reason="如果2大于1则跳过不执行")
def test_02():
    print("执行test_02")
    
    
if __name__ == '__main__':
    pytest.main(['-s'])

运行结果:

从运行结果中可以看到,这2条用例都被跳过。如果想要 跳过测试类 或 测试模块,方法同上面给测试类、测试模块打标签的方法一样,不做过多说明。

xfail(标记为预期失败)

有些场景下需要将测试用例标记为预期失败,如对尚未实现的功能或尚未修复的错误进行测试,使用@pytest.mark.xfail可以将测试用例标记为预期失败。

pytest.mark.xfail(condition=None, reason=None, raises=None, run=True, strict=False),参数说明如下:

  1. condition,预期失败的条件,默认值为None,表示只有满足条件时才标记用例为预期失败。

  2. reason,失败原因,默认值为None,说明标记用例的原因。

  3. strict关键字参数,默认值为False。

    当 strict=False 时,如果用例执行失败,则结果标记为xfail,表示符合预期的失败;如果用例执行成功,结果标记为XPASS,表示不符合预期的成功;

    当strict=True时,如果用例执行成功,结果将标记为failed。

  4. raises关键字参数,默认值为None,可以上报指定的一个或多个异常。如果用例的失败不是因为所期望的异常导致的,pytest将会把测试结果标记为failed。

  5. run关键字参数,默认值为True。当run=False时,pytest不会再执行测试用例,直接将结果标记为xfail。

常用的参数示例如下:

import pytest

# run、strict都为默认,因为用例执行是失败的,所以该用例执行结果会被标记为xfail
@pytest.mark.xfail(reason="bug待修复")
def test_01():
    print("执行test_01")
    a = "hello"
    b = "hi"
    assert a == b

# run、strict都为默认,因为用例执行是通过的,所以该用例执行结果会被标记为xpass
@pytest.mark.xfail(condition=lambda: True, reason="bug待修复")
def test_02():
    print("执行test_02")
    a = "hello"
    b = "hi"
    assert a != b

# run=False,该用例不执行,直接将结果标记为xfail
@pytest.mark.xfail(reason="功能尚未开发完成", run=False)
def test_03():
    print("执行test_03")
    a = "hello"
    b = "hi"
    assert a == b

# strict=True,因为用例执行是通过的,所以结果会被标记为failed
@pytest.mark.xfail(reason="功能尚未开发完成", strict=True)
def test_04():
    print("执行test_04")
    a = "hello"
    b = "he"
    assert b in a
    
if __name__ == '__main__':
    pytest.main(['-s'])

运行结果:

从结果中可以看出来,test_01结果展示为xfailtest_02结果展示为xpasstest_03没有执行而是直接展示为xfailtest_04结果展示为failed

总结

以上示例仅仅只是为了说明@pytest.mark提供的这些功能的使用方法,实际自动化过程中需要灵活选用。

在一般的自动化测试过程中,通过打标签的方式标记某个场景用例会比较多,如标记冒烟测试用例用于冒烟测试。跳过或条件跳过测试用例也经常会用到。而需要将用例标记为预期失败的场景则比较少。

 重点:学习资料学习当然离不开资料,这里当然也给你们准备了600G的学习资料

【需要的可以扫描文章末尾的qq群二维码自助拿走】

【记得(备注“csdn000”)】

【或私信000】

群里的免费资料都是笔者十多年测试生涯的精华。还有同行大神一起交流技术哦。

项目实战:

大型电商平台:

全套软件测试自动化测试教学视频

300G教程资料下载【视频教程+PPT+项目源码】

全套软件测试自动化测试大厂面经

python自动化测试++全套模板+性能测试

听说关注我并三连的铁汁都已经升职加薪暴富了哦!!!!

相关文章:

  • ARM汇编
  • Docker部署并启动RabbitMQ
  • 树莓派远程音乐播放器
  • LeetCode用数组建立二叉树
  • Leetcode560. 和为 K 的子数组
  • Docker部署Tomcat
  • NFT交易量下滑 传统品牌布局热情未衰
  • 2022下半年各省软考报名费用汇总,不知道的看这里
  • 社交网络的数据挖掘与分析,什么是社交网络分析
  • Allegro DVT与SiMa.ai携手优化嵌入式边缘应用的能效
  • 2022-8-30 第七小组 学习日记 (day54)JavaWeb、Servlet、HTTP-请求 响应、乱码问题
  • U9二次开发之BE插件开发
  • 推荐系统-Hive基础
  • 通信原理 | 基本概念:信源、信道、噪声、信宿等
  • 关于Flask高级_RequestParser中的add_argument方法参数详解
  • gf框架之分页模块(五) - 自定义分页
  • golang中接口赋值与方法集
  • iOS 系统授权开发
  • IP路由与转发
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • Python连接Oracle
  • Redux系列x:源码分析
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • webpack项目中使用grunt监听文件变动自动打包编译
  • Xmanager 远程桌面 CentOS 7
  • 好的网址,关于.net 4.0 ,vs 2010
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 批量截取pdf文件
  • 数据科学 第 3 章 11 字符串处理
  • 说说动画卡顿的解决方案
  • 云大使推广中的常见热门问题
  • 阿里云API、SDK和CLI应用实践方案
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • #Linux(make工具和makefile文件以及makefile语法)
  • #QT(智能家居界面-界面切换)
  • #考研#计算机文化知识1(局域网及网络互联)
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (2022 CVPR) Unbiased Teacher v2
  • (C#)一个最简单的链表类
  • (四)图像的%2线性拉伸
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (转)我也是一只IT小小鸟
  • .net framework4与其client profile版本的区别
  • .net 设置默认首页
  • .net 生成二级域名
  • .NET序列化 serializable,反序列化
  • .NET应用架构设计:原则、模式与实践 目录预览
  • @GetMapping和@RequestMapping的区别
  • @Pointcut 使用
  • [AIGC] Spring Interceptor 拦截器详解
  • [Assignment] C++1
  • [AutoSar]BSW_Com02 PDU详解