您现在的位置是:首页 >技术交流 >pytest-编写插件网站首页技术交流

pytest-编写插件

Xiaoshuang_Cao 2024-06-17 11:28:16
简介pytest-编写插件

0 、文档

官方文档
中文文档

1、钩子函数分类

pytest中的钩子函数按功能一共分为6类:引导钩子,初始化钩子、用例收集钩子、用例执行钩子、报告钩子、调试钩子。

1.4 测试运行钩子

所有与运行测试相关的钩子都会接收一个pytest.Item对象。

  • pytest_runtestloop(session: Session) 调用以开始运行测试用例循环(用例收集完成后执行)。
  • pytest_runtest_protocol(item: Item, nextitem: Optional[Item])
    用于实现runtest_setup/call/teardown协议,包括收集异常和调用报告hook。

runtest 协议:

参数

  • Item:执行的用例
  • nextitem: 指定的下一条执行的测试用例

pytest默认的runtest协议为如下三个阶段:

1、设置阶段:
这个阶段主要执行用例:前置夹具

  • call = pytest_runtest_setup(item)
  • report = pytest_runtest_makereport(item, call)
  • pytest_runtest_logreport(report)
  • pytest_exception_interact(call, report)
    2、调用阶段
    这个阶段负责执行测试用例
  • call = pytest_runtest_call(item)
  • report = pytest_runtest_makereport(item, call)
  • pytest_runtest_logreport(report)
  • pytest_exception_interact(call, report)
    3、拆解阶段
    这个阶段主要执行用例:后置夹具
  • call = pytest_runtest_teardown(item, nextitem)
  • report = pytest_runtest_makereport(item, call)
  • pytest_runtest_logreport(report)
  • pytest_exception_interact(call, report)
  • pytest_runtest_logstart(nodeid: str, location: Tuple[str,
    Optional[int], str]) 在用例setup之前调用。
  • pytest_runtest_logfinish(nodeid: str, location: Tuple[str,
    Optional[int], str])在用例teardown之后调用。
  • pytest_runtest_setup(item: Item) 在用例执行之前调用。
  • pytest_runtest_call(item: Item) 调用以执行用例。
  • pytest_runtest_teardown(item: Item, nextitem: Optional[Item])
    在用例执行完成后调用。
  • pytest_runtest_makereport(item: Item, call: CallInfo[None])
    在runtest_setup/call/teardown之后执行,用于返回当前运行的结果。
  • pytest_pyfunc_call(pyfuncitem: Function) 调用基础测试功能。

2、本地编写插件:conftest.py

⚠️conftest.py文件可以有多个,并且只在当前package下生效)使用而无需导入,
推荐使用根目录下的conftest.py

from datetime import datetime

def pytest_configure():
    """
    配置加载完毕之后执行,所有测试用例执行之前执行
    """
    print(f"{datetime.now()} pytest开始执行")

def pytest_unconfigure():
    """
    配置卸载完毕之后执行,所有测试用例执行之后执行
    """
    print(f"{datetime.now()} pytest开始结束")

任意运行某条case:
在这里插入图片描述

3、外部插件:setuptools

  1. 根目录下创建setup.py文件
import setuptools
from setuptools import setup

setup(
    name="demo",  # 包名称
    author="cxs",
    description="用于替换pnc账号",  # 程序的简单描述
    long_description="",  # 程序的详细描述
    packages=setuptools.find_packages(),  # 需要处理的包目录(通常为包含 __init__.py 的文件夹)
    py_modules="",  # 需要打包的 Python 单文件列表
    setup_requires=["pytest-runner", ...],  # 指定运行 setup.py 文件本身所依赖的包
    tests_require=["pytest", ...],  # 在测试时需要使用的依赖包
)
  1. 新建一个package,暂叫demo,该package下新建download.py,内容如下:
from concurrent.futures import ThreadPoolExecutor
import requests


def download_all(func, sites):
    with ThreadPoolExecutor(max_workers=5) as executor:
        executor.map(func, sites)


def download(url):
    response = requests.get(url)
    print(response.status_code)
    return response


if __name__ == '__main__':
    sites = ["https://www.baidu.com/", "https://codetop.cc/home",
             "https://leetcode.cn/problemset/all/"]
    download_all(download, sites)
  1. 执行python3 setup.py sdist ; 会生成dist文件,该文件内有个.tar.gz的安装包,使用pip进行安装
    在这里插入图片描述
  2. python中即可使用此包
    在这里插入图片描述

4、实战

# -*- coding: utf-8 -*-
import pytest
import requests
import json
from _pytest.reports import TestReport
from datetime import datetime

data = {
    "passed": 0,
    "failed": 0,
}

url = "xxx"
headers = {
    "Content-Type": "application/json;charset=utf-8"
}


def pytest_runtest_logreport(report: TestReport):
 	"""
    统计用例执行成功/失败数
    """
    if report.when == "call":
        data[report.outcome] += 1


def pytest_collection_finish(session: pytest.Session):
    """
    用例加载完成之后执行,包含了全部用例
    """
    data["total"] = len(session.items)


def pytest_configure(config):
    """
    配置加载完毕之后执行,所有测试用例执行之前执行
    """
    data["start_time"] = datetime.now()


def pytest_unconfigure():
    """
    配置卸载完毕之后执行,所有测试用例执行之后执行
    """
    data["end_time"] = datetime.now()
    data["duration"] = data["end_time"] - data["start_time"]
    data["passed_rate"] = f'{data["passed"] / data["total"]:.2f}%'

    content = f"""
    测试时间:{data["end_time"]}
    用例数量:{data["total"]}
    执行时长:{data["duration"]}
    测试通过:{data["passed"]}
    测试失败:{data["failed"]}
    测试通过率:{data["passed_rate"]}
    
    测试报告地址:"https://www.osgeo.cn/pytest/reference.html#test-running-runtest-hooks"
    """

    d = {"text":"pytest自动化测试通知:",
         "attachments":
             [
                 {
                     "title": "Star Wars III",
                     "text": content,
                     "color": "#ffa500"
                 }
             ]
         }

    res = requests.post(url=url, data=json.dumps(d), headers=headers).json()

执行结果如图:
在这里插入图片描述

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。