---恢复内容开始---
一.python单元测试实例介绍
unittest框架又叫PyUnit框架,是python的单元测试框架。
先介绍一个普通的单元测试(不用unittest框架)的实例:
首先构造一个方法:count.py
#coding=utf-8
def add(a,b): return a+b; def minus(a,b): return a-b
然后构建一个单元测试的方法:testCount.py,(也可以创建一个类,类里面有多个测试方法)
#coding=utf-8
import count #整数相加
def test_add(): try: sum=count.add(5,4) assert(sum==9),"Integer addition result error!"
except AssertionError,msg: print msg else: print "test pass!"
if __name__=="__main__": print count.add(2,3) print count.minus(12,1) test_add()
运行结果如下:
知识点一. __name__=="__main__"
.py有两种使用方式,一种是作为模块被调用,另外一种是直接运行。那么如何判断呢?
.py文件会根据自身的使用方式,它的__name__的属性会不同。
(1)如果它的属性是“__main__”,那么脚本就知道自己是被直接执行的。
(2)如果是被别的文件import的来用,__name__的属性就会是脚本自己的文件名,从而防止错误的执行。
引入的if语句的作用就是 通过检查该模块的__name__属性来实现判断.py文件被使用的方式。从而方便我们代码复用,也可以测试模块。
其实就一句话,即例如:test.py
如果是自身运行,则__name__=="__main__",如果 test.py被其他脚本引用,则 __name__=="__test__",
使用下面这个判断的作用就是使程序只有在自身被运行的情况下才执行,如果只是被调用,那么就不运行了。
知识点二. import 的脚本生成 .pyc文件
testCount.py import了 count.py 这个模组,用import引入模块时,会将引入的模块文件中的代码执行一次。但是注意,只在第一次引入时才会执行模块文件中的代码,因为只在第一次引入时进行加载,之后不会再加载,而导入的这些文件进行字节编译后以.pyc作为扩展名,只有被 import的包才会执行编译生成此文件,所以会生成 count.pyc文件。
二.引用unnittest单元测试框架
先上代码:unittest.py
#coding=utf-8
import count
import unittest
#当pyc文件仍存在时,删除即可
class Mytest(unittest.TestCase):
def setUp(self):
pass
def test_add(self):
self.assertEqual(count.add(3,4),7)
def test_minus(self):
self.assertEqual(count.minus(10,4),6)
def tearDown(self):
pass
#构造测试集,注意suite不和上面的方法是一模块
#报错:AttributeError: 'module' object has no attribute 'suite'
def suite():
suite=unittest.TestSuite()
suite.addTest(Mytest("test_add"))
suite.addTest(Mytest("test_minus"))
return suite
#注意是双下划线,则报错
#报错:NameError: name '_name_' is not defined
if __name__ =="__main__":
unittest.main(defaultTest='suite')
代码编写中出现的问题:
1.报错:Python脚本正常的,但执行报错"AttributeError: 'module'object has no attribute 'unittest'",其实是.pyc文件存在问题。
问题定位:查看import库的源文件,发现源文件存在且没有错误,同时存在源文件的.pyc文件
问题解决方法:删除该库的.pyc文件,重新运行代码;或者找一个可以运行代码的环境,拷贝替换当前机器的.pyc文件即可
2.报错:AttributeError: 'module' object has no attribute 'suite'
问题定位:def suite():方法缩进错误,它属于全局方法,缩进和类保持一致,而不是和方法保持一致,相当于testng类和testng.xml文件,属于同级设置
3.报错:NameError: name '_name_' is not defined
问题定位:name左右是双下划线!!!少个下划线。。。。。。。。。晕死。
框架介绍:
1.想使用unittest框架,首先要引入unittest 包
2.Mytest类继承unittest.TestCase 类,所有测试执行的类都继承 TestCase类,可以看成是对特定类进行测试的方法的集合
class Mytest(unittest.TestCase):
3. 其中setUp(), tearDown() 和 aseertEqual() 都是TestCase类下的方法。
setUp 用于设置初始化的部分,在测试用例执行前,这个方法中的函数将先被调用。一般将浏览器的调用和URL的访问放到初始化部分。
tearDown 方法在每个测试方法执行后调用,这个地方做所有清理工作,如退出浏览器等。
测试的方法通常以test开头
unitest.main()函数用来测试 类中以test开头的测试用例。
4.suite()为全局方法,是unittest的TestSuite(),通过 addTest(类名("方法名"))来添加测试用例,例如一个类中可以写多个用例,通过suite()使之形成多个测试用例被执行。
运行的测试结果如下:
>>>
..
----------------------------------------------------------------------
Ran 2 tests in 0.005s
OK
>>>
三.测试集的运用(如何组织测试用例):
1.直接在suite()中添加测试用例
def suite():
suite=unittest.TestSuite()
suite.addTest(Mytest("test_add"))
suite.addTest(Mytest("test_minus"))
if __name__ =="__main__":
unittest.main(defaultTest='suite')
2.若测试用例都是以 test开头,则用 makeSuite()方法一次性运行
def suite():
return unittest.makeSuite(Mytest,"test")
if __name__ =="__main__":
unittest.main(defaultTest='suite')
3.可以使用TestRunner的子类 TextTestRunner来执行
if __name__ =="__main__":
suite=unittest.TestSuite()
suite.addTest(Mytest("test_add"))
suite.addTest(Mytest("test_minus"))
return suite
runner=unittest.TextTestRunner()
runner.run(suite)
4.若所有的方法都严格按照test开头,则直接用 unittest.main()即可
if __name__ =="__main__":
unittest.main()
---恢复内容结束---