unittest 扩展TestCase类

本文介绍如何扩展unittest.TestCase以获取用例信息,如模块名、类名和docstring,并创建自定义TestResult类以记录这些信息。通过自定义startTest方法实现对测试用例详细描述的跟踪。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在编写用例的时候,我们可能会为用例添加一些描述信息以及使用标签用来区分冒烟测试和线上测试,或者在执行的时候获取用例名称、用例所在的模块等等。

unittest.TestCase 类已经为我们提供了一些可用的属性和方法,比如:

  • self._testMethodDoc 属性:获取测试用例的描述。unittest.TestCase自带属性。
  • self.shortDescription() 方法:获取第一行描述。unittest.TestCase自带方法。
  • self.id() 方法:用例完整路径,unittest.TestCase自带方法。

我们需要扩展一下,获取用例所在的模块、类名、用例所在类完整路劲以及类的docstring描述(后续可以增加开始时间、结束时间等属性)。

怎么做?

第一步:自定义一个测试类,包含所有所需要的属性。
第二步:自定义一个简单的TestResult类,继承unittest.TestResult并重写startTest()方法。

为什么重写startTest方法,就不能写其他的?
因为在执行TeatCase用例时,每条测试用例执行之前都会执行uniitest.TestResult类中的startTest方法,而我们只需要继承然后在重写就行了,会自动帮我们调用。

TestCase.run方法部分源码:

 def run(self, result=None):
        if result is None:
            result = self.defaultTestResult()
            startTestRun = getattr(result, 'startTestRun', None)
            stopTestRun = getattr(result, 'stopTestRun', None)
            if startTestRun is not None:
                startTestRun()
        else:
            stopTestRun = None

        result.startTest(self)   # 在执行用例之前会执行startTest()方法,参数self表示当前测试用例。

1. 自定义TestCase测试类

实例化的时候需要把测试用例对象传递进来,不然怎么知道测试用例的相关内容。

class MyTestCase():
    
  def __init__(self,test:unittest.TestCase) -> None:
      self.test = test   # 测试用例对象
      self.testMethodDoc = test._testMethodDoc  # 获取测试用例的描述
      self.id = test.id()    # 测试用例的路径
      self.shortDescription = test.shortDescription()  # 获取第一行描述
      self.module_name = test.__module__  # 用例所在模块名
      self.class_name = test.__class__.__name__  # 用例所在类名
      self.class_id = f'{test.__module__}.{test.__class__.__name__}'  # 用例所在类完整路径
      self.class_doc = test.__class__.__doc__  # 用例所在类docstring描述
    
    # 用于打印调试
    def __str__(self):
      return f"描述: {self.doc}\
              id: {self.id}\
              shortDescription: {self.shortDescription}\
              模块名称:{self.module_name}\
              类名:{self.class_name}\
              类的描述:{self.class_doc}"

__str__ 方法只是用于打印调试的,后续可以存为json或其他数据格式。

2. 自定义TestResult

需要继承uniitest.TestResult类并重写startTest方法。

class MyTestResult(unittest.TestResult):
    
  # 重写startTest方法
  def startTest(self,test):
    result=MyTestCase(test=test) # 实例化自定义的MyTestCase,将测试用例传递过去
    print(result)   # 输出打印一下
    
    # 线上最好是存放在result属性中,上面只适用于调试
    # test.result=MyTestCase(test=test) 
    
    super().startTest(test)  # 调用父类的startTest,保证其他功能不会丢失

参数test 表示当前测试用例实例对象。通过上面的TestCase.run()方法中的result.startTest(self) 这条语句传递。

3. 编写测试用例

class TestDemo(unittest.TestCase):
    """登录页面测试"""

    def test_1(self):
      """输入正确用户名和密码登录系统
        tag:冒烟测试
      """
      print('登录测试用例')
        

运行代码:

if __name__ == '__main__':

    test_load = unittest.defaultTestLoader
    case = test_load.loadTestsFromTestCase(TestDemo)  # 加载自己的测试用例的类

    runner = unittest.TextTestRunner(resultclass=MyTestResult)  # 使用自定义的报告
    runner.run(case)
    
    
-------------------
# 输出
# 类的描述:登录页面测试
# 类名:TestDemo
# 模块名称:__main__
# 描述: 输入正确用户名和密码登录系统
#        tag:冒烟测试
#        tag:线上测试
            
# id: __main__.TestDemo.test_1
# shortDescription: 输入正确用户名和密码登录系统 

全部测试代码:

import unittest



class TestDemo(unittest.TestCase):

    def test_1(self):
      """输入正确用户名和密码登录系统
        tag:冒烟测试
        tag:线上测试
      """
      print('第一个测试用例')




class MyTestCase():
    
  def __init__(self,test:unittest.TestCase) -> None:
      self.test = test   # 测试用例对象
      self.testMethodDoc = test._testMethodDoc  # 获取测试用例的描述
      self.id = test.id()    # 测试用例的路径
      self.shortDescription = test.shortDescription()  # 获取第一行描述
      self.module_name = test.__module__  # 用例所在模块名
      self.class_name = test.__class__.__name__  # 用例所在类名
      self.class_id = f'{test.__module__}.{test.__class__.__name__}'  # 用例所在类完整路径
      self.class_doc = test.__class__.__doc__  # 用例所在类docstring描述
    
    # 用于打印调试
    def __str__(self):
      return f"id: {self.id}\
              shortDescription: {self.shortDescription}\
              模块名称:{self.module_name}\
              类名:{self.class_name}\
              类的描述:{self.class_doc}"


class MyTestResult(unittest.TestResult):


  def startTest(self,test:unittest.TestCase):

    result=MyTestCase(test=test)
    print(result)
    super().startTest(test)




if __name__ == '__main__':

    test_load = unittest.defaultTestLoader
    case = test_load.loadTestsFromTestCase(TestDemo)


    runner = unittest.TextTestRunner(resultclass=MyTestResult)
    runner.run(case)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值