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

news2025/1/15 17:38:03

前言

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.coloradmin.cn/o/822599.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PHP代码审计--理论

提供资料&#xff1a; php 基础 : https://www.runoob.com/php/php-tutorial.html php是什么&#xff1f; PHP 是服务器端脚本语言。 首先在学习PHP前需要对HTML 和CSS有一定的认识 PHP 能做什么&#xff1f; PHP 可以生成动态页面内容PHP 可以创建、打开、读取、写入、关…

InnoDB引擎底层逻辑讲解——架构之磁盘架构

1. System Tablespaces区域 系统表空间是change buffer&#xff08;更改缓冲区&#xff09;的存放区域&#xff0c;这是在8.0之后重新规划的&#xff0c;在5.x版本的时候&#xff0c;系统表空间还会存放innodb的数据字典undolog日志等信息&#xff0c;在8.0之后主要主要存放更…

【程序猿周末如何才能获得充分的休息】

工作以后常常容易感到疲于奔命&#xff0c;即使在周末也没有得到高质量的休息。打工人/学生党如何过周末&#xff1f;你有哪些延长周末和下班时间的好方法吗&#xff1f;你可以选择从以下几个方向谈谈你的想法和观点。 一&#xff1a;周末的时间规划 周末双休 二&#xff1a;提…

springboot 自定义starter项目Unable to read meta-data for class

springboot 自定义starter包&#xff0c;在项目中引用&#xff0c;启动报错。 org.springframework.boot.SpringApplication [SpringApplication.java:843] Application run failed java.lang.IllegalStateException: Unable to read meta-data for class com.hxg.mail.spring…

找好听的配乐、BGM就上这6个网站,免费商用。

推荐几个音乐素材网站给你&#xff0c;各种类似、风格的都有&#xff0c;而且免费下载&#xff0c;还可以商用&#xff0c;建议收藏起来~ 菜鸟图库 https://www.sucai999.com/audio.html?vNTYxMjky 站内有上千首音效素材&#xff0c;网络流行的音效素材这里都能找到&#xf…

一起学算法(双指针篇)

概念&#xff1a; 通过两个指针&#xff0c;不断的调整区间&#xff0c;从而求出问题最优解的算法就叫“尺取法”&#xff0c;由于利用的是两个双指针&#xff0c;所以也叫作“双指针”算法&#xff0c;这里的“尺”的含义&#xff0c;主要是因为这类问题&#xff0c;最终要求解…

刷题笔记 day2

力扣 1089 复写零 思路&#xff1a;双指针 第一步&#xff1a;利用指针 cur 去记录最后一位要复写的数 &#xff0c; 利用指针 dest 指向最后一位数所要复写的位置&#xff1b; 实现过程&#xff1a;最开始 cur 指向0&#xff0c;dest 指向 -1 &#xff0c; 当arr[cur] ! …

高并发与性能优化的神奇之旅

作为公司的架构师或者程序员&#xff0c;你是否曾经为公司的系统在面对高并发和性能瓶颈时感到手足无措或者焦头烂额呢&#xff1f;笔者在出道那会为此是吃尽了苦头的&#xff0c;不过也得感谢这段苦&#xff0c;让笔者从头到尾去探索&#xff0c;找寻解决之法。 目录 第一站&…

深入理解设计模式之模板方法模式

深入理解设计模式之模板方法模式 什么是模板方法模式&#xff1f; 模板方法模式是一种行为型设计模式&#xff0c;它定义了一个算法的骨架&#xff0c;将一些步骤的具体实现延迟到子类中。模板方法模式通过将算法的通用部分抽象出来&#xff0c;以模板方法的形式提供给子类&am…

express学习笔记7 - docker跟mysql篇

安装Docker和Navicat Docker 进官⽹https://docs.docker.com/get-docker/ 选择机型安装即可。 Navicat&#xff08;也可以在网上找个破解版本&#xff09; 进官⽹https://www.navicat.com/en/products/navicat-premium 安装完之后连接新建⼀个数据库连接 然后再⾥⾯新建⼀个数…

【编程语言 · C语言 · 通讯录管理系统】

【编程语言 C语言 通讯录管理系统】https://mp.weixin.qq.com/s?__bizMzg4NTE5MDAzOA&mid2247491539&idx1&sn02173f15bbff6d5f01a3426a1ecf7120&chksmcfade32af8da6a3cb187ecde99fe0519c4d67ef05488754ab2196fab0915262c260ccc68b304&payreadticketHEsQ…

MacOS使用brew如何下载Nginx

首先&#xff0c;第一步切换源&#xff1a; 切换 brew.git 仓库地址&#xff1a; cd "$(brew --repo)" git remote set-url origin https://mirrors.aliyun.com/homebrew/brew.git 替换 homebrew-core.git 仓库地址: cd "$(brew --repo)/Library/Taps/home…

无线蓝牙耳机有什么值得耳机买的?几款值得买的口碑品牌盘点

蓝牙耳机是一种无线耳机&#xff0c;其通过蓝牙技术与其他设备进行连接&#xff0c;例如手机、电脑、平板电脑等。蓝牙耳机使得用户可以在不受线缆限制的情况下享受音频体验&#xff0c;而且还可以方便地进行通话&#xff0c;目前市场上有许多不同种类和品牌的蓝牙耳机&#xf…

大厂原来都这么使用IDEA远程调试的!

远程调试是一项重要的技术&#xff0c;特别是对于使用IDEA开发的开发者来说。在本篇技术博客中&#xff0c;我们将探讨如何使用IDEA进行远程调试。 1 IDEA 配置 首先&#xff0c;我们需要确保我们的开发环境已经准备就绪。我们需要在远程服务器上安装并配置好调试器&#xff…

【福建事业单位-语言理解】02 细节判断-标题填入-词句理解

【福建事业单位-语言理解】02 细节判断-标题填入-词句理解 一、细节判断题细节判断优先验证原则总结 二、标题填入题总结 三、词句理解题3.1 代词指代实词理解句子理解总结 一、细节判断题 如果文段长难怪绕&#xff0c;就先看选项&#xff0c;反之一样。 面对温和的可能性表述…

java集成短信服务 测试版 qq邮箱简单思路

java集成短信服务 注册一个帐号 使用的是容联云&#xff0c;百度搜一下官网 用手机注册一个帐号就行&#xff0c;免费体验不需要认证 注册后会有八块钱送&#xff0c;可以使用免费的给自己设置三个固定手机号发送短信&#xff0c;不需要认证。 此页面的 三个信息需要在代码中…

免驱触摸屏为啥在我的Linux上驱动不起来

背景&#xff1a; 某宝上买了个HDMI接口的触摸屏&#xff0c;用树莓派驱动没啥问题&#xff0c;但是用在我自己定制的Linux系统上&#xff0c;咋都不好使&#xff0c;咨询商家&#xff0c;商家说触摸屏的芯片是GT911&#xff0c;芯片是I2c协议&#xff0c;触摸屏上是usb接口的…

《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(19)-Fiddler精选插件扩展安装,将你的Fiddler武装到牙齿

1.简介 Fiddler本身的功能其实也已经很强大了&#xff0c;但是Fiddler官方还有很多其他扩展插件功能&#xff0c;可以更好地辅助Fiddler去帮助用户去开发、测试和管理项目上的任务。Fiddler已有的功能已经够我们日常工作中使用了&#xff0c;为了更好的扩展Fiddler&#xff0c…

这9个UI设计工具一定码住!非常好用

对于设计师来说&#xff0c;好用的UI设计工具无疑会对设计工作起到事半功倍的作用&#xff0c;今天本文与大家分享9个好用的UI设计工具&#xff0c;一起来看看吧&#xff01; 1、即时设计 即时设计是一个能在网页中直接使用&#xff0c;且支持团队协作的国产UI设计工具&#…

你的shell脚本存在安全问题吗?

更多技术资料&#xff0c;请关注微信公众号“运维之美” 信息安全对于线上环境显得尤为重要&#xff0c;shell脚本的代码中可能经常会引用到密码等变量进行赋值等场景&#xff0c;但是在使用的过程中可能会导致环境的登录信息泄露&#xff0c;导致安全隐患&#xff0c;那么如何…