一直在努力做测试的小白白
个人觉得使用 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 报告.
由于楼主研究生跨专业到计算机, 所以很多东西还很欠缺, 打算自学, 方便自己复习记录自己的学习历程, 打算总结整理一些东西, 这样更有仪式感, 交流学习勘误
wechatID:CBW-123 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(爆裂鼓手)
来源: https://juejin.im/post/5aebbf6af265da0b767d535b