python框架之pytest

bilibili学习地址:

https://www.bilibili.com/video/BV14U4y137mF?p=11&spm_id_from=pageDriver

运行多条用例方式

def inc(x):
    return x + 1


def test_answer():
    assert inc(4) == 5


class TestDemo:
    def test_demo01(self):
        pass

执行包下所有的用例:pytest/py.test [包名]

执行单独一个pytest模块:pytest 文件名.py

运行某个模块里面某个类:pytest 文件名.py::类名

运行某个模块里面某个类里面的方法:pytest 文件名.py::类名::方法名

pytest 文件名.py::类名 -v : 查询类下面有多少可执行的case

Pycharm默认测试执行器配置为pytest

1.进入tools -> Python Integrated Tools

2.选择Default test runner 为pytest

小知识点:文件鼠标右键Open In Terminal,进入命令行运行当前文件

运行结果分析

常用的:fail/error/pass

特殊的结果:warning/deselect (后面会讲)

Pytest 测试框架结构(setup/teardown)

测试装置介绍
类型:
setup_module/teardown_module:全局模块级
*setup_class/teardown_class:类级,只在类中前后运行一次
setup_function/teardown_function:函数级,在类外
setup_method/teardown_methond:方法级,类中的每个方法执行前后
*Setup/teardown:在类中,运行在调用方法的前后(重点)
命令行参数~常用命令行参数

-help

-x :用例一旦失败(fail/error),就立刻停止执行

—maxfail=num :用例达到

-m :标记用例

-k :执行包含某个关键字的测试用例

实例:pytest test_first.py::TestDemo -v -k “demo”

-v :打印详细日志

-s :打印输出日志(一般-vs 一块儿使用)

—collect-only :(测试平台,python 自动导入功能)收集测试用例,不执行case

命令行参数~使用缓存状态

—if(—list-failed) :只重新运行故障

如:pytest —if 只执行上次运行失败的case

—ff(—failed-first) :先运行故障然后再运行其余的测试

Mark:标记测试用例 @pytest.mark.标签

场景:只执行符合要求的一部分测试用例,可以把一个web项目划分多个模块,然后指定模块名称执行

解决:在测试用例方法上加 @pytest.mark.标签

执行:-m 执行自定义标记的相关用例(-m后面加不加=都行)

Pytest -s test_mark_zi_09.py -m = webtest

Pytest -s test_mark_zi_09.py -m aptest

Pytest -s test_mark_zi_09.py -m “not iOS”

实例: pytest test_first.py -vs -m "str"

注:

处理打印中的警告 warnings处理方法:创建pytest.ini文件,并在文件中注册pytest中mark后面的标签名

如:

@pytest.mark.float

def test_double_float():

print("test double float")

assert 0.2 == double(0.1)

# pytest.ini 文件中注册的内容

[pytest]

markers = str

bignum

float

int

minus

zero

实例代码:

import pytest

'''def inc(x):
    return x + 1


def test_answer():
    assert inc(4) == 5


class TestDemo:
    def test_demo01(self):
        pass
    def test_demo02(self):
        pass
    def test_demo03(self):
        pass'''
def double(a):
    return a * 2


# 测试数据:整型
@pytest.mark.int
def test_double_int():
    print("test double int")
    assert 2 == double(1)


# 测试数据:负数
@pytest.mark.minus
def test_double1_minus():
    print("test double int")
    assert -2 == double(-1)


# 测试数据:浮点数
@pytest.mark.float
def test_double_float():
    print("test double float")
    assert 0.2 == double(0.1)


#
@pytest.mark.float
def test_double2_minus():
    print("test double minus")
    assert -0.2 == double(-0.1)


#
@pytest.mark.zero
def test_double_0():
    assert 0 == double(0)


#
@pytest.mark.bignum
def test_double_bignum():
    print("test double int")
    assert 200 == double(100)


#
@pytest.mark.str
def test_double_str():
    print("test double int")
    assert "aa" == double("a")


#
@pytest.mark.str
def test_double_str1():
    print("test double int")
    assert 'a$a$' == double('a$')

创建pytest.ini文件

[pytest]
markers = str
          bignum
          float
          int
          minus
          zero
Mark:跳过(skip)及预期失败(xFail)

这是pytest的内置标签,可以处理一些特殊的测试用例,不能成功的测试用例

Skip - 始终跳过该测试用例

Skipif - 遇到特定情况跳过该测试用例

Xfail - 遇到特定情况,产生一个“期望失败”输出

import pytest


@pytest.mark.skip
def test_aaa():
#    print("start")
    print("代码未开发完")
    assert True


@pytest.mark.skip(reason="代码没有实现")
def test_bbb():
    assert False

# 代码中添加,跳过代码块 pytest.skip(reson="")
def check_login():
    return True

def test_funcion():
    print("start")
    # 如果未登录,则跳过后续步骤
    if not check_login():
        pytest.skip("unsupported configuration")
    print("end")
Skip使用场景

调试时不想运行这个用例

标记无法在某些平台上运行的测试功能

在某些版本中执行,其他版本中跳过

比如:当前的外部资源不可用时跳过

如果测试数据是从数据库中取到的,

链接数据库的功能如果返回结果未成功就跳股,因为执行也都报错

解决1:添加装饰器

@pytest.mark.skip

@pytest.mark.skipif

解决2:代码中添加跳过代码

pytest.skip(reason)

import pytest
import sys

# print("sys.platform:", sys.platform)


@pytest.mark.skipif(sys.platform == 'darwin', reason="does not run on mac")
def test_case1():
    assert True


@pytest.mark.skipif(sys.platform == 'win', reason="does not run on windows")
def test_case2():
    assert True


@pytest.mark.skipif(sys.version_info < (3, 6), reason="requires python3.6 or higher")
def test_case3():
    assert True
xfail 使用场景

与skip类似,预期结果为fail,标记用例为fail

用法:添加装饰器@pytest.mark.xfail

import pytest


def test_xfail():
    print("****开始测试****")
    pytest.xfail(reason="该功能尚未完成")
    print("测试过程")
    assert 1 == 1


@pytest.mark.xfail
def test_aaa():
    print("test_xfail 方法执行")
    assert 2 == 2


xfail = pytest.mark.xfail


@xfail(reason="bug 110")
def test_hello4():
    assert 0

参数化

参数化设计方法就是将模型中的定量信息变量化,使之成为任意调整的参数。对于变量化参数赋予不同数值,就可得到不同大小和形状的零件模型。

mark:参数化测试函数

测试场景:

测试登录成功,登录失败(账号错误,密码错误)

创建多种账号:中文账号,英文账号

普通测试用例方法:

copy多分代码or读入入参数?

一次性执行多个输入入参数

Pytest参数化实现方法

@pytest.mark,parametrize进行参数化和数据驱动更灵活

mark:参数化测试函数使用

单参数:

import pytest

search_list = ['appium', 'selenium', 'pytest']


@pytest.mark.parametrize('name', search_list)
def test_search(name):
    assert name in search_list

多参数:

import pytest


# 多个参数:
# 1.参数化的名字,要与方法中的参数名,一一对应
# 2.如果传递多个参数的话,要放在列表中,列表中嵌套列表/元组

@pytest.mark.parametrize("test_input, expected", [("3+5", 8), ("2+5", 7), ("7+5", 12)])
def test_mark_more(test_input, expected):
    assert eval(test_input) == expected

用例重命名:添加ids参数

import pytest


# 多个参数:
# 1.参数化的名字,要与方法中的参数名,一一对应
# 2.如果传递多个参数的话,要放在列表中,列表中嵌套列表/元组
# 3.ids 的个数 == 传递的数据个数

@pytest.mark.parametrize("test_input, expected", [("3+5", 8), ("2+5", 7), ("7+5", 12)], ids=["number1", "number2", "number3"])
def test_mark_more(test_input, expected):
    assert eval(test_input) == expected

笛卡尔积:

比如:

a = [1, 2, 3]

b = [a ,b, c]

有几种组合形势?

(1, a), (1, b), (1, c)

(2, a), (2, b), (2, c)

(3, a), (3, b), (3, c)

@pytest.mark.parametrize("wd", ["appium", "selenium", "pytest"])
@pytest.mark.parametrize("code", ["utf-8", "gbk", "gb2312"])
def test_dkej(wd, code):
    print(f"wd: {wd}, code: {code}")

小知识扩展:

eval()函数

eval()函数用来执行一个字符串表达式,并返回表达式的值。

eval是Python的一个内置函数,这个函数的作用是,返回传入字符串的表达式的结果。想象一下变量赋值时,将等号右边的表达式写成字符串的格式,将这个字符串作为eval的参数,eval的返回值就是这个表达式的结果。

python中eval函数的用法十分的灵活,但也十分危险,安全性是其最大的缺点。本文从灵活性一方面介绍eval。

————————————————

也可以这样来理解:

eval()函数就是实现list、dict、tuple、与str之间的转化

语法:eval(expression[, globals[, locals]])

参数:

expression – 表达式。

globals – 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。

locals – 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。

————————————————

示列:

python 代码执行pytest

使用main函数
使用python -m pytest调用 pytest(jenkins持续集成用例)

python 代码执行pytest - main 函数

if __name__ == ‘__main__’:

# 1.运行当前目录下所有符合规则的用例,包括子目录(test_*.py 和 *_test.py)

pytest.main()

# 2.运行 test_mark1.py::test_dkej 模块中的某一条用例

pytest.main([‘’test_mark1.py::test_dkej, ‘-vs’])

# 3.运行某个标签

pytest.main([‘test_mark1.py’, ‘-vs’, ‘-m’, ‘dekt’])

运行方式

pytest test_*.py

if __name__ == '__main__':
    # 1.运行当前目录下所有符合规则的用例,包括子目录(test_*.py 和 *_test.py)
    pytest.main()
    # 2.运行 test_mark1.py::test_dkej 模块中的某一条用例
    '''pytest.main(['test_param.py::test_mark_more', '-vs'])'''
    # 3.运行某个标签
    '''pytest.main("运行某个标签:", ['test_param.py', '-vs', '-m', 'dekj'])'''

常用的异常处理方法

Try...except
Pytest.raises()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值