IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> pytest关键字详解 -> 正文阅读

[开发测试]pytest关键字详解

一、pytest之跳过用例 @pytest.mark.skip和@ pytest.mark.skipif

1-1、@pytest.mark.skip (无条件跳过,只要使用了这个关键字就会跳过)

参数:reason(跳过的原因)

该参数非必传,可传可不传

代码:

import pytest
class TestIndex():
    @pytest.mark.skip(reason='跳过该用例')
    def test_myself(self):
        print '我被跳过了'

    def test_class(self):
        print '我没被跳过'

运行结果:

1-2、@pytest.mark.skipif(有条件跳过,只有符合条件才会跳过)

参数:

reason(跳过的原因)该参数非必传,可传可不传

condition? (跳过条件),只有当该条件结果为True时才会跳过该用例

代码:

import pytest
class TestIndex():
    @pytest.mark.skipif(condition=2>1,reason='因为2>1为真,所以跳过该用例')
    def test_myself(self):
        print '我被跳过了'

    def test_class(self):
        print '我没被跳过'

运行结果:

?1-3、除了上面两个注解以外,还可以通过调用pytest.skip()来跳过用例

代码:

import pytest
class TestIndex():
    def test_myself(self):
        pytest.skip(msg='跳过该用例')
        print '我被跳过了'

    def test_class(self):
        print '我没被跳过'

?运行结果:

?跳过用例类或用例函数的方法一样,使用1或2两个注解修饰即可

跳过模块则需要使用变量pytestmark,让它等于标签

import pytest
pytestmark=pytest.mark.skipif(condition=2>1,reason='因为2>1为真,所以跳过该用例')
class TestIndex():
    def test_myself(self):
        print '我被跳过了'

    def test_class(self):
        print '我没被跳过'

运行结果:

二、 标签@pytest.mark.parametrize()详解:

该标签是一种参数化方式,pytest有两种参数化方式,除了此标签外,还有一种是@pytest.fixture(params=[]),这个在这里不做解释,在后面fixture篇会详细说明

接下来解释说明@pytest.mark.parametrize()的各个参数

2-1、argnames、argvalues

必传参数,argnames定义参数名,argvalues为参数值

argnames数量与argvalues数量一一对应

用法:

2-1-1、单参数单值

代码:

import pytest
class TestIndex():
    @pytest.mark.parametrize(argnames='arg',argvalues=['我是参数arg'])
    def test_myself(self, arg):
        print arg

运行结果:

2-1-2、单参数多值

代码:

import pytest
class TestIndex():
    @pytest.mark.parametrize(argnames='arg',argvalues=['我是参数arg',(1),['arg']])
    def test_myself(self, arg):
        print arg

运行结果:

标签中设置了三组值,用例执行了三次,这就是pytest 的数据驱动,参数值有n组,用例就会遍历执行n次

2-1-3、多参数多值

代码:

import pytest
class TestIndex():
    @pytest.mark.parametrize(argnames="arg1,arg2",
                             argvalues=[("我是第一个参数",'我是第二个参数'),('第二次第一个参数','第二次第二个参数')])
    def test_myself(self, arg1, arg2):
        print arg1+'、'+arg2

?运行结果:

这里多参数时,参数值是一个元组,一个元组是一组参数

2-2、 indirect

1),indirect一般与pytest的request、fixture组合使用

2),当indirect为true时,argnames则要传入fixture的函数名,不再是普通参数,而是要被调用的fixture函数,argvalues则是要给这个参数传的值

3),作用其实与pytest.fixture(params)一样,但使用了@pytest.mark.parametrize相当于参数化了fixture

2-2-1.单fixture单值(列表形式传值)

代码:

import pytest
class TestIndex():
    @pytest.fixture()
    def qianzhi(self,request):   #request是pytest的固定用法,用于接收传参并调用
        user = request.param
        print '传入的用户名:%s' % user
        return user               #如果想fixture有返回值,直接return即可,这个返回值可以在调用                                            
                                  #它的测试函数中使用

    user = ['张三','李四']

    @pytest.mark.parametrize('qianzhi', user, indirect=True)   # 这里的'qianzhi'就是调用的    
                                                               # fixture的函数名,user为传递 
                                                               # 给fixture的值
    def test_myself(self, qianzhi):    #  这里入参的qianzhi就是fixture的调用,便且可以拿到 
                                       #  fixture的返回值,如果fixture有返回值
        print '测试类接收的用户名:%s' % qianzhi

运行结果:

?2-2-2.单fixture多值(字典形式传值)

代码:

import pytest
class TestIndex():
    @pytest.fixture()
    def qianzhi(self,request):
        user = request.param
        print '传入的用户名:%s,密码:%s' % (user['user'],user['pwd'])
        return user

    user = [
        {'user':'张三','pwd': '123'},
        {'user':'李四','pwd': '456'}]

    @pytest.mark.parametrize('qianzhi', user, indirect=True)
    def test_myself(self, qianzhi):
        print '测试类接收的用户名:%s,密码:%s' % (qianzhi['user'],qianzhi['pwd'])

运行结果:

?

2-2-3. 多fixture多值(嵌入元组的列表形式传参)

代码:

import pytest
class TestIndex():
    @pytest.fixture()
    def login(self,request):
        user = request.param
        print '传入的用户名:%s' %user
        return user
    @pytest.fixture()
    def pwd(self,request):
        user = request.param
        print '传入的密码:%s' % user
        return user

    user = [
        ('张三','123'),
        ('李四','456')]

    @pytest.mark.parametrize("login,pwd", user, indirect=True)
    def test_myself(self, login,pwd):
        print '测试类接收的用户名:%s,密码:%s' % (login,pwd)

运行结果:

?

2-2-4.叠加fixture(单值列表,执行次数是笛卡尔积N*M)

代码:

import pytest
class TestIndex():
    @pytest.fixture()
    def login_user(self,request):
        user = request.param
        print '传入的用户名:%s' %user
        return user
    @pytest.fixture()
    def login_pwd(self,request):
        pwd = request.param
        print '传入的密码:%s' % pwd
        return pwd

    user = ['张三','李四']
    pwd = ['123','456']

    @pytest.mark.parametrize("login_user", user, indirect=True)
    @pytest.mark.parametrize("login_pwd", pwd, indirect=True)
    def test_myself(self, login_user,login_pwd):
        print '测试类接收的用户名:%s,密码:%s' % (login_user,login_pwd)

运行结果:

?

可以看到一共执行了四次,也就是每个fixture传入值的个数的积

总结:当indirect为True时就是调用fixture,将参数传入fixture做一次前置处理,为False时就是普通的参数化

?2-3、ids(用来设置标题)

不设置ids的情况下,pytest执行后会用输入数据作为用例标题显示

使用ids可以自定义用例标题

但注意,使用中文时?会显示unicode编码

解决方法:

在test_case同级目录新建conftest.py文件,在文件中添加以下代码:

from typing import List
def pytest_collection_modifyitems(
? ? session: "Session", config: "Config", items: List["Item"]
) -> None:
? ? for item in items:
? ? ? ? item.name = item.name.encode('utf-8').decode('unicode-escape')
? ? ? ? item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')

2-4、scope

scope的作用范围取值与fixture 的scope一致,当indirect=True才会被使用

scope的作用范围会覆盖fixture的scope范围,如果同一个被调用的fixture有多个parametrize定义了scope,取第一条的范围,见下例:

2-4-1.小于Fixture的scope范围:

?2-4-2.大于Fixture的scope范围:

??2-4-3.多个parametrize不同的scope范围,为先执行的范围:

?

?2-4-4.与mark变量一起使用,标记子用例

代码:

import pytest

class TestIndex():

    @pytest.mark.parametrize('x,y',[('test','123'),
                                    pytest.param('test1','1234',marks=pytest.mark.xfail)])
    def test_myself(self,x,y):
        print '用户名:%s 密码:%s' % (x,y)

运行结果:

?三、pytest.mark.自定义标签使用

可以标记测试方法、测试类,标记名可以自定义,最好起有意义的名字

同一测试类/方法可同时拥有多个标记

3-1,实例:

import pytest

@pytest.mark.login
class TestIndex():

    @pytest.mark.test
    def test_myself(self):
        print '示例'
    @pytest.mark.start
    def test_myself(self):
        print 'kaishi'

?3-2、运行方法;

pytest -m "自定义标签名"?
或:
pytest.main(['-m 自定义标签名'])

3-3、 组合运行用例:

使用-m参数运行标记的用例,-m参数支持and、or、not等表达式

3-4、?注册、管理mark标记:

当使用 -m 参数执行 mark 标记的用例时,pytest 会发出告警信息 “PytestUnknownMarkWarning: Unknown pytest.mark.login - is this a typo? ”,告诉你这是一个 pytest 未知的一个标记!为了消除告警,我们需要在 pytest 的配置文件中注册 mark 标记!

注册mark标记:

首先在项目根目录创建一个文件 pytest.ini ,这个是 pytest 的配置文件

?然后在 pytest.ini 文件的markers 中写入你的 mark 标记, 冒号 “:” 前面是标记名称,后面是 mark 标记的说明,可以是空字符串

?注意:pytest.ini 文件中只能使用纯英文字符,绝对不能使用中文的字符(尤其是冒号和空格)

?规范使用mark标记:

注册完 mark 标记之后 pytest 便不会再告警,但是有时手残容易写错 mark 名,导致 pytest 找不到用例,一时想不开很难debug,尤其是团队协作时很容易出现类似问题

处理方法:在 pytest.ini 文件中添加参数 “addopts = --strict”

?添加该参数后,当使用未注册的 mark 标记时,pytest会直接报错:“ ‘xxx’ not found in markers configuration option ”,不执行测试任务

?注意:pytest.ini 配置文件不支持注释,不支持注释,不支持注释…

?

?

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-08-13 12:34:55  更:2021-08-13 12:35:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/17 20:25:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码