pytest+allure学习笔记

1、Addfinalizer和yield后置操作,在前面代码抛出异常之后都不会执行了

import pytest

@pytest.fixture(scope="module")

def test_addfinalizer(request):

    # 前置操作setup

    print("==再次打开浏览器==")

    test = "test_addfinalizer"

    raise ValueError

    yield

    print("==再次关闭浏览器==")

    # def fin():

    #     # 后置操作teardown

    #     print("==再次关闭浏览器==")

    #

    # request.addfinalizer(fin)

    # 返回前置操作的变量

    return test 

def test_anthor(test_addfinalizer):

    print("==最新用例==", test_addfinalizer) 

2、Fixures需要返回值的情况只能用方法入参的方式调用,不能用pytest.usefixure方式会拿不到返回值

3、Fixure实列化顺序是优先级大的先实列化,被依赖的先实列化

4、unittest只有setup、teardown、setup_calss,teardown_class, pytest有十种,setup,setup_class,setup_moudle,setup_method,setup_function,针对整个脚本生效

5、Conftest的fixure在同一个包的用列有效,顶层conftest一般写全局的通用操作

6、Pytest.ording可以定义用列顺序,但是不推荐,因为我们的用列最好是随时随地可独立执行

7、Pytest的执行结果,用列语法错误或者调用的fixure报错执行结果是error,测试用列的代码抛出异常或者断言失败执行结果是fail,error越多测试脚本质量越撇

8、跳过执行pytest.mark.skip

pytest.mark.skip(reasion=‘不执行,因为没开发完’),可以加在class或者method

pytest.mark.skipif(sys.platform == 'win32', reason="不能在window上运行啦啦啦=====")

pytest.importorskip("pexpect", minversion="0.3")

9 、自定义标记:@pytest.mark.web

pytest -s -m web xx.py

pytest -s -m ‘web or app’ xx.py

pytest -s -m ‘not app’ xx.py

10、参数化

@pytest.mark.parametrize(self,argnames, argvalues, indirect=False, ids=None, scope=None)

 argnames可以是str,tuple,list格式,比如’input, except  /   (‘input’,’except’)   /   [‘input’,’except’]

argvalues必须是list或者tuple,但是list里面可以是str、tuple、dict,比如[(‘3+5', 8), ('6+7', 13)]   / [‘1’,’2’]  / [{‘name’:’admin’},{‘password’:’123’}] ,一个参数用str,两个参数用dict,多个参数用tuple

indirect=True表示参数以函数方式运行,拿返回值作为参数

Ids是为了增加可读性提供的一个list描述

多个parametrize装饰器作用一个method或class,最终的参数组数是多个parametrize参数组数的乘积

import pytest

@pytest.fixture(scope='function')

def get_user(request):

    return type(request.param)

@pytest.fixture(scope='function')

def get_pwd(request):

    return type(request.param) 

@pytest.mark.parametrize(['get_user', 'get_pwd'], [('admin1', 'pwd1'), ('admin2', 'pwd2')])

def test_multfixure(get_user, get_pwd):

    print(get_user + get_pwd)

# 最终的参数组数是 2*2

@pytest.mark.parametrize('get_user', ['admin1', 'pwd1'], indirect=True)

@pytest.mark.parametrize('get_pwd', ['admin2', 'pwd2'], indirect=True)

def test_multparam(get_user, get_pwd):

    print(get_user + get_pwd)

@pytest.fixture()

def logins(request):

    return type(request.param)

data = [

    {"username": "name1", "pwd": "pwd1"},

    {"username": "name2", "pwd": "pwd2"},

]

@pytest.mark.parametrize("logins", data, indirect=True)

@pytest.mark.flaky(reruns=5, reruns_delay=2)

def test_name_pwd(logins):

    assert False

11、统一加前缀简写

data=['jim','san']

names=[f'name:{name}' for name in data]

@pytest.mark.parametrize("login", data, ids=ids, indirect=True)

 

12、装饰器实现

def logger(func):

    def wrapper(*args,**kwargs):

        res=func(*args,**kwargs)

        return res

    return wrapper

 

@logger

def test_fun():

    print('test')

 

 13、es和mysql对应关系

Table--->index

Row——>doc

Cols——->filed

14、param+fixures使用

@pytest.mark.parametrize("login", data, ids=ids, indirect=True)

Login这里是一个fixure, 添加  indirect=True  参数是为了把 login 当成一个函数去执行,而不是一个参数,并且将data当做参数传入fixure,在fixure用request.param承接的就是这里的data

 

15、失败重新运行(fixure和setup失败的也重新运行)

重试次数:—return n

重试延时:—return-delay n

全局:Pytetst  —return 5 --return-delay 10

单个用列:@pytest.mark.flaky(reruns=5,reruns_delay=2)

优先级:单个>全局

 

15、重复运行:pytest-repeat(复现偶现的bug,相同参数重复运行直到失败,不稳定的case连续多跑几次)

全局:pytest -s --count 5 -x xx.py

单个:@pytest.mark.repeat(5)

 

 

16、pytest.ini(定义pytest的默认行为)

[pytest]
#自定义标签
markers =
app: app
web: web

#选项
addopts = -v

#用列收集忽略路径
norecursedirs = .* build dist CVS _darcs {arch} *.egg venv src resources log report uti

#用列收集规则
python_files = test_* *_test test*
python_classes = Test* test*
python_functions = test_* test*

 

17、Assume多重断言(前面的断言失败了后面的断言还是可以执行)

   pytest.assume(1 + 4 == 5)

    pytest.assume(1 + 3 == 3) #这里失败了后面还是会执行

    pytest.assume(2 + 5 == 7)

    pytest.assume(2 + 5 == 9)

    print("测试完成")

18、分布式运行xdist

前置条件:用列可独立、无顺序、可重复的运行

可以自动检测到系统的CPU核数为分布式进程个数:pytest -s -n auto

分布式共用一个session

# web ui自动化, 声明一个driver,再返回

# 接口自动化,发起一个登录请求,将token返回都可以这样写

@pytest.fixture(scope="session")

def login():

with FileLock("session.lock"):

return s

 

19、allure报告

环境显示:在allure报告路径生成environment.properties

Browser=Chrome

Browser.Version=81.0.4044.92

Stand=Production

ApiUrl=127.0.0.1/login 

python.Version=3.7.2

分类自定义:在allure报告路径生成categories.json

[

    {

        "name": "通过的用例数",

        "matchedStatuses": [

            "passed"

        ]

    },

    {

        "name": "实际结果与期望不符", 

        "matchedStatuses": ["failed"],  #运行结果

        "traceRegex": ".*AssertionError.*",  #正则匹配堆栈信息

        "flaky": true #标记为闪烁,失败了下次还可以运行

    }

]

 

标记测试step

@allure.step("第一步")

def passing_step():

pass

标记附件

allure.attach(file, title,filetype)

posted @ 2020-08-13 17:51  频顾  阅读(260)  评论(0)    收藏  举报