Pytest钩子函数获取用例执行情况

一、背景:

我们平时使用pytest执行完接口自动化后,可能还要对接邮箱现在更多的是到企业微信、钉钉等发送用例执行情况给到同事,本篇主要介绍如何搜集用例的这些执行情况

二、钩子函数:

2.1、创建位置:

项目主路径下-创建conftes.py文件,这样不用做任何钩子函数自动加载

2.2、代码介绍:

在用例执行完成后会自动打印出结果

def pytest_terminal_summary(terminalreporter, exitstatus, config):
    '''
    收集用例执行结果
    :param terminalreporter:
    :param exitstatus:
    :param config:
    :return:
    '''
    print("捕捉用例的通过对象", len(terminalreporter.stats.get("passed", [])))
    print("捕捉用例的失败对象", len(terminalreporter.stats.get("failed", [])))
    print("捕捉用例的跳过对象", len(terminalreporter.stats.get("skipped", [])))
    faild_list = list()
    faild_object = terminalreporter.stats.get("passed", [])
    print("捕捉用例总数", terminalreporter._numcollected)
    print("捕捉所有对象", terminalreporter.stats)
    for i in faild_object:
        print("获取失败用例集对象i:", i)
        print("获取失败用例集对象名称location", i.location)
        faild_list.append(i.location[-1])
        print("获取失败用例集日志", i.longrepr)

2.3、按各域返回用例情况:

def pytest_terminal_summary(terminalreporter, exitstatus, config):
    '''
    收集用例执行结果
    :param terminalreporter:
    :param exitstatus:
    :param config:
    :return:
    '''
    print("捕捉用例的通过对象", len(terminalreporter.stats.get("passed", [])))
    print("捕捉用例的失败对象", len(terminalreporter.stats.get("failed", [])))
    print("捕捉用例的跳过对象", len(terminalreporter.stats.get("skipped", [])))
    passed_list = list()
    _list = []
    _list1 = []
    passed_object = terminalreporter.stats.get("passed", [])
    print("捕捉用例总数", terminalreporter._numcollected)
    print("捕捉所有对象", terminalreporter.stats)

    for i in passed_object:
        print("获取成功用例集对象i:", i)
        item2 = str(i).split("::")[0]
        if 'test_product/credit' in item2:
            _list.append(item2)
        if 'test_product/tax' in item2:
            _list1.append(item2)
        # _list.append(str(i).split("::")[0])
        print("获取成功用例集对象名称location", i.location)
        passed_list.append(i.location[0])
    print(_list)
    print(_list1)
    print(len(_list))
    print(len(_list1))
    print(passed_list)

在这里插入图片描述
返回情况:
在这里插入图片描述

三、pytest结合allure生成测试报告

3.1、用例执行情况查看:

可以结合生成的报告文件-data下的suites.json中获取执行详情进行解析后即可获得,也可以知道每个测试用例集下的情况
在这里插入图片描述

四、统计个人名下的测试用例方法:

4.1、添加用例别名并注明作者:

例如:
@pytest.mark.parametrize(
'case_id, case_name,[(test01,test02)], ids=[‘测试testcase1@张三’])
备注:这样该条用例就会统计到作者为-张三名下
在这里插入图片描述

4.2、钩子函数统计用例到个人:

def pytest_collection_modifyitems(items):
    list_name = []
    list_node = []
    case_number_list = []
    cases_number_dict = {
    
    }
    for item in items:
        item.name = item.name.encode("utf-8").decode("unicode_escape")
        item._nodeid = item.nodeid.encode("utf-8").decode("unicode_escape")
        list_node.append(item._nodeid)
        list_name.append(item.name)
        try:
            # 以@开头匹配第一个不是中文的字符串匹配作者
            match_obj = re.findall("(?<=@).*?(?=[\x00-\xff])", str(item.name))
            case_number_list += match_obj
        except:
            continue
    _list = set(case_number_list)
    for i in _list:
        cases_number_dict[f'{
      
      i}'] = case_number_list.count(i)
    # print(f"=================={case_number_list}")
    print(f"=======个人名下用例汇总:{
      
      cases_number_dict}")
    logger.info(f"测试用例名称:{
      
      list_name}")
    logger.info(f"测试用例文件路径:{
      
      list_node}")

这样就能根据别名中的用例作者去分别匹配用例个数了,最终结果:{‘张三’:1},{‘作者’:用例个数}

五、pytest.fixture实现动态传参的几种方式:

5.1、用法描述:

#coding=utf-8
import pytest
 
#fixture传单个参数
 
@pytest.fixture()
def login(request):
    name=request.param #request.param就代表参数化的data里的每一个参数
    #print("账号是:{}".format(name))
    return name
 
data=["vince","jerry"]
 
@pytest.mark.parametrize(
    'login',
    data,
    indirect=True
)
def test_01(login):
    print("测试账号是:{}".format(login))
 
if __name__ == '__main__':
    pytest.main(["-s","test_param2.py"])
    
"""
注:
为了提高复用性,我们在写测试用例的时候,会用到不同的fixture,
比如:最常见的登录操作,大部分的用例的前置条件都是登录
假设不同的用例想登录不同的测试账号,
那么登录fixture就不能把账号写死,
需要通过传参的方式来完成登录操作

indirect=True 表示将参数'login'当做一个函数去执行(即参数名要和定义的fixture的函数名一致),而不是一个参数变量,并且将data当做参数传递给该函数
def test_01(login) ,这里的login是获取fixture返回的值
结果:
test_param2.py 测试账号是:vince
.测试账号是:jerry
.
"""

5.2、fixture传多个参数:

#coding=utf-8
import pytest
@pytest.fixture()
def logins(request):
    param=request.param
    #print("账号是:{}".format(name))
    return param
 
data=[{
    
    "username":"user1","pd":"123"},
      {
    
    "username":"user2","pd":"456"}
      ]
 
@pytest.mark.parametrize(
    'logins',
    data,
    indirect=True
)
def test_01(logins):
    print("测试用户名是:{0}———测试密码是:{1}".format(logins["username"],logins["pwd"]))
 
if __name__ == '__main__':
    pytest.main(["-s","test_param3.py"])
"""
结果:
test_param3.py 测试用户名是:user1———测试密码是:123
.测试用户名是:user2———测试密码是:456
.
"""

5.3、多个fixture叠加装饰器:

#coding=utf-8
import pytest
 
@pytest.fixture()
def input_user(request):
    user=request.param
    return user
 
@pytest.fixture()
def input_pwd(request):
    pwd=request.param
    return pwd 
 
data=[("user1","123"),
      ("user2","456")
      ]
@pytest.mark.parametrize('input_user',data,indirect=True)
@pytest.mark.parametrize('input_pwd',data,indirect=True)
def test_01(input_user,input_pwd):
    print("测试用户名是:{0}———测试密码是:{1}".format(input_user,input_pwd))
 
if __name__ == '__main__':
    pytest.main(["-s","test_param5.py"])
"""
结果:
test_param5.py 测试用户名是:('user1', '123')———测试密码是:('user1', '123')
.测试用户名是:('user2', '456')———测试密码是:('user1', '123')
.测试用户名是:('user1', '123')———测试密码是:('user2', '456')
.测试用户名是:('user2', '456')———测试密码是:('user2', '456')
.
"""

使用pytest.fixture()实行动态传参

先在conftest.py文件内创建pytest.fixture()装饰器,定义的函数中需要传参request
获取参数方式为:request.param

@pytest.fixture(scope='function', autouse=False)
def tax_prompt(request):
    cert_state = request.param['cert_state']
    prompt_error_msg = request.param['prompt_error_msg']
    rv = kelp_tax()
    rv.common_prompt(cert_state=cert_state, prompt_error_msg=prompt_error_msg)

传递参数方式:
@pytest.mark.parametrize(‘tax_prompt’, [
{‘cert_state’: kelp_tax().prompt_data(num=1)[0][1], ‘prompt_error_msg’: kelp_tax().prompt_data(num=1)[0][0]}],
indirect=True)
在这里插入图片描述

Python的switch case写法:

    @staticmethod
    def prompt_data(num):
        numbers = {
    
    
            0: [("testceshi", "46", "46-testceshi@test")],
            1: [("testceshi1", "41", "41-testceshi1@test")],
            2: [("testceshi2", "42", "42-testceshi2@test")],,
            3: [("testceshi3", "43", "43-testceshi@test")],,
            4: "",
            5: "",
            6: ""
        }
        return numbers.get(num, None)

一般情况下需要跟测试用例添加别名的方式:
@pytest.mark.parametrize(‘case_name’, [(‘test01’)], ids=[‘test01@test’])

猜你喜欢

转载自blog.csdn.net/weixin_52358204/article/details/126684165
今日推荐