Unittest二次开发实战

目录

  前言

  unittest.TestResult类简介

  TestResult类定制目标

  实现步骤

  测试结果summary格式规划

  单个用例结果格式规划

  用例tags和level的实现

  根据测试方法对象获取用例代码

  单个用例结果类的实现

  TestResult属性及初始化方法

  测试开始和测试结束

  用例开始和用例结束

  1. 重写恢复输出流方法

  2. 用例开始和结束方法

  用例结果注册

  测试本TestResult类方法

  其他函数和方法

  1. 用例状态列

  2. 获取平台信息

  3. 从异常中提取异常信息方法

  4. 从异常和已知异常中提取失败原因的方法


  前言

  Unittest是Python自带的自动化测试框架,提供了基本的控制结构和模型概念。

  由于Unittest功能较为基础,因此在实际框架实战中往往需要对其功能进行扩充。

  比如:

  ·生成HTML报告

  ·多线程并发(并且报告不混乱)

  ·自动重试出错用例

  ·为用例提供tags标签和level等级等,往往需要我们对Unittest框架进行二次开发和扩展,由于Unittest框架清晰的API,扩展和定制也非常方便。

  unittest.TestResult类简介

  TestResult类一般在TestRunner类中实例化,并穿梭于每个执行的测试套件和测试用例中用于记录结果。

  TestResult对象常用的属性有:

  ·stream:用于输出测试信息的IO流,一般是终端或文本文件。

  ·descriptions:描述信息。

  ·verbosity:显示详细级别。

  ·buffer:默认为False,用例中的print信息立即输出,buffer为True时将用例中的print信息统一收集并集中输出。

  ·tb_locals: 在报错异常信息中显示用例中的局部变量(即tackback_locals)。

  ·failfast:默认为False, 用例失败后继续运行,为True时,任何一条用例失败时立即停止。

  ·_mirrorOutput:是否重定向输出流状态标志unittest.TestResult类提供了以下几种方法:

      -运行开始/结束

        startTestRun: 执行开始时调用,参考unittest.TextTestRunner中的run方法。

        stopTestRun: 所有用例执行结束后调用

        startTest:单个用例执行开始时调用,参考unittest.TestCase类中的run方法。

        stopTest:单个用例执行结束后调用。

      -注册用例结果

        addSuccess:单个用例执行成功时调用,来注册结果,默认为空。

        addFailure:用例失败时在stopTest前调用。

        addError:用例异常时在stopTest前调用。

        addSkip:用例跳过时在stopTest前调用。

        addExpectedFailure:用例期望失败时在stopTest前调用。

        addUnexpectedSuccess:用例非期望成功时在stopTest前调用。

      -重定向和恢复系统输出流

        _setupStdout:重定向输出流,默认self.buffer为True时生效

        _restoreStdout:恢复系统输出流

  用例失败Failure和用例异常Error的区别:

  用例中的断言错误(期望结果和实际结果不一致)引发的AssertionError异常被视为用例失败,其他异常视为用例异常Error。

  ExpectedFailure和UnexpectedSuccess: 期望失败指我们期望这条用例执行失败,即用例失败了才是符合预期的,而没有失败即UnexpectedSuccess,这是一种反向用例,如果失败了其实是通过,而成功了反而是失败。

  TestResult类定制目标

  1. 在result中增加整体的运行开始时间start_at,持续时间duration和每条用例的开始时间,执行时间

  2. 存储用例中的print信息及异常信息,以供生成HTML使用

  3. 为已知异常提供失败原因

  4. 提供结构化和可序列化的summary和详情数据

  5. 探测每个用例code,以为审视用例代码提供方便

  6. 增加运行平台platform信息和运行时的环境变量信息

  7. 将print信息改为使用log记录,增加日志时间,方便追溯。

  8. 提供用例的更多的信息,如tags,level, id, 描述等信息。

  实现步骤

  测试结果summary格式规划

  测试结果result类提供一个summary属性,格式如下(参考了httprunner的summary格式):

name: result结果名称
  success: 整个测试结果是否成功
  stat: # 结果统计信息
    testsRun: 总运行数
    successes: 成功数
    failures: 失败数
    errors: 异常数
    skipped: 跳过的用例数
    expectedFailures: 期望失败数
    unexpectedSuccesses: 非期望成功数
  time:
    start_at: 整个测试开始时间(时间戳)
    end_at: 增高测试结束时间(时间戳)
    duration: 整个测试执行耗时(秒)
  platform:
    platform: 执行平台信息
    system: 执行操作系统信息
    python_version: Python版本信息
    # env: 环境变量信息(信息中可能包含账号等敏感信息)
  details:  # 用例结果详情
    - ... # 单个用例结果

  单个用例结果格式规划

# 执行前可获取的信息
  name: 用例名称或用例方法名
  id: 用例完整路径(模块-类-用例方法名)
  decritpion: 用例描述(用例方法docstring第一行)
  doc: 用例方法完整docstring
  module_name: 用例模块名
  class_name: 用例类名
  class_id: 用例类路径(模块-类)
  class_doc: 用例类docstring描述
  tags: 用例标签
  level: 用例等级
  code: 用例代码
  # 执行后可获取的信息
  time:
    start_at: 用例执行开始时间
    end_at: 用例结束时间
    duration: 用例执行持续时间
  status: 用例执行状态success/fail/error/skipped/xfail/xpass
  output: 用例中的print输出信息
  exc_info: 用例异常追溯信息
  reason: 用例跳过,失败,出错的原因

  读者也可以根据自己的需要添加其他额外的信息,如timeout用例超时时间配置,order用例执行顺序,images用例中的截图,link用例中的链接等信息。

  以上的tags和level通过在用例方法的docstring中注入"tag:smoke"及"level:1"等样式为用例添加标签和等级,然后配合定制的loader用例加载器去收集指定标签或等级的用例,下节会详细讲解。

  用例tags和level的实现

  每个框架都会有自己约定格式,这里我采用在docstring注入特定格式描述的方式为用例添加tags和level信息,用例格式如下。

import unittest
  class TestDemo(unittest.TestCase):
      def test_a(self):
          """测试a
          tag:smoke
          tag:demo
          level:1
          """
          print('测试a')

  对于每个用例对象,可以使用test._testMethodDoc来获取其完整的docstring字符串,然后通过正则匹配来匹配出用例的tags列表和level等级,实现方法如下。

import re
  TAG_PARTTEN = 'tag:(\w+)'
  LEVEL_PARTTEN = 'level:(\d+)'
  def get_case_tags(case: unittest.TestCase) -> list:
      """从用例方法的docstring中匹配出指定格式的tags"""
      case_tags = None
      case_doc = case._testMethodDoc
      if case_doc and 'tag' in case_doc:
          pattern = re.compile(TAG_PARTTEN)
          case_tags = re.findall(pattern, case_doc)
      return case_tags
  def get_case_level(case: unittest.TestCase):
      """从用例方法的docstring中匹配出指定格式的level""
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值