Python自动化测试必会模块——Unittest

个人觉得使用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报告。


参考链接
http://www.51testing.com/html/55/n-3726355.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342