Pytest学习教程_测试报告生成pytest-html(三)

前言

pytest-html 是一个用于生成漂亮的 HTML 测试报告的 pytest 插件。它可以方便地将 pytest 运行的测试结果转换为易于阅读和理解的 HTML 报告,提供了丰富的测试结果展示功能和交互性。

一、安装

# 版本查看命令
pytest版本: pytest --version
pytest-html版本: pip show pytest-html

# 安装指定版本(在V3.2.0版本报告中,中文显示乱码,目前不知道什么原因)
卸载pytest-html: pip uninstall pytest-html
安装指定版本: pip install pytest-html==3.1.1

# 当前演示环境版本
pytest版本:7.4.0
pytest-html版本:3.1.1

二、生成方法

1、生成默认报告

# test_run.py
import pytest


def test_A():
    '''执行A测试用例'''
    assert True


def test_B():
    '''执行B测试用例'''
    assert True


def test_C():
    '''执行C测试用例'''
    assert False


if __name__ == '__main__':
    pytest.main([
        'test_run.py', '-v', '--html=./directory/report.html',
        '--self-contained-html'
    ])
# --html=./directory/report.html (在当前directory目录下生成普通HTML报告,CSS是独立的)
# --self-contained-html(合并CSS的HTML报告)
  • 默认报告样式:

在这里插入图片描述
2、修改报告样式
  在测试用例的同目录下新建conftest.py文件,并复制以下内容:

# conftest.py
import pytest
from py._xmlgen import html
from time import strftime


# 一、修改测试报告标题
# 使用带有`optionalhook=True`的`hookimpl`装饰器
@pytest.hookimpl(optionalhook=True)
def pytest_html_report_title(report):
    # 设置报告标题
    report.title = "自动化测试报告"


# 二、修改Summary部分的信息
@pytest.mark.parametrize
def pytest_html_results_summary(prefix, summary, postfix):
    # 添加自定义的段落信息
    prefix.extend([html.p("所属部门:测试组")])
    prefix.extend([html.p("测试人员:张三")])


# 三、修改Results部分的信息
def pytest_html_results_table_header(cells):
    # 在索引1处插入“描述”列标题
    cells.insert(1, html.th('Description'))
    # 在索引2处插入“任务完成时间”列标题
    cells.insert(2, html.th('TaskCompleteTime'))
    # 删除最后一列“link列”
    cells.pop(-1)


def pytest_html_results_table_row(report, cells):
    # 在索引1处插入报告的描述信息
    cells.insert(1, html.td(report.Description))
    # 在索引2处插入报告的任务完成时间信息
    cells.insert(2, html.td(report.TaskCompleteTime))
    # 删除最后一列“link”
    cells.pop(-1)


@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
    outcome = yield
    report = outcome.get_result()
    # 将报告的描述信息设置为测试项的文档字符串
    report.Description = str(item.function.__doc__)
    # 将报告的任务完成时间设置为当前时间
    report.TaskCompleteTime = str(strftime("%Y-%m-%d %H:%M:%S"))
  • 运行test_run.py生成报告:

在这里插入图片描述
3、用例失败自动截图

# test_run.py
import pytest
from selenium import webdriver
from time import sleep


@pytest.fixture(scope="function")
def setup_browser():
    """
    设置和关闭浏览器的测试夹具
    """
    driver = webdriver.Chrome()
    driver.maximize_window()

    yield driver  # 返回driver对象供测试使用

    driver.quit()  # 测试结束后关闭浏览器


@pytest.fixture(params=[("https://www.baidu.com/", "百度一下,你就知道"),
                        ("https://www.csdn.net/", "CSDN - 专业开发者社区"),
                        ("https://www.youdao.com/", "网易有道失败")],
                ids=["百度网址验证用例", "CSDN网址验证用例", "网易网址验证用例"])
def parametrize_search_engine(request):
    """
    参数化的搜索引擎测试夹具
    """
    return request.param


def test_navigation(setup_browser, parametrize_search_engine):
    """
    测试网页是否能正常打开,并显示内容
    """
    driver = setup_browser  # 获取浏览器驱动对象
    keyword, engine = parametrize_search_engine
    # 请求网址
    driver.get(keyword)
    # 等待2秒
    sleep(2)

    assert driver.title == engine  # 检查打开的页面标题是否与期望结果一致


if __name__ == '__main__':
    pytest.main([
        'test_run.py', '-v', '--html=./directory/report.html',
        '--self-contained-html'
    ])
# conftest.py
import pytest
import pyautogui
import base64
import io


@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item):
    '''
    pytest_runtest_makereport是一个钩子函数,用于在每个测试用例执行完成后生成测试报告
    item参数表示当前正在执行的测试用例
    '''

    # 获取pytest-html插件实例,用于生成HTML格式的测试报告
    pytest_html = item.config.pluginmanager.getplugin('html')

    # yield语句暂停函数的执行,并返回给调用方一个值(被yield关键字后面的值)
    # 当函数恢复执行时,outcome变量将接收到yield语句后面yielded的值
    outcome = yield

    # 从outcome中获取测试用例的结果报告
    report = outcome.get_result()

    # 获取report对象的extra属性,如果不存在则返回一个空列表
    extra = getattr(report, 'extra', [])

    # 如果测试用例是在"call"或"setup"阶段执行时
    # 也就是在测试用例被调用执行或设置阶段出现问题时
    if report.when == 'call' or report.when == 'setup':

        # 检查报告对象中是否有wasxfail属性,表示测试用例是否被标记为预期失败(xfail)
        xfail = hasattr(report, 'wasxfail')

        # 如果测试用例被跳过且是预期失败,或者测试用例执行失败且不是预期失败
        if (report.skipped and xfail) or (report.failed and not xfail):

            # 使用pyautogui库进行屏幕截图
            screenshot = pyautogui.screenshot()

            # 创建一个BytesIO对象,用于存储屏幕截图的二进制数据
            screenshot_buffer = io.BytesIO()

            # 将屏幕截图保存到BytesIO对象中,格式为PNG
            screenshot.save(screenshot_buffer, format='PNG')

            # 使用base64对屏幕截图的二进制数据进行编码,得到base64编码后的字符串
            screenshot_base64 = base64.b64encode(
                screenshot_buffer.getvalue()).decode('utf-8')

            # 构建一个HTML的div元素,其中包含一个img元素,用于显示屏幕截图
            # 图片源使用base64编码的字符串,点击图片时可以在新窗口打开原始截图
            # div元素的样式设置了图片的宽度和高度,并将其右对齐
            html = '<div><img src="data:image/png;base64,{}" alt="screenshot" style="width:500px;height:260px;" ' \
                   'οnclick="window.open(this.src)" align="right"/></div>'.format(screenshot_base64)

            # 将构建的HTML字符串添加到extra列表中,作为测试报告的额外信息
            extra.append(pytest_html.extras.html(html))

        # 将extra列表设置为报告对象report的extra属性,更新测试报告的额外信息
        report.extra = extra
  • 运行test_run.py生成报告:
    在这里插入图片描述
    4、完整代码
# conftest.py
import pytest
from py._xmlgen import html
from time import strftime
import pyautogui
import base64
import io


# 一、修改测试报告标题
@pytest.hookimpl(optionalhook=True)
def pytest_html_report_title(report):
    report.title = "自动化测试报告"


# 二、修改Summary部分的信息
@pytest.mark.parametrize
def pytest_html_results_summary(prefix, summary, postfix):
    prefix.extend([html.p("所属部门:测试组")])
    prefix.extend([html.p("测试人员:张三")])


# 三、修改Results部分的信息,并自动截取错误截图
def pytest_html_results_table_header(cells):
    cells.insert(1, html.th('Description'))
    cells.insert(2, html.th('TaskCompleteTime'))
    cells.pop(-1)


def pytest_html_results_table_row(report, cells):
    cells.insert(1, html.td(report.Description))
    cells.insert(2, html.td(report.TaskCompleteTime))
    cells.pop(-1)


@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item):
    pytest_html = item.config.pluginmanager.getplugin('html')
    outcome = yield
    report = outcome.get_result()

    report.Description = str(item.function.__doc__)
    report.TaskCompleteTime = str(strftime("%Y-%m-%d %H:%M:%S"))

    extra = getattr(report, 'extra', [])
    if report.when == 'call' or report.when == 'setup':
        xfail = hasattr(report, 'wasxfail')
        if (report.skipped and xfail) or (report.failed and not xfail):
            screenshot = pyautogui.screenshot()
            screenshot_buffer = io.BytesIO()
            screenshot.save(screenshot_buffer, format='PNG')
            screenshot_base64 = base64.b64encode(
                screenshot_buffer.getvalue()).decode('utf-8')
            html = '<div><img src="data:image/png;base64,{}" alt="screenshot" style="width:500px;height:260px;" ' \
                   'οnclick="window.open(this.src)" align="right"/></div>'.format(screenshot_base64)
            extra.append(pytest_html.extras.html(html))
        report.extra = extra

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/61656.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes 整体架构介绍

架构图 Kubernetes 主要由以下几个核心组件组成&#xff1a; etcd 保存了整个集群的状态&#xff1b;kube-apiserver 提供了资源操作的唯一入口&#xff0c;并提供认证、授权、访问控制、API 注册和发现等机制&#xff1b;kube-controller-manager 负责维护集群的状态&#xf…

SpringBoot 升级内嵌Tomcat

SpringBoot 更新 Tomcat 最近公司的一个老项目需要升级下Tomcat&#xff0c;由于这个项目我完全没有参与&#xff0c;所以一开始我以为是一个老的Tomcat项目&#xff0c;升级它的Tomcat依赖或者是Tomcat容器镜像&#xff0c;后面发现是一个SpringBoot项目&#xff0c;升级的是…

Rpc异步日志模块

Rpc异步日志模块作用 在一个大型分布式系统中&#xff0c;任何部署的分布式节点都可能发生崩溃&#xff0c;试想如果用普通的办法&#xff0c;即先排查哪个节点down掉了&#xff0c;找到down掉的节点后采取调试工具gdb调试该节点&#xff0c;进而排查宕机的原因。这中排查方法…

考研408 | 【计算机网络】物理层

导图&#xff1a; 一、通信基础 基本概念&#xff1a; 物理层接口特性&#xff1a;物理层解决如何在连接各种计算机的传输媒体上传输数据比特流&#xff0c;而不是指具体的传输媒体。 物理层主要任务&#xff1a;确定与传输媒体接口有关的一些特性 典型的数据通信模型 数据通…

PLL 的 verilog 实现

锁相环&#xff08;PLL&#xff09;是一种常用的频率、相位追踪算法&#xff0c;在信号解调、交流并网等领域有着广泛的应用。本文对全数字锁相环的原理进行介绍&#xff0c;随后给出 verilog 实现及仿真。 PLL 锁相原理 锁相环结构如下图所示&#xff0c;主要由鉴相器、环路滤…

4.DNS和负载均衡

文章目录 coreDNS概念部署croeDNS测试 kubernetes多master集群结构master节点部署 负载均衡配置部署nginx做四层反向代理安装高可用 keepalivednginx监控脚本修改k8s中组件的配置文件 coreDNS 概念 coreDNS是kubernetes的默认DNS实现。可以为集群中的service资源创建一个资源名…

【Unity3D】消融特效

1 前言 选中物体消融特效中基于 Shader 实现了消融特效&#xff0c;本文将基于 Shader Graph 实现消融特效&#xff0c;两者原理一样&#xff0c;只是表达方式不同&#xff0c;另外&#xff0c;选中物体消融特效中通过 discard 丢弃片元&#xff0c;本文通过 alpha 测试丢弃片元…

idea 2023 新版ui中git的相关操作

前两个月换了新电脑&#xff0c;下了最新版的idea发现可以切换一套新的ui了 切换新ui肯定不太习惯&#xff0c;很多操作都得重新摸索一下 在这里记录几个git相关的操作 忽略我下面截图中当前项目是js的后端项目…… 切换ui 首先说一下怎么切换新旧版ui&#xff0c;我这里就…

Spring很常用的@Conditional注解的使用场景和源码解析

介绍 今天要分享的是Spring的注解Conditional&#xff0c;Conditional是一个条件注解&#xff0c;它的作用是判断Bean是否满足条件&#xff0c;如果满足条件&#xff0c;则将Bean注册进IOC中&#xff0c;如果不满足条件&#xff0c;则不进行注册&#xff0c;这个注解在SpringB…

Three.js给场景添加背景颜色,背景图,全景图

1.相关API的使用&#xff1a; 1 THREE.Color &#xff08;用于创建和表示颜色&#xff09; 2. THREE.TextureLoader&#xff08;用于加载和处理图片纹理&#xff09; 3. THREE.SphereGeometry&#xff08;用于创建一个球体的几何体&#xff09; 4. THREE.Mesh&#xff08;用…

chapter13:springboot与任务

Spring Boot与任务视频 1. 异步任务 使用注解 Async 开启一个异步线程任务&#xff0c; 需要在主启动类上添加注解EnableAsync开启异步配置&#xff1b; Service public class AsyncService {Asyncpublic void hello() {try {Thread.sleep(3000);} catch (InterruptedExcept…

Tuxera NTFS2023Mac强大的Mac读写工具

Mac用户在使用NTFS格式移动硬盘时&#xff0c;会遇到无法写入硬盘的情况。要想解决无法写入的问题&#xff0c;很多人选择使用Mac读写软件。面对市面上“众多”的读写硬盘软件&#xff0c;用户应该怎么选择呢&#xff1f;初次接触移动硬盘的伙伴可能不知道移动硬盘怎么和电脑连…

git【潦草学习】

初始配置git 查询版本号 初次使用git前配置用户名与邮箱地址 git config --global user.name "your name" git config --global user.name "your email" git config -l 发现最后两行多出了用户名和邮箱&#xff0c;说明配置成功

【SpringCloud】Feign远程调用

先来看我们以前利用RestTemplate发起远程调用的代码&#xff1a; String url "http://userservice/user/" order.getUserId(); User user restTemplate.getForObject(url, User.class);存在下面的问题&#xff1a; • 代码可读性差&#xff0c;编程体验不统一 • …

外国机构在中国境内提供金融信息服务23家许可名单

6月30日&#xff0c;国家互联网信息办公室公布23家外国&#xff08;境外&#xff09;机构在中国境内提供金融信息服务许可名单&#xff0c;如下&#xff1a;

CCL 2023 电信网络诈骗案件分类评测-第一名方案

1 任务内容 1.1 任务背景 2022年12月1日起&#xff0c;新出台的《反电信网络诈骗犯罪法》正式施行&#xff0c;表明了我国治理当前电信网络诈骗乱象的决心。诈骗案件分类问题是打击电信网路诈骗犯罪过程中的关键一环&#xff0c;根据不同的诈骗方式、手法等将其分类&#xff…

PyTorch深度学习实战(9)——学习率优化

PyTorch深度学习实战&#xff08;9&#xff09;——学习率优化 0. 前言1. 学习率简介2. 梯度值、学习率和权重之间的相互作用3. 学习率优化实战3.1 学习率对缩放后的数据集的影响3.2 学习率对未缩放数据集的影响 小结系列链接 0. 前言 学习率( learning rate )是神经网络训练中…

Spring Data JPA源码

导读: 什么是Spring Data JPA? 要解释这个问题,我们先将Spring Data JPA拆成两个部分&#xff0c;即Sping Data和JPA。 从这两个部分来解释。 Spring Data是什么? 摘自: https://spring.io/projects/spring-data Spring Data’s mission is to provide a familiar and cons…

压力测试与测试工具jmeter的介绍

目录 一、性能指标 二、jmeter &#xff08;一&#xff09;JMeter 安装 &#xff08;二&#xff09;JMeter 压测示例 1、添加线程组 2、添加 HTTP 请求 3、添加监听器 4、启动压测&查看分析结果 &#xff08;三&#xff09;JMeter Address Already in use 错误解决 压力测…

【ChatGPT 指令大全】怎么使用ChatGPT写履历和通过面试

目录 怎么使用ChatGPT写履历 寻求履历的反馈 为履历加上量化数据 把经历修精简 为不同公司客制化撰写履历 怎么使用ChatGPT通过面试 汇整面试题目 给予回馈 提供追问的问题 用 STAR 原则回答面试问题 感谢面试官的 email 总结 在职场竞争激烈的今天&#xff0c;写一…
最新文章