16. Pytest常用插件:pytest-html生成简洁的测试报告

一、前言

我们都知道,在功能测试过程中,执行完测试用例后,最终要交付测试报告来直观的展示测试结果。自动化测试也是同样,脚本运行完之后,需要有一份测试报告对测试执行的结果进行统一的汇总展示,pytest给我们提供了两个自动生成测试报告的插件,安装即用。

本节课对pytest-html这个插件做讲解,这个插件生成的测试报告的特点是简洁明了。

二、学习目标

1.pytest-html插件安装

2.pytest-html插件应用

3.其他格式的测试报告

三、知识点

1.【pytest-html插件安装】

插件安装:

pip install pytest-html

2.【pytest-html插件应用】

测试用例示例代码:

#test_html_demo.py
from selenium import webdriver

url = "https://www.baidu.com"

class TestCase():
    '''测试类'''

    def setup(self):
        '''方法级前置操作-每条用例开始前初始化driver'''
        self.driver = webdriver.Chrome(executable_path=r"C:\Users\19344\Desktop\xdist_demo\chromedriver.exe")

    def teardown(self):
        '''方法级后置操作-每条用例结束后关闭浏览器'''
        self.driver.quit()

    def test_case_01(self):
        '''测试用例一'''
        self.driver .get(url)
        self.driver .find_element_by_name('wd').send_keys('Pthon')
        self.driver .find_element_by_id('su').click()
        print("用例执行成功!")

    def test_case_02(self):
        '''测试用例二'''
        self.driver .get(url)
        self.driver .find_element_by_name('wd').send_keys('Java')
        self.driver .find_element_by_id('su').click()
        print("用例执行成功!")

    def test_case_03(self):
        '''测试用例三'''
        self.driver .get(url)
        self.driver .find_element_by_name('wd').send_keys('go')
        self.driver .find_element_by_id('su').click()
        print("用例执行成功!")
  • 创建一个独立的报告

    命令行执行测试用例,增加参数:

    --html=report.html --self-contained-html
    
    示例:pytest --html=/report/auto_reports.html --self-contained-html test_html_demo.py
    

    说明:--html=report.html,指定报告的生成路径;--self-contained-html,可以是报告独立,复制给他人。

  • 自定义报告展示

    • 修改报告标题

      默认情况下,报告标题将是报告的文件名,您可以使用pytest_html_report_title钩子对其进行编辑:

      def pytest_html_report_title(report):
          report.title = "My very own title!"
      
    • 修改环境信息

      环境部分由提供pytest-metadata的插件,并且可以通过访问pytest_configurepytest_sessionfinish钩子函数修改环境信息。

      运行测试之前修改Environment部分,请使用:pytest_configure

      def pytest_configure(config):
          config._metadata["其他环境"] = "无网环境"
      

      运行测试修改Environment部分,请使用:pytest_sessionfinish

      import pytest
      
      @pytest.hookimpl(tryfirst=True)
      def pytest_sessionfinish(session, exitstatus):
          session.config._metadata["其他环境"] = "联网环境"
      

      请注意,在上面的示例中,@pytest.hookimpl(tryfirst=True)很重要,因为这确保pytest_sessionfinish 任何其他插件(包括pytest-htmlpytest-metadata)运行它们之前尽最大努力尝试运行您的 插件。如果省略此行,则环境表将不会更新,因为pytest_sessionfinish插件将首先执行,因此不会接受您的更改。

    • 修改摘要信息

      可以使用钩子编辑摘要部分pytest_html_results_summary

      from py.xml import html
      
      def pytest_html_results_summary(prefix, summary, postfix):
          prefix.extend([html.p("自动化测试工程师: 工具人")])
      
    • 修改报告结果

      可以通过为标题和行实施自定义挂钩来修改报告的列。下面的示例conftest.py添加了一个带有测试函数 docstring 的 description 列,添加了一个可排序的时间列,并删除了 links 列:

      from datetime import datetime
      from py.xml import html
      import pytest
      
      def pytest_html_results_table_header(cells):
          cells.insert(2, html.th("Description")) #2代表列的索引,如0,1,2
          cells.insert(1, html.th("Time", class_="sortable time", col="time"))
          cells.pop()
      
      def pytest_html_results_table_row(report, cells):
          if hasattr(report,'description'):
              cells.insert(2, html.td(report.description))
              cells.insert(1, html.td(datetime.utcnow(), class_="col-time"))
              cells.pop()
          else:
              print("插入测试报告报错:{}".format(report.longreprtext))
      
      @pytest.hookimpl(hookwrapper=True)
      def pytest_runtest_makereport(item, call): #item是所有的测试用例,call是测试结果
          outcome = yield
          report = outcome.get_result() #获取测试报告对象,为下面自定义测试报告做铺垫
          report.description = str(item.function.__doc__) #修改描述信息,获取测试用例的__doc__,也就是测试函数的注释
      
    • 额外内容

      可以通过在报告对象上创建“额外”列表来向 HTML 报告添加详细信息。以下是可以添加的额外内容类型:

      类型 例子
      原始 HTML extra.html('<div>Additional HTML</div>')
      JSON extra.json({'name': 'pytest'})
      纯文本 extra.text('Add some simple Text')
      网址 extra.url('http://www.example.com/')
      图片 extra.image(image, mime_type='image/gif', extension='gif')
      图片 extra.image('/path/to/file.png')
      图片 extra.image('http://some_image.png')

      注意:从文件添加图像时,路径可以是绝对路径,也可以是相对路径。

      还有几种图像格式的方便类型:

      图像格式 例子
      PNG extra.png(image)
      JPEG格式 extra.jpg(image)
      SVG extra.svg(image)

      这里介绍一下如何从测试报告中自定义插入图片,在自动化测试中可以展示失败的截图,方便定位问题:

      from selenium import webdriver
      driver = webdriver.Chrome(executable_path=r"C:\Users\19344\Desktop\xdist_demo\chromedriver.exe")
      
      @pytest.hookimpl(hookwrapper=True)
      def pytest_runtest_makereport(item):
          """
          当测试失败的时候,自动截图,展示到html报告中
          :param item:
          """
          pytest_html = item.config.pluginmanager.getplugin('html')
          outcome = yield
          report = outcome.get_result()
      	# 获取调用结果的测试报告,返回一个report对象, report对象的属性包括when(steup, call, teardown三个值)、nodeid(测试用例的名字)、		outcome(用例的执行结果,passed,failed)
          extra = getattr(report, 'extra', [])
      	#以上是固定写法,目的是为了获取report对象,下面对report做自定义修改
          if report.when == 'call' or report.when == "setup": #先判断用例执行到哪一阶段
              xfail = hasattr(report, 'wasxfail')
              if (report.skipped and xfail) or (report.failed and not xfail): #判断用例如果是失败的
                  file_name = report.nodeid.replace("::", "_")+".png"
                  screen_img = _capture_screenshot()
                  if file_name:
                      html = '<div><img src="data:image/png;base64,%s" alt="screenshot" style="width:600px;height:300px;" ' \
                             'οnclick="window.open(this.src)" align="right"/></div>' % screen_img
                      extra.append(pytest_html.extras.html(html))
              report.extra = extra
      
      def _capture_screenshot():
          '''
          截图保存为base64,展示到html中
          :return:
          '''
          return driver.get_screenshot_as_base64()
      
      

      说明:测试用例的测试步骤是执行完常规钩子函数返回的report报告有个属性叫report.when,先执行when=’setup’ 返回setup 的执行结果; 然后执行when=’call’ 返回call 的执行结果;最后执行when=’teardown’返回teardown 的执行结果。

      示例测试用例:

      from conftest import driver
      
      url = "https://www.baidu.com"
      
      class TestCase():
          '''测试类'''
      
          def test_case_01(self):
              '''测试用例一'''
              driver.get(url)
              driver.find_element_by_name('wd').send_keys('Pthon')
              print("输入Python成功")
              driver.find_element_by_id('su').click()
              print("点击百度一下成功")
              assert False
      

3.【其他格式的测试报告】

  • 生成JunitXML 格式的测试报告

    在CMD中切换到该测试用例路径下,执行指令:

    #其中report\auto_report.xml为生成log的路径
    pytest -v test_demo.py --junitxml=report/auto_report.xml
    
  • 生成result log格式的测试报告(新版本的pytest可能没有了)

    在CMD中切换到该测试用例路径下,执行指令:

    pytest -v test_demo.py --result-log=report/log.txt
    
  • 生成在线测试报告

    pytest -v test_demo.py --pastebin=all
    
posted @ 2023-01-17 10:33  测开星辰  阅读(66)  评论(0编辑  收藏  举报