---恢復內容開始---
一.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()
運行結果如下:
>>> 5 11 test pass! >>>
知識點一. __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 包
import 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()
---恢復內容結束---