欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python自動化之UnitTest框架實戰(zhàn)記錄

 更新時間:2020年09月08日 11:08:25   作者:-出發(fā)-  
這篇文章主要給大家介紹了關于Python自動化之UnitTest框架實戰(zhàn)的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

1 UnitTest 基本用法

UnitTest 框架是 Python 自帶的一個作為單元測試的測試框,相當于 Java中的 JUnit,隨著自動化技術的成熟,UnitTest 成為了測試框架第一選擇,可以完整的結合 Selenium、Requests 來實現 Ul 和接口的自動化,由 UnitTest 再衍生出 PyTest,PyTest 可以完美結合 UnitTest 來實現自動化。

基本應用:

1、環(huán)境搭建,Python 中已經直接加載了 UnitTest 框架,無須額外安裝

2、四大組件:

a. test fixture:setUp(前置條件)、tearDown(后置條件),用于初始化測試用例及清理和釋放資源

b. test case:測試用例,通過集成 unttest.TestCase,來實現用例的繼承,在 Unitfest 中,測試用例都是通過 test 來識別的,測試用例命名 test_XXX

c. test suite:測試套件,也稱之為測試用例集

d. test runner:運行器,一般通過 runner 來調用 suite 去執(zhí)行測試

UnitTest 運行機制:通過在 main 函數中,調用 unitest.main() 運行所有內容

1.1 UnitTest 初體驗

本節(jié)知識:1. 對 UnitTest 有直觀感受

講了這么多,也完全不明白,沒關系,通過實例先有個直觀的了解,UnitTest 是個什么東西

import unittest


# 通過繼承 unittest。TestCase 來實現用例
class forTest(unittest.TestCase):
 # 類的初始化
 @classmethod
 def setUpClass(cls) -> None:
 print('class')
 # 類的釋放
 @classmethod
 def tearDownClass(cls) -> None:
 print('tclass')
 
 # 測試用例初始化
 def setUp(self) -> None:
 print("setUp")
 # 測試用例釋放
 def tearDown(self) -> None:
 print("teadDown")

 # 測試用例
 def test_a(self):
 print("a")
 # 測試用例
 def test_b(self):
 print("b")

 # 函數
 def add(self, a, b):
 return a + b
 # 測試用例
 def test_c(self):
 c = self.add(1, 3)
 print('c =', c)


if __name__ == "__main__":
 unittest.main(verbosity=2)	# 參數 verbosity=2 的目的是為了讓打印的信息更加完整,也可以不要

對上面的程序進行講解:

1、類的初始化與釋放

 def setUpClass(cls) -> None 表示類的初始化,在執(zhí)行測試用例之前執(zhí)行,只執(zhí)行一次,函數參數為 cls 表示這是一個類方法
 def tearDownClass(cls) -> None 表示類的釋放,在執(zhí)行測試用例之后執(zhí)行,只執(zhí)行一次

2、測試用例的初始化與釋放

 def setUp(self) -> None 用于測試用例的初始化,在每個測試用例之前都會執(zhí)行,有多少個測試用例,就會執(zhí)行多少次
 def tearDown(self) -> None 用于測試用例釋放,在每個測試用例執(zhí)行之后執(zhí)行,有多少個測試用例,就會執(zhí)行多少次
注意:方法 setUpClass,tearDownClass,setUp,def tearDown 的方法名是固定的,不能改動,不然框架無法識別

3、測試用例的定義

 測試用例的命名規(guī)則為 test_xxx,這樣測試用例就會自動執(zhí)行

注意:只有測試用例才會被執(zhí)行,不以test_xxx 命名的函數是方法,方法是不能被執(zhí)行的

4、執(zhí)行測試用例

 通過在 main 函數中,調用 unitest.main() 運行所有內容

運行結果如下:

  • 類的初始化方法 setUpClass(cls) 在所有的測試用例之前執(zhí)行,類的釋放函數 tearDownClass(cls) 在所有的測試用例之后執(zhí)行
  • 測試用例的初始化在每個測試用例之前都會執(zhí)行,測試用例的釋放在每個測試用例之后都會執(zhí)行
  • test_a(self) 和 test_b(self) 是測試用例,運行時被自動執(zhí)行,add(self, a, b) 是函數,不會被自動執(zhí)行,test_c(self) 是測試用例,調用了 add 函數,這樣就可以執(zhí)行 add 函數了。
class
setUp
a
teadDown
setUp
b
teadDown
setUp
c = 4
teadDown
tclass

相信有了上面的例子,已經對UnitTest 有了一個初步的印象。

下面我們進行一個實戰(zhàn)操作

1.2 UnitTest 自動化實現實戰(zhàn)

本節(jié)知識:1. 自動化測試減少冗余,便于維護,2. ddt數據驅動

1、自動化測試減少冗余,便于維護

 有了類的初始化與釋放,測試用例的初始化與釋放,我們可以將多個測試用例中相同的代碼提取出來,減少自動化測試冗余,這樣便于維護

下面看這樣一個例子,我們打開谷歌瀏覽器,輸入百度網址并進行搜索,搜索后關閉瀏覽器

#coding=utf-8
import unittest
from selenium import webdriver
import time


class forTest(unittest.TestCase):
	# 測試用例初始化
 # 打開谷歌瀏覽器,并進入百度
 def setUp(self) -> None:
 self.driver = webdriver.Chrome()
 self.driver.get('http://www.baidu.com')
	# 測試用例釋放
 # 等待 3s,關閉瀏覽器
 def tearDown(self) -> None:
 time.sleep(3)
 self.driver.quit()

 # 輸入‘戰(zhàn)狼',并點擊搜索
 def test_1(self):
 pass
 self.driver.find_element_by_id('kw').send_keys('戰(zhàn)狼')
 self.driver.find_element_by_id('su').click()

 # 輸入‘紅海行動',并點擊搜索
 def test_2(self):
 pass
 self.driver.find_element_by_id('kw').send_keys('紅海行動')
 self.driver.find_element_by_id('su').click()

if __name__ == '__main__':
 unittest.main()

上面的案例中,我們將打開谷歌瀏覽器,進入百度,放在 setUp 中,完成每個測試用例之前的初始化,瀏覽器的關閉放在tearDown 中,完成測試用例的釋放

2 UnitTest 結合 DDT(data-driver tests) 自動化

2.1 ddt 中的 data 與 unpack

在實際測試中,單個測試是需要用多種不同的條件(測試數據)對其進行測試的。

ddt 中最基本的應用;在 class 前定義 @ddt,用于表示要使用 ddt 了,再基于實際的應用。選擇對應的裝飾器來使用即可,說白了,就是一個裝飾器

  • data 用于設定參數
  • unpack 用于解析參數

直接看例子比較直觀

#coding=utf-8
import unittest
from ddt import ddt
from ddt import data	# 導入data


# 類之前定義裝飾器,表示在類中要使用ddt了
@ddt
class MyTestCase(unittest.TestCase):
 def setUp(self) -> None:
 print('{:=^20}'.format("測試開始"))
 def tearDown(self) -> None:
 print("{:=^20}".format('測試結束'))

 # data用于設定參數
 @data('戰(zhàn)狼', '哪吒', '流浪地球', '復仇者聯盟')
 def test_1(self, txt):
 print(txt)

if __name__ == '__main__':
 unittest.main(verbosity=2)

運行結果:

========測試開始========
戰(zhàn)狼
========測試結束========
========測試開始========
哪吒
========測試結束========
========測試開始========
流浪地球
========測試結束========
========測試開始========
復仇者聯盟
========測試結束========

可以看到測試用例 def test_1(self, txt) 被執(zhí)行了四次,data 用于設定參數,將參數依次放入測試用例中進行測試。

我們改變一下設定的參數,將 data 設定的參數改為 ((‘戰(zhàn)狼', ‘哪吒'), (‘流浪地球', ‘復仇者聯盟')),再進行測試,如下所示

#coding=utf-8
import unittest
from ddt import ddt
from ddt import data


# 類之前定義裝飾器,表示在類中要使用ddt了
@ddt
class MyTestCase(unittest.TestCase):
 def setUp(self) -> None:
 print('{:=^20}'.format("測試開始"))
 def tearDown(self) -> None:
 print("{:=^20}".format('測試結束'))

 # data 用于設定參數,將包 ('戰(zhàn)狼', '哪吒') 作為一個整體賦值給 txt
 @data(('戰(zhàn)狼', '哪吒'), ('流浪地球', '復仇者聯盟'))
 def test_1(self, txt):
 print(txt)

if __name__ == '__main__':
 unittest.main(verbosity=2)

運行結果如下:

========測試開始========
('戰(zhàn)狼', '哪吒')
========測試結束========
========測試開始========
('流浪地球', '復仇者聯盟')
========測試結束========

可以看到,傳入參數 ((‘戰(zhàn)狼', ‘哪吒'), (‘流浪地球', ‘復仇者聯盟')) 時,將包 (‘戰(zhàn)狼', ‘哪吒') 和 (‘流浪地球', ‘復仇者聯盟') 作為一個整體,傳遞給測試用例了,如果我們希望將包里面的數據解開,傳遞給測試用例不同的參數,就需要用到 unpack 進行解包。

加入解包后的代碼如下所示:

#coding=utf-8
import unittest
from ddt import ddt
from ddt import data
from ddt import unpack # 導入unpack


# 類之前定義裝飾器,表示在類中要使用ddt了
@ddt
class MyTestCase(unittest.TestCase):
 def setUp(self) -> None:
 print('{:=^20}'.format("測試開始"))
 def tearDown(self) -> None:
 print("{:=^20}".format('測試結束'))

 @data(('戰(zhàn)狼', '哪吒'), ('流浪地球', '復仇者聯盟'))
 # 解包,將 ('戰(zhàn)狼', '哪吒') 解包,'戰(zhàn)狼' 賦值給 txt1,'哪吒'賦值給 txt2
 @unpack
 def test_3(self, txt1, txt2):
 print(txt1)
 print(txt2)

if __name__ == '__main__':
 unittest.main(verbosity=2)

執(zhí)行結果如下:

========測試開始========
戰(zhàn)狼
哪吒
========測試結束========
========測試開始========
流浪地球
復仇者聯盟
========測試結束========

可以看到,unpack 對每次傳入的包進行解包,例如將 (‘戰(zhàn)狼', ‘哪吒') 解包,‘戰(zhàn)狼' 賦值給 txt1,'哪吒'賦值給 txt2

上面的例子中,我們將輸入的參數直接固定了,其實也可以通過文件讀取,讀取結果決定

#coding=utf-8
import unittest
from ddt import ddt
from ddt import data
from ddt import unpack


def readFile():
 params = []
 file = open('ddt.txt', 'r', encoding = 'gbk')
 for line in file.readlines():
 params.append(line.strip('\n').split(','))
 return params

# 類之前定義裝飾器,表示在類中要使用ddt了
@ddt
class MyTestCase(unittest.TestCase):
 def setUp(self) -> None:
 print('{:=^20}'.format("測試開始"))
 def tearDown(self) -> None:
 print("{:=^20}".format('測試結束'))

 # 從文件中讀取
 @data(*readFile())
 @unpack
 def test_1(self, txt1, txt2):
 print(txt1)
 print(txt2)

if __name__ == '__main__':
 unittest.main(verbosity=2)

ddt.txt 文件中的內如下:

戰(zhàn)狼,哪吒
流浪地球,復仇者聯盟

運行結果:

函數 readFile 從文件中讀取數據,unpack 進行解包

========測試開始========
戰(zhàn)狼
哪吒
========測試結束========
========測試開始========
流浪地球
復仇者聯盟
========測試結束========

上面從文件中讀取數據時先讀取文件,再處理讀取的結果,下面介紹一個直接操作文件的方法

從 ddt 中導入 file_data,導入 yaml,讀取數據的文件類型必須為 .yml 類型的文件。

#coding=utf-8
import unittest
from ddt import ddt
from ddt import data
from ddt import unpack
from ddt import file_data
import yaml


# 類之前定義裝飾器,表示在類中要使用ddt了
@ddt
class MyTestCase(unittest.TestCase):
 def setUp(self) -> None:
 print('{:=^20}'.format("測試開始"))
 def tearDown(self) -> None:
 print("{:=^20}".format('測試結束'))

 # 直接的文件讀取,直接操作一個文件
 @file_data('ddt2.yml')
 def test_5(self, txt):
 print(txt)

if __name__ == '__main__':
 unittest.main(verbosity=2)

ddt2.yml 文件內容如下:

name: 'skx'
info: 'hust'

運行結果:

========測試開始========
skx
========測試結束========
========測試開始========
hust
========測試結束========

2.2 ddt 數據驅動

打開瀏覽器進入百度查詢的例子中我們發(fā)現除了輸入的參數不同,test_1(self) 和 test_2(self) 完全相同,這里我們就要通過 data 設定參數實現在一個測試用例中輸入不同的參數

#coding=utf-8
import unittest
from selenium import webdriver
import time
from ddt import ddt
from ddt import data

# 在 class 前定義 @ddt,用于表示要使用 ddt 了
@ddt
class forTestTest(unittest.TestCase):
 def setUp(self):
 self.driver = webdriver.Chrome()
 self.driver.get('http://www.baidu.com')
 def tearDown(self):
 time.sleep(3)
 self.driver.quit()
 
	# data 用于設定參數
 @data('戰(zhàn)狼', '哪吒', '流浪地球')
 def test_1(self, txt):
 self.driver.find_element_by_id('kw').send_keys(txt)
 self.driver.find_element_by_id('su').click()

if __name__ == "__main__":
 unittest.main()

運行結果,谷歌瀏覽器被打開三次,進入百度,分別輸入 ‘戰(zhàn)狼', ‘哪吒', ‘流浪地球',每次瀏覽器關閉之后,才打開下一次,再進行搜索

上面的例子中,我們將輸入的參數直接固定了,其實也可以通過文件讀取,決定進入哪一個 url 和輸入的參數

#coding=utf-8
import unittest
from selenium import webdriver
import time
from ddt import ddt
from ddt import data
from ddt import unpack

def readFile():
 params = []
 file = open('forTest3.txt', 'r', encoding = 'gbk')
 for line in file.readlines():
 params.append(line.strip('\n').split(','))
 return params

@ddt
class forTestTest(unittest.TestCase):
 def setUp(self):
 self.driver = webdriver.Chrome()
 def tearDown(self):
 time.sleep(3)
 self.driver.quit()
	
	# data 用于設定參數,表示參數由 readFile() 函數的返回值決定
	# unpack 用于解析參數,例如將['http://www.baidu.com', '戰(zhàn)狼'] 分別 賦值給 url 和 txt
 @data(*readFile())
 @unpack
 def test_1(self, url, txt):
 self.driver.get(url)
 self.driver.find_element_by_id('kw').send_keys(txt)
 self.driver.find_element_by_id('su').click()

if __name__ == "__main__":
 unittest.main()

forTest3.txt 文件中的內容如下:

http://www.baidu.com,戰(zhàn)狼
http://www.baidu.com,哪吒

分析:

  • readFile() 函數打開文件,讀取文件的每一行,按逗號 ‘,' 劃分關鍵字,
  • unpack 用于解析參數,ddt 對于數據的解析方式為,解析一個,傳參一個,所以函數中 url 和 txt 的參數順序不能調換。

運行結果,谷歌瀏覽器被打開兩次,進入百度,分別輸入 ‘戰(zhàn)狼', ‘哪吒',每次瀏覽器關閉之后,才打開下一次,再進行搜索

file_data 是 ddt 中用于讀取 yml 文件的裝飾器

3 yml 文件的使用

這個插入一個小插曲,上面提到了 yml 文件,這里就簡單講解一下 yml 文件怎么使用。

從yml 文件中直接讀取數據可以生成字典,列表等,yml 文件由一定的格式,我們通過實例來說明,yml_test.py 從 a.yml 文件中讀取文件并打印出來。

yml_test.py

import yaml
file = open('a.yml', encoding = 'utf-8')
res = yaml.load(file, Loader = yaml.FullLoader)
print(res)

a.yml 文件中的內容如下所示,冒號代表字典,字典結構可以嵌套,也可以生成列表,具體格式參考下面的 a.yml 文件。

a.yml

name: 'skx'
age: 18
data:
 a: 1
 b: 2
 c: 3
 d: 4
list:
 - a
 - b
 - c
 - d

打印的結果如下所示,生成四個字典元素,第三個字典元素為嵌套字典結構,第四個字典對應的 value 為列表。

{'name': 'skx', 'age': 18, 'data': {'a': 1, 'b': 2, 'c': 3, 'd': 4}, 'list': ['a', 'b', 'c', 'd']}

如果將 a.yml 文件中的數據改為如下結構,則生成一個純列表,打印的結果如下所示。

a.yml

- a
- b
- c
- d
['a', 'b', 'c', 'd']

有了 yml 文件,我們就可以將測試數據放到 yml 文件中,從文件中獲取參數,傳入測試函數,完成測試。還是通過例子來講解,yml_test2.yml 中是一個列表,每個列表元素是一個字典,字典中有兩個元素,name 和 age,使用 file_data 直接可以將 yml_test2.yml 傳入測試用例中。

read_yml2.py

#coding=utf-8
import unittest
from ddt import ddt
from ddt import file_data
import yaml

# 類之前定義裝飾器,表示在類中要使用ddt了
@ddt
class MyTestCase(unittest.TestCase):
 def setUp(self) -> None:
 print('{:=^20}'.format("測試開始"))
 def tearDown(self) -> None:
 print("{:=^20}".format('測試結束'))

 @file_data('read_yml2_data.yml')
 def test_yam(self, **kwargs):
 # 獲取參數中key 為 name 的 value
 print(kwargs["name"])
 # 獲取為 text 的 value
 print(kwargs["age"])

if __name__ == '__main__':
 unittest.main(verbosity=2)

read_yml2_data.yml

-
 name: 'Tom'
 age: 13
-
 name: 'Carl'
 age: 20
-
 name: 'Edward'
 age: 28

運行結果:

========測試開始========
Tom
13
========測試結束========
========測試開始========
Carl
20
========測試結束========
========測試開始========
Edward
28
========測試結束========

4 UnitTest 斷言用法

在 UnitTest中,TestCase 已經提供有封裝好的斷言方法進行斷言校驗。

斷言:用于校驗實際結果與預期結果是否匹型,在斷言的內容選擇上,是有要求的。

斷言強調的是對于整個測試流程的結果進行判斷,所以斷言的內容是極為核心的。

上面的代碼

#coding=utf-8
import unittest
from ddt import ddt
from ddt import file_data
import yaml

# 類之前定義裝飾器,表示在類中要使用ddt了
@ddt
class MyTestCase(unittest.TestCase):
 def setUp(self) -> None:
 print('{:=^20}'.format("測試開始"))
 def tearDown(self) -> None:
 print("{:=^20}".format('測試結束'))

 @file_data('read_yml2_data.yml')
 def test_yam(self, **kwargs):
 # 獲取參數中key 為 name 的 value
 name = kwargs['name']
 print(name)
 # 這里做斷言,當斷言不相等的時候返回 msg
 self.assertEqual(name, 'Tom', msg = 'NotEqual')
 # 獲取為 text 的 value
 print(kwargs["age"])

if __name__ == '__main__':
 unittest.main()
-
 name: 'Tom'
 age: 13
-
 name: 'Carl'
 age: 20
-
 name: 'Edward'
 age: 28

可以看到第一個例子執(zhí)行正確,后面的例子,執(zhí)行結果和預期不一致,返回 NotEqual,左側的日志可以看到第一個用例執(zhí)行成功,后面兩個例子執(zhí)行失敗。

unittest 框架的 TestCase 類提供以下方法用于測試結果的判斷

方法 檢查
assertEqual(a, b) a ==b
assertNotEqual(a, b) a !=b
assertTrue(x) bool(x) is True
assertFalse(x) Bool(x) is False
assertIs(a, b) a is b
assertIsNot(a, b) a is not b
assertIsNone(x) x is None
assertIsNotNone(x) x is not None
assertIn(a, b) a in b
assertNotIn(a, b) a not in b
assertIsInstance(a, b) isinstance(a,b)
assertNotIsInstance(a, b) not isinstance(a,b)

5 UnitTest.skip()用法

假設我們有很多測試用例,有些我們需要執(zhí)行,有些我們不想執(zhí)行,不想執(zhí)行的測試用例如何才能不執(zhí)行呢,這就需要用到 skip。

Skip用法:

  • 在 Case 中,對于不需要運行的用例或者特定條件下不執(zhí)行的用例,可以應用 skip() 來實現有條件執(zhí)行,或者絕對性跳過,用于對指定用例進行不執(zhí)行操作
  • skip通過裝飾器進行使用

還是通過案例進行講解,下面有 6 個測試用例,2-5測試用例被屏蔽了,使用的方法不同,

  • @unittest.skip(“xxx”)是無條件跳過,xxx為跳過的理由
  • unittest.skipIf(1 < 2, ‘xxx'),條件為 True 時跳過
  • @unittest.skipUnless(1 > 2, ‘xxx'),條件為 False 時跳過,和 skipIf 更好相反
  • @unittest.expectedFailure,如果用例執(zhí)行失敗,則不計入失敗的case數中

直接看例子更加直觀

skip_t.py

#coding=utf-8
import unittest

class MyTestCase(unittest.TestCase):
 def setUp(self) -> None:
 pass

 def tearDown(self) -> None:
 pass

 def test_1(self):
 print('1')

 # 無條件跳過該條用例
 @unittest.skip("不想運行")
 def test_2(self):
 print('2')

 # 有條件跳過操作,條件為True跳過
 @unittest.skipIf(1 < 2, '1 < 2 為True,條件成立,跳過執(zhí)行')
 def test_3(self):
 print('3')

 # 有條件執(zhí)行跳過,條件為False跳過
 @unittest.skipUnless(1 > 2, 'Unless的理由,條件為False,跳過執(zhí)行')
 def test_4(self):
 print('4')

 # 如果用例執(zhí)行失敗,則不計入失敗的case數中
 @unittest.expectedFailure
 def test_5(self):
 print('5')
 self.assertEqual(4, 3, msg = 'NotEqual')

 def test_6(self):
 print('6')

if __name__ == "__main__":
 unittest.main()

執(zhí)行結果如下,可以看到,test_2,test_3,test_4 跳過,test_5執(zhí)行失敗,但是不計入case數中

5 UnitTest測試套件及runner應用

測試套件 Suite 作用:

  1. 用于給測試用例進行排序
  2. 管理測試用例

通過例子講解最容易理解,看一個最簡單的例子,下面的代碼中有五個測試用例,程序運行的結果和測試用例在代碼中位置是沒有關系的,結果永遠打印 1 2 3 4 5,這是因為測試用例的執(zhí)行順序默認是按照字典順序執(zhí)行的,如何才能控制測試用例的執(zhí)行順序呢,這就需要使用測試套件了。

suite_case.py

import unittest
class MyTestCase(unittest.TestCase):
 def setUp(self) -> None:
 pass

 def tearDown(self) -> None:
 pass
 
 def test_2(self):
 print("2")
 
 def test_1(self):
 print("1")

 def test_4(self):
 print("4")

 def test_3(self):
 print("3") 

 def test_5(self):
 print("5")

if __name__ == "__main__":
 unittest.main()

運行結果:

1
2
3
4
5

再建一個py 文件

#coding=utf-8
import unittest
from suite_case import *

# 創(chuàng)建一個測試套件 list
suite = unittest.TestSuite()
# 方法一,添加測試用例(子元素)到測試套件(集合)
suite.addTest(MyTestCase('test_3'))
suite.addTest(MyTestCase("test_1"))
suite.addTest(MyTestCase("test_5"))

# 套件通過TextTestRunner對象運行,功能相當于unittest.main()
runner = unittest.TextTestRunner()
runner.run(suite)

我們首先創(chuàng)建一個測試套件,然后向測試套件中添加測試用例,最后創(chuàng)建 TextTestRunner 對象,調用 run 函數運行測試用例。這樣我們不僅可以控制測試用例的執(zhí)行順序,還可以控制運行哪個測試用例。

結果如下:

3
1
5

上面的方法每次添加測試用例都需要調用 addTest 函數,能不能一次添加多個測試用例呢,可以的,將測試用例寫成一個列表,通過addTests 函數可以一次添加多個測試用例

#coding=utf-8
import unittest
from suite_case import *

# 創(chuàng)建一個測試套件 list
suite = unittest.TestSuite()

# 方法二,批量添加測試用例
cases = [MyTestCase('test_3'), MyTestCase('test_1'), MyTestCase('test_5')]
suite.addTests(cases)

# 套件通過TextTestRunner對象運行,功能相當于unittest.main()
runner = unittest.TextTestRunner()
runner.run(suite)

如果測試用例非常多,或者有多個文件中的測試用例都需要測試,這樣添加也不是很方便,我們好可以按照文件路徑,將該路徑下需要測試的文件添加進測試套件中

#coding=utf-8
import unittest
from suite_case import *

# 創(chuàng)建一個測試套件 list
suite = unittest.TestSuite()

# 方法三,批量運行多個unittest類
test_dir = './'
# start_dir 參數指定文件路徑,pattern 執(zhí)行規(guī)則,'s*.py' 表示以 "s" 開頭,".py" 的都加入測試套件中
discover = unittest.defaultTestLoader.discover(start_dir = test_dir, pattern = 's*.py')

runner = unittest.TextTestRunner()
runner.run(discover)		# 通過 run 函數運行測試用例

還可以執(zhí)行類的名字,執(zhí)行該類下面所有的測試用例,使用 loadTestsFromName 函數或者 loadTestsFromTestCase 都可以,案例如下:

#coding=utf-8
import unittest
from suite_case import *

# 創(chuàng)建一個測試套件 list
suite = unittest.TestSuite()

# 方法四,給出文件名和類名,就能測試所有的測試用例
suite.addTests(unittest.TestLoader().loadTestsFromName('suite.MyTestCase'))

# 套件通過TextTestRunner對象運行,功能相當于unittest.main()
runner = unittest.TextTestRunner()
runner.run(suite)
#coding=utf-8
import unittest
from suite_case import *

# 創(chuàng)建一個測試套件 list
suite = unittest.TestSuite()

# 方法五,給出類名,就能測試所有的測試用例
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(MyTestCase))
# 套件通過TextTestRunner對象運行,功能相當于unittest.main()
runner = unittest.TextTestRunner()
runner.run(suite)

6 UnitTest+HTMLTestRunner 自動化實現

通過 HTMLTestRunner 我們可以將測試結果生成 html 文件,通過網頁端進行查看。步驟如下:

1. 導入環(huán)境

下載 HTMLTestRunner.py 文件,下載地址

點進入HTMLTestRunner.py,右鍵另存為就可以下載到本地。

下載后,把HTMLTestRunner.py 文件復制到 Python 安裝路徑下的 lib 文件夾中(我的安裝路徑是:C:\Users\Administrator\AppData\Local\Programs\Python\Python38\Lib)。在python3中用HTMLTestRunner.py 報 importError“:No module named 'StringIO'解決辦法,原因是官網的是python2語法寫的,看官手動把官網的 HTMLTestRunner.py 改成 python3 的語法。

修改內容:

  • 第94行,將import StringIO修改成import io
  • 第539行,將self.outputBuffer = StringIO.StringIO()修改成self.outputBuffer = io.StringIO()
  • 第642行,將if not rmap.has_key(cls):修改成if not cls in rmap:
  • 第631行,將print >> sys.stderr, ‘\nTime Elapsed: %s' % (self.stopTime-self.startTime)修改成print(sys.stderr, ‘\nTime Elapsed: %s' % (self.stopTime-self.startTime))
  • 第766行,將uo = o.decode(‘latin-1')修改成uo = e
  • 第772行,將ue = e.decode(‘latin-1')修改成ue = e

2. 導包

from HTMLTestRunner import HTMLTestRunner

下面就通過案例進行演示

suite_case.py 文件

import unittest
class MyTestCase(unittest.TestCase):
 def setUp(self) -> None:
 pass

 def tearDown(self) -> None:
 pass

 def test_2(self):
 print("2")

 def test_1(self):
 print("1")

 def test_4(self):
 print("4")

 def test_3(self):
 print("3")

 def test_5(self):
 print("5")

if __name__ == "__main__":
 unittest.main()
#coding=utf-8
import unittest
from suite_case import MyTestCase
from HTMLTestRunner import HTMLTestRunner
import os

suite = unittest.TestSuite()

report_path = './report/'
report_file = report_path + 'report.html'
# 路徑不存在就創(chuàng)建一個文件夾
if not os.path.exists(report_path):
 os.mkdir(report_path)
else:
 pass

report_name = '測試報告名稱'
report_title = '測試報告標題'
report_desc = '測試報告描述'

with open(report_file, 'wb') as report:
 suite.addTests(unittest.TestLoader().loadTestsFromTestCase(MyTestCase))
 # 套件結合 TextTestRunner 對象進行運行,相當于 unittest.mian()
 # 如果結合 HTMLTestRunner 使用,則需要調用 HTMLTestRunner 中的運行器
 runner = HTMLTestRunner(stream = report, title = report_title, description = report_desc)
 runner.run(suite)

運行 就會成成 report.html 文件,瀏覽器打開該文件,如下所示:

這樣就生成一個比較直觀的測試報告

總結

到此這篇關于Python自動化之UnitTest框架實戰(zhàn)的文章就介紹到這了,更多相關Python自動化UnitTest框架實戰(zhàn)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • python機器學習之神經網絡(一)

    python機器學習之神經網絡(一)

    這篇文章主要為大家詳細介紹了python機器學習之神經網絡第一篇,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • 一種Python工具的License授權機制詳解

    一種Python工具的License授權機制詳解

    這篇文章主要介紹了一種Python工具的License授權機制,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • 微信跳一跳python代碼實現

    微信跳一跳python代碼實現

    這篇文章主要為大家詳細介紹了微信跳一跳python代碼實現,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • python按綜合、銷量排序抓取100頁的淘寶商品列表信息

    python按綜合、銷量排序抓取100頁的淘寶商品列表信息

    這篇文章主要為大家詳細介紹了python按綜合、銷量排序抓取100頁的淘寶商品列表信息,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • 利用Python腳本實現傳遞參數的三種方式分享

    利用Python腳本實現傳遞參數的三種方式分享

    使用python腳本傳遞參數在實際工作過程中還是比較常用。這篇文章為大家總結了三個常用的方式,感興趣的小伙伴可以跟隨小編一起學習一下
    2022-12-12
  • 判斷Threading.start新線程是否執(zhí)行完畢的實例

    判斷Threading.start新線程是否執(zhí)行完畢的實例

    這篇文章主要介紹了判斷Threading.start新線程是否執(zhí)行完畢的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • Python?虛擬環(huán)境的價值和常用命令詳解

    Python?虛擬環(huán)境的價值和常用命令詳解

    在實際項目開發(fā)中,我們通常會根據自己的需求去下載各種相應的框架庫,如Scrapy、Beautiful?Soup等,但是可能每個項目使用的框架庫并不一樣,或使用框架的版本不一樣,今天給大家分享下Python?虛擬環(huán)境的價值和常用命令,感興趣的朋友一起看看吧
    2022-05-05
  • 更改Python命令行交互提示符的方法

    更改Python命令行交互提示符的方法

    這篇文章主要介紹了更改Python命令行交互提示符的方法,本文還介紹了一款開源軟件iPython和Python的distutils,需要的朋友可以參考下
    2015-01-01
  • Python實現對比不同字體中的同一字符的顯示效果

    Python實現對比不同字體中的同一字符的顯示效果

    這篇文章主要介紹了Python實現對比不同字體中的同一字符的顯示效果,也就是對比不同字體中某個字的顯示效果,這在做設計時非常有用,需要的朋友可以參考下
    2015-04-04
  • Python RabbitMQ消息隊列實現rpc

    Python RabbitMQ消息隊列實現rpc

    這篇文章主要介紹了python 之rabbitmq實現rpc,主要實現客戶端通過發(fā)送命令來調用服務端的某些服務,服務端把結果再返回給客戶端,感興趣的小伙伴們可以參考一下
    2018-05-05

最新評論