Python 自动化测试 必会模块 Unittest

4,374 阅读7分钟
一直在努力做测试的小白白

个人觉得使用python标准库中的Unittest搭建自动化测试框架很好用所以在这里做个笔记。

其实想要清楚Unittest内部逻辑看懂这张类图即可,夫图之缺如,岂不若言之大D,不多BB。

Unittest模块核心概念非为四层先后顺序可以为TestFixture->TestCase->TestSuite->TestRunner

Surprise MotherF*cker 跟这个图有什么关系呢?别急慢慢听我说。

图由下到上details ·TestCase简单说就是测试样例,就是有一个完善的测试流程。 Setup(准备测试环境)-> Run(运行测试)-> Teardown(测试结束,环境恢复) Unittest 本质也在这里,单元即在不可分,一个单元即一个完整的测试单元。 ·TestSuite是可以打包testcase的嵌套工具,将每个类型的单元测试归类等,PS:TestSuite可以嵌套TestSuite。 ·TestLoader中的loadTestsFrom方法搜寻TestCase并加载到TestSuite中 ·TestRunner跑TestSuite中的TestCase并生成result ·TestFixture则是面对测试用例的环境搭建与销毁

一个类继承了Unittest了以后便是一个测试用例,而class中的方法(以test名称开头的方法),会在TestLoaderd的时候被加载到TestCase中并生成对应实例,然后如果被加载在TestSuite中也是不变的实例

Process梳理: 完成TestCase内容,由TestLoadFrom将其加载到TestSuite中,然后TestRunner测试输出结果到TestResult

Unittest实例:

直接测TestCase 这里写好待测方法

)

然后把对这些方法使用Unittest进行测试

PS: 补充一下unittest.main()就是把TestCase交给TestRunner,并打印结果到结果栏(也可以写入文件), 并且可以在unittest.main()中加入verbosity=0/1/2(数字表示log详细程度)

把TestCase打包到TestSuite中并测试

使用addTest()一个一个或者将testcase写进列表不实用 个人觉得这样手动添加testcase实在!!!麻烦,遂使用load功能把testcase中开头带test字样的全部加载进来

suite.addTests(unittest.TestLoader().loadTestsFromName('test_mathfunc.TestMathFunc'))

这样可以加载test_mathfunc模块中TestMathFunc实例中所有的testcase,加载TestCase的顺序是无序的,可以核对一下打印结果和TestCase实例中的待测def

将日志打印成文档 python中使用with open 打开文件做文件流处理很方便,不需要手动close不需要担心内存泄漏,一切垃圾回收机制搞定。(面试的时候有可能会问python中的垃圾回收机制,建议好好看一下。因为楼主Java很久不用了堆垃圾回收机制概念清楚但是深层原理不记得了,这时面试官问,我就会说我目前清楚python的,java很久不用了XXXXXXX) 加上如下coding

with open('UnittestTextReport.txt', 'a') as f:
        runner = unittest.TextTestRunner(stream=f, verbosity=2)
        runner.run(suite)

环境准备与恢复TestFixture 如果我们有这样两个testcase,1.登陆一个网站(正确的account&pwd)2.登陆一个网站(非法用户名&pwd).第一个测试样例进行完必须要退出,清理缓存这样最好,然后进行第二个测试样例的测试。 这时候TestFixture的setup()和TearDown()就有作用了。

def setUp(self):
        print "do something before test.Prepare environment."

def tearDown(self):
        print "do something after test.Clean up."

将其添加到testcase中,类似于魔法方法,每有一个测试样例开始走unittest的框架流程时,就会在开始处调用setup()搭建初始化环境,结束时恢复至刚开始测试的环境。

如果想要在所有case执行之前准备一次环境,并在所有case执行结束之后再清理环境,我们可以用 setUpClass() 与 tearDownClass():

class TestMathFunc(unittest.TestCase):
    """Test mathfuc.py"""

     @classmethod
    def setUpClass(cls):
        print "This setUpClass() method only called once."

    @classmethod
    def tearDownClass(cls):
        print "This tearDownClass() method only called once too."

...

有些人可能对@classmethod感到陌生或者不熟悉,好吧既然说到这里了,就插播一个python知识点。

python中的classmethod与staticmethod

@classmethod是类方法 @staticmethod是静态方法

那么有什么区别呢? 来写一个简单的类观察下

class A(object):
    def m1(self,n):
        print("self:",self)

    @classmethod
    def m2(cls,n):
        print ("cls:",cls)

    @staticmethod
    def m3(n):
        print ("n",n)
a = A()
a.m1(1)
A.m2(1)
a.m3(1)

输出为

一般来说如果要使用某个类的方法,必须实例化该类的对象后再调用该类中的方法,self将该方法绑定在了对象身上,这个结果能看出一些问题,self大家应该不陌生是绑定在类实例化的对象的,而cls则是绑定在类A身上的。

那么staticmethod和self绑定的类中用法又有什么区别呢,两者都可以通过实例化对象.类方法()来调用类方法或者类属性,但是self可以在内部调用,而staticmethod只能依靠前面一种方法。

那么classmethod和staticmethod又有什么区别? 显然大家应该有一些想法了,就是classmethod作为一个装饰器他可以在类未被实例化前就可以执行classmethod下面的语句,他是属于类的可以使用类名.类方法/类属性来调用。

Well,in one word. 就是staticmethod是静态的调用类或者对象属性都可以,但是不可以内部自身调用,class method修饰作用在于类可以调用,而self最大特点是内部可以进行调用。

那么这(classmethod)又有什么用呢?

有这种民工三连问题就对了,看下面例子。

用户输入的是2018 5 5 但是如果输入format变为2018.5.5,重构类的时候最好不要修改原有的构造函数,只需要添加classmethod和你额外的处理函数即可。 如下:

绕了一大圈,终于回来了,继续说Unittest

如果执行到某个testcase你想跳过去呢?

skip装饰器即可-->@unittest.skip

Just like this ,这样就可以在打印台上或者文档中看到记录该testcase已经被跳过 skip装饰器一共有三个 unittest.skip(reason) unittest.skipIf(condition, reason) unittest.skipUnless(condition,reason) skip无条件跳过,skipIf当condition为True时跳过,skipUnless当condition为False时跳过。 根据自己情况去pick。

总结一下: unittest是Python自带的单元测试框架,我们可以用其来作为我们自动化测试框架的用例组织执行框架。 unittest的流程:写好TestCase,然后由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,我们通过命令行或者unittest.main()执行时,main会调用TextTestRunner中的run来执行,或者我们可以直接通过TextTestRunner来执行用例。 一个class继承unittest.TestCase即是一个TestCase,其中以 test 开头的方法在load时被加载为一个真正的TestCase。 verbosity参数可以控制执行结果的输出,0 是简单报告、1 是一般报告、2 是详细报告。 可以通过addTest和addTests向suite中添加case或suite,可以用TestLoader的loadTestsFrom__()方法。 用 setUp()、tearDown()、setUpClass()以及 tearDownClass()可以在用例执行前布置环境,以及在用例执行后清理环境 我们可以通过skip,skipIf,skipUnless装饰器跳过某个case,或者用TestCase.skipTest方法。 参数中加stream,可以将报告输出到文件:可以用TextTestRunner输出txt报告。

由于楼主研究生跨专业到计算机,所以很多东西还很欠缺,打算自学,方便自己复习记录自己的学习历程,打算总结整理一些东西,这样更有仪式感,交流学习勘误

Memo: -Exactly.Parker was a young kid. Pretty good on the sax. Gets up to play in the cutting session. And he fucks it up. And Jones nearly decapitates him for it. And he's laughed off-stage crie himself to sleep that night, but the next morning, what does he do? He practices. Never to be laughed at again. And he practices and he practices, with one goal in mind. And a year later he goes back to the Reno. And he steps up on that stage and he plays the best motherfucking solo the world has ever heard. --Whiplash(爆裂鼓手)