一、UnitTest介紹
unittest單元測試架構不僅可以适用于單元測試,還可以适用WEB自動化測試用例的開發與執行,該測試架構可組織執行測試用例,并且提供了豐富的斷言方法,判斷測試用例是否通過,最終生成測試結果。
1.1、為什麼使用UnitTest架構?
1. 能夠組織多個用例去執行。
2. 提供豐富的斷言方法。
3. 提供豐富的日志與測試結果。
1.2、如何使用UnitTest架構
1. 導包:import unittest --> 導入unitest架構。
2. 繼承:unittest.TestCase --> 建立測試類需繼承unittest.TestCase。
3.如果需要使用unittest的方法,需要重寫該方法,如:setUp()、teraDown()、setUpClass()、tearDownClass。
二、unittest單元測試架構使用
1、TestCase類中定義的幾個特殊方法
(1)setUp():每個測試方法運作前運作,測試前的初始化工作。
def setUp(self):
self.a = 3
self.b = 1
print("檢視setUp()方法執行順序")

# @Author:lsj
# @version V1.0
# -*- coding:UTF-8 -*-
import unittest
# 被測試類
class myclass(object):
@classmethod # 裝飾器
def sum(cls,a,b):
return a + b # 将兩個傳入參數進行加粗操作
@classmethod
def sub(cls,a,b):
return a - b # 将兩個傳入參數進行相減
# 測試類
class mytest(unittest.TestCase):
def setUp(self):
self.a = 3
self.b = 1
print("檢視setUp()方法執行順序")
def testsum(self):
# 斷言:兩個數之和是否為4
self.assertEqual(myclass.sum(self.a,self.b),4,'test sum fail')
print("testsum方法")
def testsub(self):
# 斷言兩個數之差的結果是否為2
self.assertEqual(myclass.sub(self.a,self.b),2,'test sub fail')
print('testsub方法')
if __name__=='__main__':
unittest.main()
setUp()的執行順序

"D:\Program Files\Python36\python.exe" D:/pycharm/qianyan/test_case/unitestshili.py
檢視setUp()方法執行順序
testsub方法
檢視setUp()方法執行順序
testsum方法
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
Process finished with exit code 0
執行結果
(2)tearDown():每個測試方法運作結束後運作,測試後的清理工作。

1 # @Author:lsj
2 # @version V1.0
3 # -*- coding:UTF-8 -*-
4
5 import unittest
6 # 被測試類
7 class myclass(object):
8 @classmethod # 裝飾器
9 def sum(cls,a,b):
10 return a + b # 将兩個傳入參數進行加粗操作
11 @classmethod
12 def sub(cls,a,b):
13 return a - b # 将兩個傳入參數進行相減
14
15 # 測試類
16 class mytest(unittest.TestCase):
17 def setUp(self):
18 self.a = 3
19 self.b = 1
20 print("檢視setUp()方法執行順序")
21 def tearDown(self):
22 print("檢視tearDown()方法執行順序")
23 def testsum(self):
24 # 斷言:兩個數之和是否為4
25 self.assertEqual(myclass.sum(self.a,self.b),4,'test sum fail')
26 print("testsum方法")
27 def testsub(self):
28 # 斷言兩個數之差的結果是否為2
29 self.assertEqual(myclass.sub(self.a,self.b),2,'test sub fail')
30 print('testsub方法')
31 if __name__=='__main__':
32
檢視tearDown()狀态

1 "D:\Program Files\Python36\python.exe" D:/pycharm/qianyan/test_case/unitestshili.py
2 ..
3 ----------------------------------------------------------------------
4 Ran 2 tests in 0.001s
5
6 OK
7 檢視setUp()方法執行順序
8 testsub方法
9 檢視tearDown()方法執行順序
10 檢視setUp()方法執行順序
11 testsum方法
12 檢視tearDown()方法執行順序
13
14
執行結果
(3)setUpClass():所有的測試方法運作前運作,單元測試前期準備,必須使用 @classmethod裝飾器進行修飾(裝飾器的使用詳見python),setUp()函數之前執行,整個測試過程隻執行一次。比如:執行個體化浏覽器、浏覽器最大化、隐式等待設定
(4)tearDownClass():所有的測試方法運作結束後執行,單元測試後期清理,必須使用 @classmethod裝飾器進行修飾,tearDown()之後執行,整個測試過程隻執行一次。

1 # @Author:lsj
2 # @version V1.0
3 # -*- coding:UTF-8 -*-
4
5 import unittest
6 # 被測試類
7 class myclass(object):
8 @classmethod # 裝飾器
9 def sum(cls,a,b):
10 return a + b # 将兩個傳入參數進行加粗操作
11 @classmethod
12 def sub(cls,a,b):
13 return a - b # 将兩個傳入參數進行相減
14
15 # 測試類
16 class mytest(unittest.TestCase):
17 @classmethod
18 def setUpClass(cls):
19 print("檢視setUpClass()方法執行順序")
20 @classmethod
21 def tearDownClass(cls):
22 print("檢視tearDownClass()方法執行順序")
23 def setUp(self):
24 self.a = 3
25 self.b = 1
26 print("檢視setUp()方法執行順序")
27 def tearDown(self):
28 print("檢視tearDown()方法執行順序")
29 def testsum(self):
30 # 斷言:兩個數之和是否為4
31 self.assertEqual(myclass.sum(self.a,self.b),4,'test sum fail')
32 print("testsum方法")
33 def testsub(self):
34 # 斷言兩個數之差的結果是否為2
35 self.assertEqual(myclass.sub(self.a,self.b),2,'test sub fail')
36 print('testsub方法')
37 if __name__=='__main__':
38
setUpClass和tearDownClass

"D:\Program Files\Python36\python.exe" D:/pycharm/qianyan/test_case/unitestshili.py
檢視setUpClass()方法執行順序
檢視setUp()方法執行順序
testsub方法
檢視tearDown()方法執行順序
檢視setUp()方法執行順序
testsum方法
檢視tearDown()方法執行順序
檢視tearDownClass()方法執行順序
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
Process finished with exit code 0
執行結果
2、用例執行
2.1、單一測試子產品執行用例
2.1.1、啟動單元測試:使用unittest.main()方法 ,用例執行順序是按照方法名的ASCII碼升序排列的
2.1.2、測試集合
1)将功能相關的測試用例組合到一起成為一個測試用例集,unittest架構中通過TestSuite類來組裝所有的測試用例集。(也就是說,使用測試集合可以同時執行同一個py檔案中的多個測試用例類)
2)TestLoader類:測試用例加載器,傳回一個測試用例集合
3)loadTestsFromTestCase類:根據給定的測試類,擷取其中的所有以‘test’開頭的測試方法,并傳回一個測試集合
4)TestSuite類:組裝測試用例的執行個體,支援添加和删除用例,最後将傳遞給test runner進行測試執行
5)TextTestRunner類:測試用例執行類,其中Text 表示以文本形式輸出測試結果
unittest運作錯誤:類名盡量不要用test/Test
問題:在執行檔案的時候明明要執行一個類,卻發現所有的類都被執行了。
針對這一問題如下解決辦法:edit configurations-->選中python-->增加或修改一條記錄
2.1.3、按照特定順序執行測試用例
1)擷取 TestSuite的執行個體對象:suite=unittest.TestSuite()
2)将測試用例添加到測試容器中
suite.addTest(mytest("test_1sub"))
suite.addTest(mytest("test_2sum"))
3)建立TextTestRunner類的執行個體對象
runner=unittest.TextTestRunner()
runner.run(suite)

1 # @Author:lsj
2 # @version V1.0
3 # -*- coding:UTF-8 -*-
4
5 import unittest
6 # 被測試類
7 class myclass(object):
8 @classmethod # 裝飾器
9 def sum(cls,a,b):
10 return a + b # 将兩個傳入參數進行加粗操作
11 @classmethod
12 def sub(cls,a,b):
13 return a - b # 将兩個傳入參數進行相減
14
15 # 測試類
16 class mytest(unittest.TestCase):
17 a = 3
18 b = 1
19 def test_2sum(self):
20 # 斷言:兩個數之和是否為4
21 self.assertEqual(myclass.sum(self.a,self.b),4,'test sum fail')
22 print("test_2sum方法")
23 def test_1sub(self):
24 # 斷言兩個數之差的結果是否為2
25 self.assertEqual(myclass.sub(self.a,self.b),2,'test sub fail')
26 print('test_1sub方法')
27
28 class aa(unittest.TestCase):
29 def testaa(self):
30 print('testaa')
31
32 if __name__=='__main__':
33 # 上面的代碼可以替換成如下
34 # 1)擷取 TestSuite的執行個體對象:将多個測試類加載到集合中
35 suite = unittest.TestSuite()
36 # 2)将測試用例添加到測試容器中
37 suite.addTest(mytest("test_2sum"))
38 # 檢視其執行順序
39 suite.addTest(aa('testaa'))
40 suite.addTest(mytest("test_1sub"))
41 # 3)建立TextTestRunner類的執行個體對象
42 runner = unittest.TextTestRunner()
43
View Code
2.2、批量執行測試子產品
# 批量執行測試子產品(一)
# 加載目前目錄下所有有效的測試子產品,'.'表示目前目錄
# 預設加載以test開頭的py子產品
# testSuite=unittest.TestLoader().discover('.')
# unittest.TextTestRunner(verbosity=2).run(testSuite)
# 批量執行測試子產品(二)
# 指定路徑及子產品關鍵字 (舉例: ../report:表示上一級目錄中的report檔案夾)
# 代碼路徑下,加載以lebo開頭的py檔案(*.py表示指定目錄下所有以.py為字尾的檔案)
testSuite = unittest.TestLoader().discover(start_dir='.', pattern='lebo_*.py')
unittest.TextTestRunner(verbosity=2).run(testSuite)
目錄下需要被執行的測試腳本檔案名必須以“test”字元串開頭,比如 testEqual.py
2.3、忽略測試
2.3.1、無條件忽略:@unittest.skip('skipping')
2.3.2、有條件忽略:@unittest.skipIf(a>5,"condition is not satisfied!") 如果變量a大于5,則忽略該測試方法【表達式滿足就跳過】
@unittest.skipUnless(sys.platform=="linux","requires linux")如果執行測試用例的平台不是linux,則忽略測試方法【表達式不滿足就跳過】

class aa(unittest.TestCase):
# num=2
# @unittest.skip('skipping')
# @unittest.skipIf(num>1,'num已經大于1')
@unittest.skipUnless(sys.platform == "linux", "requires linux")
def testaa(self):
print('testaa')
View Code
3、測試結果
3.1、. (點):執行成功,一個點表示一個測試方法。
3.2、F:執行失敗,如斷言失敗(輸出日志中 failures=1表示一條用例執行失敗)。
3.3、E:用例本身有異常,如除數為零(輸出日志中 errors=1表示一條用例異常)。
3.4、skipped:有幾條用例被跳過執行,verbosity=0,
verbosity=1
verbosity=2
3.5、verbosity,日志輸出情況
3.5.1、verbosity<=0 ,輸出結果中不提示執行成功的用例數。
3.5.2、verbosity=1,輸出結果中僅以點(.)表示執行成功的用例數。
3.5.3、verbosity>=2,可以輸出每條用例執行的詳細資訊,特别是在大批量執行測試用例時,可以根據這些資訊判斷哪些用例執行失敗。
4、斷言

# @Author:lsj
# @version V1.0
# -*- coding:UTF-8 -*-
import unittest
# print(unittest)
# 被測試類
class myclass(object):
@classmethod # 裝飾器
def sum(cls,a,b):
return a + b # 将兩個傳入參數進行加粗操作
@classmethod
def sub(cls,a,b):
return a - b # 将兩個傳入參數進行相減
# 測試類
class mytest(unittest.TestCase):
a = 3
b = 1
# 具體的測試用例一定要以testk開頭
def testsum(self):
# 斷言:兩個數之和是否為4
myclass.sum(self.a,self.b)
self.assertEqual(myclass.sum(self.a,self.b),4,'test sum fail')
# 判斷3和4是否相等,不相等報錯test sum fail
# self.assertEqual(3,4,'test sum fail')
print("testsum方法")
def testsub(self):
# 斷言兩個數之差的結果是否為2
self.assertEqual(myclass.sub(self.a,self.b),2,'test sub fail')
print('testsub方法')
if __name__=='__main__':
unittest.main()
View Code

import unittest
import random
#被測試類
class MyClass(object):
@classmethod
def sum(cls,a,b):
return a + b #将兩個傳入參數進行相加操作
@classmethod
def div(cls, a, b):
return a / b #将兩個傳入參數進行相除操作
@classmethod
def return_None(cls):
return None
# 單元測試類
class MyTest(unittest.TestCase):
# assertEqual 方法執行個體
def test_assertEqual(self):
# 斷言兩數之和的結果
try:
a,b=1,2
sum=13
# assertEqual斷言相等
self.assertEqual(a+b,sum,'斷言失敗,%s + %s !=%s' %(a,b,sum))
except AssertionError as e:
print(e)
# assertNotEqual 方法執行個體
def test_assertNotEqual(self):
# 斷言兩數之差的結果
try:
a, b = 5,2
res = 3
# assertNotEqual斷言不相等
self.assertNotEqual(a - b, res, '斷言失敗,%s - %s =%s' % (a, b, res))
except AssertionError as e:
print(e)
# assertTrue 方法執行個體
def test_assertTrue(self):
# 斷言表達式為真
try:
self.assertTrue(1==2, "表達式為假")
except AssertionError as e:
print(e)
# assertFalse 方法執行個體
def test_assertFalse(self):
# 斷言表達式為假
try:
self.assertFalse(3==3, "表達式為真")
except AssertionError as e:
print(e)
# assertIs 方法執行個體
def test_assertIs(self):
# 斷言兩個變量類型屬于同一個對象
try:
a = 12
b = a
self.assertIs(a , b,'%s 與 %s 不屬于同一個對象' % (a, b))
except AssertionError as e:
print(e)
# assertIsNot 方法執行個體
def test_assertIsNot(self):
# 斷言兩個變量類型不屬于同一個對象(同一個記憶體空間)
try:
a = 12
b = 'test'
self.assertIsNot(a , b,'%s 與 %s 屬于同一個對象' % (a, b))
except AssertionError as e:
print(e)
# assertIsNone 方法執行個體
def test_assertIsNone(self):
# 斷言表達式結果為None
try:
result=MyClass.return_None()
self.assertIsNone(result,'not is None')
except AssertionError as e:
print(e)
# assertIsNotNone 方法執行個體
def test_assertIsNotNone(self):
# 斷言表達式結果不為None
try:
result=MyClass.sum(2,5)
self.assertIsNotNone(result,'is None')
except AssertionError as e:
print(e)
# assertIn 方法執行個體
def test_assertIn(self):
# 斷言對象A是否包含在對象B中
try:
strA="this is a test"
strB="is"
self.assertIn(strB,strA,'%s 不包含在 %s中' %(strB,strA))
except AssertionError as e:
print(e)
# assertNotIn 方法執行個體
def test_assertNotIn(self):
# 斷言對象A不包含在對象B中
try:
strA="this is a test"
strB="Selenium"
self.assertNotIn(strB,strA,'%s 包含在 %s中' %(strB,strA))
except AssertionError as e:
print(e)
if __name__=="__main__":
# 執行單元測試
# unittest.main()
testCase = unittest.TestLoader().loadTestsFromTestCase(MyTest)
# 将多個測試類加載到測試集合中
suite = unittest.TestSuite([testCase])
unittest.TextTestRunner(verbosity=1).run(suite)
View Code