unittest测试框架-测试方法执行方式有哪些(带看源码)

接着上一篇讲到测试方法的执行。unittest测试框架有几种运行方式呢?我学到的是六种。如果你看源码能力足够的话(我是看完后头就疼了,能力有限,但还好大致搞清楚了),点开main.py就发现,都写在初始化方法里了。入参这里给大家做个简单的解释。
按住ctrl键,点击main
在这里插入图片描述
在这里插入图片描述
defaultTest=None, 待测试用例的名称,默认是所有,可以运行指定测试用例,传入形式可以是字符串或者是序列,例如:defaultTest=[“类.测试用例”]
testRunner=None, 测试运行器,TextTestRunner 默认运行出来的结果是文本格式
testLoader=loader.defaultTestLoader, 指定使用默认的测试用例加载器
verbosity=1, 类似于命令行-v, 0(简洁的模式),1(正常的模式),2(详细的模式)
以下参数不重要,了解即可。
exit=True, 是否在用例完成后结束python程序
failfast=None, 失败的时候是否终止测试
argv=None, 接受外部参数
catchbreak=None,
buffer=None, 是否捕获输出流
warnings=None 是否显示警告信息
tb_locals=False

接下来就简单举例说明
创建一个jx_01_case.py文件,内容如下:

import unittest

class BusinessCase(unittest.TestCase):

    def test_01(self):
        print("测试用例1执行成功")

    def test_02(self):
        print("测试用例2执行成功")

    def test_03(self):
        print("测试用例3执行成功")

    def test_10(self):
        print("测试用例10执行成功")

1.第一种运行方式。所有用例都执行,这也是最基础的。

if __name__ == "__main__":
    unittest.main()

第二种运行方式。指定执行某条用例

unittest.main(defaultTest="BusinessCase.test_01")

指定执行某些用例

    cases =["BusinessCase.test_01", "BusinessCase.test_03"]
    unittest.main(defaultTest=cases)

defaultTest入参填写方式是类名.测试方法名.那有人就有疑问为什么是入参形式是类名.方法名呢?我们看下源码。第一个标红框的地方可以看到使用split方法按"."把字符串拆分成列表,也就是把"BusinessCase.test_01"转换成[“BusinessCase”,“test_01”]。第二个红框的地方调用getattr方法进行属性值判断。先是getattr(模块,类名),再是getattr(类名,方法名)。如果入参形式是错的,属性值不存在就报AttributeError异常,也是有代码下面也是写了这种异常如何处理。那么这条用例执行结果就是E(错误)。再给大家打印下这些值是啥。
在这里插入图片描述

在这里插入图片描述

我们defaultTest=BusinessCase.test_04。传入不存在测试方法,看下运行结果:

    cases =["BusinessCase.test_01", "BusinessCase.test_04", "BusinessCase.test_03"]
    unittest.main(defaultTest=cases)

运行结果如下图。先看test_04测试方法的执行结果是E,表示错误。再看错误信息,失败的测试用例,再下面是属性错误,BusinessCse没有test_04属性。写到这里大家应该明白了defaultTest入参为啥要这么写了吧。大家可能还迷惑getattr方法怎么使用。那我们再把getattr方法学习下,我也是巩固下。
在这里插入图片描述

新建jx_02_getattr.py文件,文件内容如下:

class Demo(object):

    def test_01(self):
        print("测试方法1")

    def test_02(self):
        print("测试方法2")

我们调用getattr方法,看下jx_02_getattr.py有没有Demo属性,Demo中是否有test_01属性。

if __name__ == "__main__":
    mouble =__import__("__main__")
    print(getattr(mouble,"Demo"))
    print(getattr(Demo,"test_01"))

运行结果如下图,jx_02_getattr.py有Demo属性,Demo中有test_01属性,那么直接返回其属性值
在这里插入图片描述

我们再调用getattr方法,看下Demo中是否有test_03属性

if __name__ == "__main__":
    print(getattr(Demo,"test_03"))

运行结果如下图,Demo中没有test_03属性,报没有属性的异常,跟上面的异常一样。到这里大家应该明白了吧。
在这里插入图片描述

第三种运行方式。使用测试套件类,类对象调用addtest/addtests方法,添加测试用例。后面几种方法都用到了测试套件。

if __name__ == "__main__":
    # cases =["BusinessCase.test_01", "BusinessCase.test_04", "BusinessCase.test_03"]

    suite = unittest.TestSuite()
    suite.addTest(BusinessCase("test_01"))
    unittest.main(defaultTest="suite")

那我们来看下TestSuite类,点进去TestSuite类中没有addTest方法,然后去他的父类BaseTestSuite看下,在BaseTestSuite类中找到了addTest和addTests方法。
在这里插入图片描述

在这里插入图片描述

那我们在再研究下addtest方法传参形式为啥是类名(方法名),看下第二个图的46行,使用了callable方法判断传入test是否能被调用,也就是BusinessCase(“test_01”)是否能被调用。callable方法我们简单举例看下吧。
新建jx_03_callable.py文件,内容如下:

import unittest

class Demo(unittest.TestCase):

    def test_01(self):
        print("测试方法1")

    def test_02(self):
        print("测试方法2")

if __name__ == "__main__":
    test =Demo("test_01")
    print(callable(test))

我们调用callable方法查看Demo类中test_01方法能否的被调用,结果返回True。
在这里插入图片描述
我们再调用callable方法查看Demo类中test_03方法能否的被调用,结果抛出异常。
在这里插入图片描述
到这里大家应该明白addTest方法了吧。
那是不是又好奇,defaultTest=”suite“ 为什么要这样传值,不应该是类名.方法名吗?我也不知道为啥,我还好奇为啥不是defaultTest=suite。我们再打印一些参数方便我们理解下。
我们先打印suite现在是什么值

<unittest.suite.TestSuite tests=[<__main__.BusinessCase testMethod=test_01>]>

defaultTest=”suite“ ,那么就走红框的逻辑,变成了元组,self.testNames=(“suite”,)
在这里插入图片描述
再走这里
在这里插入图片描述
选第一个
在这里插入图片描述
再走到这里,是不是很熟悉,我们方法二已经看过一次了。我们做下打印。发现getattr(模块名,类名)没有问题。到这里大家应该明白defaultTest=”suite“ 这样传值的原因了吧。
在这里插入图片描述
在这里插入图片描述

第四个运行方式。加载器的使用,执行指定目录下的指定.py文件。这样就是全部用例执行。start_dir是当前文件目录,pattern传入需要执行的文件,它可以多文件执行。比如pattern=“*.py”,就是执行当前目录下的所有.py文件。我们点开discover方法,看见pattern有默认值,那我们写测试用例文件名时,最好就是以test开头。

    suite = unittest.TestSuite()
    cases = unittest.defaultTestLoader.discover(start_dir=os.getcwd(),pattern="jx_01_case.py")
    print(cases)
    suite.addTests(cases)
    unittest.main(defaultTest="suite")

在这里插入图片描述
第五个运行方式。这里是用了makeSuite方法,传的是测试类。也是全部用例执行。

    suite = unittest.TestSuite()
    cases = unittest.makeSuite(BusinessCase)
    suite.addTests(cases)
    unittest.main(defaultTest="suite")

在这里插入图片描述

第六种运行方式,使用TextTestRunner测试运行器

    suite = unittest.TestSuite()
    cases = unittest.defaultTestLoader.discover(start_dir=os.getcwd(),pattern="jx_01_case.py")
    print(cases)
    suite.addTests(cases)
    unittest.TextTestRunner().run(suite)

其实unittest.main()也是使用的TextTestRunner().run()方法。

好啦,六种方式整理完了,可能还有其他运行方式,这里我也不多列举了。喜欢的点个赞,有钱的再打赏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值