TestResult

测试结果类,用来处理测试用例或测试集执行过程中的所有信息并最终输出,比如代码错误、异常、断言失败、skip等等。所以如果想要增加一些个性化的输出,可以通过或者此类或者基类(TestResult),扩展HTMLTestRunner的大神就是扩展了基类TestResult,增加了一下几个重要的统计属性和重写了基类的一些方法。大家可以去阅读一下它的源码。

本来想讲TextTestResult的,但发现其实TextTestResult也是扩展了TestResult类的,所以干脆就直接分析TestResult了,我们先看一下基类提供了哪些方法可供我们扩展:

  1. printErrors
def printErrors(self):"Called by TestRunner after test run"

注释已经说明了,在测试用例执行完成后才应该被TestRuner调用,我们可以看一下这个方法在哪个地方有调用过:

我们可以看到有两处调用了这个方法:第一处我们可以不看,因为并不是unittest框架里面的,我们直接看第二处,可以看到是在TextTestRunner的run方法中有调用,我们看看是在run方法中的什么位置调用了这个方法

class TestRunner(unittest.TextTestRunner):def run(self, test, skipped):"Run the given test case or test suite."# Same as unittest.TextTestRunner.run, except that it reports# skipped tests.result = self._makeResult()startTime = time.time()test(result)stopTime = time.time()timeTaken = stopTime - startTimeresult.printErrors()self.stream.writeln(result.separator2)run = result.testsRunif _unavail: #skipped:

从代码我们可以看出,result.printErrors()方法是在test(result)之后才调用的,所以这符合printErrors方法的调用场景了吧

  1. startTest
def startTest(self, test):"Called when the given test is about to be run"self.testsRun += 1self._mirrorOutput = Falseself._setupStdout()

从注释说明中可以看出,此方法是在用例准备执行之前会被调用一次,我们还是来看一下此方法的调用情况,同样可以看到在TestCase类中的run方法中有调用此方法:

def run(self, result=None):orig_result = resultif result is None:result = self.defaultTestResult()startTestRun = getattr(result, 'startTestRun', None)if startTestRun is not None:startTestRun()self._resultForDoCleanups = resultresult.startTest(self)testMethod = getattr(self, self._testMethodName)if (getattr(self.__class__, "__unittest_skip__", False) or#省略下面的代码...

可以看出确实是在testMethod执行前调用了一次。

  1. startTestRun
def startTestRun(self):"""Called once before any tests are executed.See startTest for a method called before each test."""

跟startTest类似,用例执行之前调用,依然在TestCase类中的run方法可以看到,沿用上面startTest贴的run部分的代码,可以看到在执行startTest之前会去判断我们传入的result是否为None,如果为None,才会去初始化result,并判断result是否有startTestRun方法,如果有则执行startTestRun方法

  1. stopTest
def stopTest(self, test):"""Called when the given test has been run"""self._restoreStdout()self._mirrorOutput = False

在用例被执行之后才会执行此方法,依然还是在TestCase类中的run方法可以看到,不过此方法有两处调用,我们来看一下代码:

第一处调用:

def run(self, result=None):#省略startTestRun和startTest部分代码...testMethod = getattr(self, self._testMethodName)if (getattr(self.__class__, "__unittest_skip__", False) orgetattr(testMethod, "__unittest_skip__", False)):# If the class or method was skipped.try:skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')or getattr(testMethod, '__unittest_skip_why__', ''))self._addSkip(result, skip_why)finally:result.stopTest(self)returntry:success = False#省略下方代码...

我们可以看到,此段代码在分析TestCase类的时候讲过,这是在判断我们编写的TestCase类是否又被skip装饰,或者TestCase类中写的方法是否又被skip装饰,如果有,则会执行一次stopTest方法(result.stopTest(self))

第二处调用:

try:success = Falsetry:self.setUp()#省略了setUp处理部分...else:try:testMethod()#省略了testMethod的处理部分...cleanUpSuccess = self.doCleanups()success = success and cleanUpSuccessif success:result.addSuccess(self)
finally:result.stopTest(self)if orig_result is None:stopTestRun = getattr(result, 'stopTestRun', None)if stopTestRun is not None:stopTestRun()

我们可以看到,是在用例执行完成后,不管有没有什么错误或异常都会执行一次stopTest方法(result.stopTest(self))

  1. stopTestRun
def stopTestRun(self):"""Called once after all tests are executed.See stopTest for a method called after each test."""

在所有用例执行完成之后被调用。跟startTestRun类似,当我们传入的参数result为None时,才会去执行这个方法

针对上面第2-4个方法我们举一个例子瞧一瞧:

#unittest_prac.py
import unittest
import sys
#扩展TestResult
class MyTestResult(unittest.TestResult):def startTest(self, test):print('startTest')def startTestRun(self):print('startTestRun')def stopTest(self, test):print('stopTest')def stopTestRun(self):print('stopTestRun')class UnitTestCase(unittest.TestCase):def setUp(self):print("setup")def test01(self):print('test01')def tearDown(self):print('teardown')if __name__ == '__main__':result = MyTestResult(sys.stdout,'test result',1)testcase = UnitTestCase('test01')testcase.run(result) #注意此处我传入了result参数

执行之后我们看一下结果:

C:\software\PythonWorkspace>python unittest_prac.py\
startTest\
setup\
test01\
teardown\
stopTest

我们可以看到确实调用了startTest、stopTest,没有去调用startTestRun、stopTestRun符合我们的分析结果。

  1. 其他可扩展的方法:
    addFailure,addSuccess,addSkip,addExpectedFailure,addUnexpectedSuccess
    这几个方法是针对测试用例执行的结果处理:

    • addFailure:测试用例error的时处理
    • addSuccess:测试用例执行成功时处理
    • addSkip:测试用例跳过时处理
    • addExpectedFailure:测试用例执行跟预期结果不一样,不如assert断言
    • addUnexpectedSuccess:测试用例结果期望失败,但最后成功了。

这几个方法也都是可以在TestCase类的run方法中找到调用的地方,大家可以自己去试试分析一下

TestResult类分析差不多就到这里了,如果想了解怎么扩展,大家可以去阅读一下TextTestResult类的方法,或者阅读一下扩展HTMLTestRunner大神的代码HTMLTestRunner.py

unittest之TestResult类详解相关推荐

  1. unittest之TestSuite类详解

    TestSuite 测试套件类,如何理解测试套件这个概念呢,从它的类定义来看,可以理解为:多个独立的测试用例(test case)或者多个独立的测试套件(test suite,可以理解为子套件)可以构 ...

  2. OpenCV Mat类详解和用法(官网原文)

    参考文章:OpenCV Mat类详解和用法 我马克一下,日后更 官网原文链接:https://docs.opencv.org/3.2.0/d6/d6d/tutorial_mat_the_basic_i ...

  3. 转载:c+string类详解

    C++ string 类详解 </h1><div class="clear"></div><div class="postBod ...

  4. JDBC学习笔记02【ResultSet类详解、JDBC登录案例练习、PreparedStatement类详解】

    黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...

  5. JDBC学习笔记01【JDBC快速入门、JDBC各个类详解、JDBC之CRUD练习】

    黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...

  6. Android复习14【高级编程:推荐网址、抠图片上的某一角下来、Bitmap引起的OOM问题、三个绘图工具类详解、画线条、Canvas API详解(平移、旋转、缩放、倾斜)、矩阵详解】

    目   录 推荐网址 抠图片上的某一角下来 8.2.2 Bitmap引起的OOM问题 8.3.1 三个绘图工具类详解 画线条 8.3.16 Canvas API详解(Part 1) 1.transla ...

  7. Java中的Runtime类详解

    Java中的Runtime类详解 1.类注释 /**Every Java application has a single instance of class Runtime that allows ...

  8. [NewLife.XCode]实体类详解

    NewLife.XCode是一个有10多年历史的开源数据中间件,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含 ...

  9. basicdatasourcefactory mysql_Java基础-DBCP连接池(BasicDataSource类)详解

    Java基础-DBCP连接池(BasicDataSource类)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 实际开发中"获得连接"或"释放资源 ...

  10. JAVA的StringBuffer类详解

    JAVA的StringBuffer类详解 StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer ...

最新文章

  1. 使用指针做函数返回值
  2. flexbox布局_这是您可以使用FlexBox制作的5种布局
  3. 彼之蜜糖,吾之砒霜——聊聊软件开发中的最佳实践
  4. CCF-CSP 201703-1 试题名称: 分蛋糕
  5. 详解Linux2.6内核中基于platform机制的驱动模型 (经典)
  6. 关联规则挖掘算法_数据挖掘 | 关联规则分析
  7. 找新房子需要考虑的因素
  8. SAP 产品 UI 里的容器组件的概念和开发概述
  9. MIME协议及源邮件格式分析
  10. NLog源码解读——StringBuilderPool
  11. 1.4编程基础之逻辑表达式与条件分支 08 判断一个数能否同时被3和5整除
  12. 1b8c语言,C语言 - 王朝网络 - wangchao.net.cn
  13. Vue Element校验validate
  14. 如何在集合中巧用Where来查找相关元素
  15. 51nod3109 看电影
  16. 基于单片机at89s52的频率计设计c语言程序,基于AT89S52单片机的数字频率计课程设计.doc...
  17. qcloud_cos 的安装问题
  18. [原]产品经理和韦小宝
  19. 第一次作业:调查市场软件
  20. 理解pem pfx文件

热门文章

  1. 心情随笔(一):五月随笔满满的正能量
  2. 量化交易7-backtrader中支持的指标
  3. Java教学视频全集,活见久
  4. 自己动手打造mini型QQ
  5. java 匹配冒号,java 冒号参数 java 获取冒号后面的参数(正则)实现代码
  6. 数据挖掘工具---Spark SQL使用
  7. 人工智能轨道交通行业周刊-第14期(2022.9.12-9.18)
  8. 从3D ToF到智能座舱系统方案,英飞凌如何赋能未来出行?
  9. 敞开拥抱中国,荷兰光刻机巨头ASML丝毫不受“大火”影响
  10. 苹果手机linux系统版本号,Linux下查看系统版本号信息的方法(转)