本文章主要講解Python自動化測試中測試用例的數據分離,在自動化測試中能夠更好的管理測試用例以及代碼,除此之外下方有系列文章的傳送門,還在持續更新中,感興趣的小伙伴也可以前往查看,話不多說,讓我們一起看看吧~
系列文章:
系列文章1:【Python自動化測試1】遇見Python之美
系列文章2:【Python自動化測試2】Python安裝配置及PyCharm基本使用
系列文章3:【Python自動化測試3】初識數據類型與基礎語法
系列文章4:【Python自動化測試4】字符串知識總結
系列文章5:【Python自動化測試5】列表與元組知識總結
系列文章6:【Python自動化測試6】字典與集合知識總結
系列文章7:【Python自動化測試7】數據運算符知識合集
系列文章8:【Python自動化測試8】流程控制語句講解
系列文章9:【Python自動化測試9】函數知識合集
系列文章10:【Python自動化測試10】文件基礎操作
系列文章11:【Python自動化測試11】模塊、包與路徑知識合集
系列文章12:【Python自動化測試12】異常處理機制知識合集
系列文章13:【Python自動化測試13】類、對象、屬性與方法知識合集
系列文章14:【Python自動化測試14】Python自動化測試基礎與進階練習題
系列文章15:【Python自動化測試15】unittest測試框架的核心概念與作用
如下代碼所示,在測試一個函數時我們需要編寫測試用例並斷言,通過框架及相關方法來進行測試,這樣做會產生一個問題,對於一個龐大的軟件、游戲而言,可能會有上萬條測試用例,如果數據與代碼存在綁定關系,很明顯會有很多弊端,例如查詢、更改測試數據等,這意味著代碼和測試數據將會一起進行維護,維護成本會隨著時間以及數量不斷的增加,且有互相依賴性。
故此我們需要把數據與代碼區分開來,那麼分開的這個過程和結果,我們就稱之為數據分離,進行單獨性的管理。 那麼測試用例的數據分離,就是將用例數據與代碼區分開的意思。如果測試數據需要進行修改或添加,那麼我們只需要維護測試數據即可,而測試用例是不需要進行改動的。
""" 一共涉及到4個知識內容: 1、setUp 測試用例前執行 2、teardown 測試用例後執行 3、setUpClass 測試類之前執行 4、teardownClass 測試類之後執行 """
import unittest
def login(username=None, password=None):
if username is None or password is None:
return {
"code": 400, "msg": "用戶名或密碼為空" }
if username == "萌笑天" and password == 123456:
return {
"code": 200, "msg": "登錄成功" }
return {
"code": 300, "msg": "用戶名或密碼錯誤" }
class TestLogin(unittest.TestCase):
def setUp(self) -> None:
"""每個測試用例之前都會執行的代碼"""
print("每個測試用例之前的准備工作")
print("假裝正在連接數據庫...")
def tearDown(self) -> None:
"""每個測試用例之後都會執行的代碼,無論測試用例是否通過,tearDown均會執行"""
print("每個測試用例執行之後都需要做的事情")
print("假裝正在斷開數據庫")
@classmethod
def setUpClass(cls) -> None:
"""每個測試類之前都會執行的"""
print("每個測試類之前只執行一次")
@classmethod
def tearDownClass(cls) -> None:
"""每個測試類之後都會執行的"""
print("每個測試類之後會執行一次")
def test_login_success(self):
username = "萌笑天"
password = 123456
expected = {
"code": 200, "msg": "登錄成功"}
actual = login(username,password)
self.assertEqual(expected, actual) # 斷言預期結果與實際結果是否相等
def test_login_error(self):
username = "萌笑天"
password = 1234567
expected = {
"code": 1100, "msg": "用戶名或密碼錯誤" }
actual = login(username,password)
self.assertEqual(expected, actual)
進行數據分離的核心就是將數據與代碼分開,結合我們前面所學的知識,我們可以把一些測試數據以列表嵌套字典的形式進行存儲,轉化後的代碼為:
""" TODO:請注意,下面的這些代碼並非是最佳的優化途徑,只是為了在配合數據分離的知識內容進行講解 TODO:在後續會逐漸進行優化,采取更優策略,後續文章會進行說明 """
import unittest
login_data = [
{
"username": "萌笑天", "password": 123456, "expected": {
"code": 200, "msg": "登錄成功"}},
{
"username": "萌笑天", "password": 1234567, "expected": {
"code": 1100, "msg": "用戶名或密碼錯誤"}}
]
def login(username=None, password=None):
if username is None or password is None:
return {
"code": 400, "msg": "用戶名或密碼為空" }
if username == "萌笑天" and password == 123456:
return {
"code": 200, "msg": "登錄成功" }
return {
"code": 300, "msg": "用戶名或密碼錯誤" }
class TestLogin(unittest.TestCase):
def setUp(self) -> None:
"""每個測試用例之前都會執行的代碼"""
print("每個測試用例之前的准備工作")
print("假裝正在連接數據庫...")
def tearDown(self) -> None:
"""每個測試用例之後都會執行的代碼,無論測試用例是否通過,tearDown均會執行"""
print("每個測試用例執行之後都需要做的事情")
print("假裝正在斷開數據庫")
@classmethod
def setUpClass(cls) -> None:
"""每個測試類之前都會執行的"""
print("每個測試類之前只執行一次")
@classmethod
def tearDownClass(cls) -> None:
"""每個測試類之後都會執行的"""
print("每個測試類之後會執行一次")
def test_login_success(self):
data = login_data[0]
username = data["username"]
password = data["password"]
expected = data["expected"]
actual = login(username,password)
self.assertEqual(expected, actual)
def test_login_error(self):
data = login_data[1]
username = data["username"]
password = data["password"]
expected = data["expected"]
actual = login(username,password)
self.assertEqual(expected, actual)
如上代碼所示,目前測試數據和代碼是實現了分離,這樣當我們想進行測試數據維護或代碼維護時就會更加便捷,雖然這樣的方式並不是最有效的,但主要是為了讓大家先行理解數據分離的概念,將會在後續的文章中繼續進行優化。
正常而言我們要進行模塊管理,即代碼屬於一個模塊(py文件),而數據屬於一個模塊,故此我們實際的data數據並不是放在代碼模塊中的,而應該是一個新的data.py的模塊文件,通過導入的方式進行調用,真實的項目裡亦是如此,如上代碼是方便新手進行理解所用:
E:\TestingSoftware\Python3.10.1(64x)\python.exe "E:\TestingSoftware\PyCharm\PyCharm Community Edition 2021.3\plugins\python-ce\helpers\pycharm\_jb_unittest_runner.py" --target test_login.TestLogin.test_login_error
Testing started at 10:49 ...
Launching unittests with arguments python -m unittest test_login.TestLogin.test_login_error in E:\TestingSoftware\Python3.10.1(64x)\PythonProject\CSDN自動化測試系列_第一節_Python基礎語法1
每個測試類之前只執行一次
每個測試用例之前的准備工作
假裝正在連接數據庫...
每個測試用例執行之後都需要做的事情
假裝正在斷開數據庫
{
'code': 300, 'msg': '用戶名或密碼錯誤'} != {
'code': 1100, 'msg': '用戶名或密碼錯誤'}
Expected :{
'code': 1100, 'msg': '用戶名或密碼錯誤'}
Actual :{
'code': 300, 'msg': '用戶名或密碼錯誤'}
<Click to see difference>
Traceback (most recent call last):
File "E:\TestingSoftware\Python3.10.1(64x)\PythonProject\CSDN自動化測試系列_第一節_Python基礎語法1\test_login.py", line 55, in test_login_error
self.assertEqual(expected, actual)
AssertionError: {
'code': 1100, 'msg': '用戶名或密碼錯誤'} != {
'code': 300, 'msg': '用戶名或密碼錯誤'}
- {
'code': 1100, 'msg': '用戶名或密碼錯誤'}
? ^^
+ {
'code': 300, 'msg': '用戶名或密碼錯誤'}
? ^
每個測試類之後會執行一次
Ran 1 test in 0.005s
FAILED (failures=1)
Process finished with exit code 1
""" 數據分離的流程: 1、excel編寫測試用例 2、通過Python讀取excel(讀取出來的格式就是列表嵌套字典: [{}, {}, {}] 3、導入測試用例函數 由上得知:目前只需要有一份excel版本的測試用例,並通過Python讀取即可 """
在路徑下創建一個case.xlsx,存儲測試用例數據
openpyxl
屬於第三方庫,故此我們需要先行安裝,已經安裝過會直接更新
如下代碼所示:我們用函數進行封裝,使用openpyxl進行excel數據的讀取
""" Python操作excel的思路: 1、先打開excel文件 2、選擇對應表格頁簽 3、讀取對應單元格數據 4、通過數據實現一定的操作 5、關閉excel文件 """
import openpyxl # 專門用於處理excel表格的庫,openpyxl擁有pandas的特性,並屬於輕量級庫,不會像pandas一樣更加復雜,更具優勢
from openpyxl.worksheet.worksheet import Worksheet
def read_excel(file_path, sheet_name ):
"""讀取excel的函數"""
workbook_data = openpyxl.load_workbook(file_path) # 打開名稱為case.xlsx的excel文檔
sheet: Worksheet = workbook_data[sheet_name] # 頁簽名為login,定位到login頁簽,指明sheet類型為Worksheet
# """如果我們想要獲取某一個單元格的數據,可以使用這個方式,但往往一個表格中有龐大的數據,我們並非通過這樣的方式獲取"""
# cell = sheet.cell(row=1, column=1) # 獲取單元格數據,row為行,column為列,代碼中表示的為第一行第一列的單元格
# print(cell.value) # 獲取第一行第一列的數據
"""更推薦的獲取方法是獲取所有數據,因為獲取的數據並非列表類型,我們還需要進一步進行數據轉換"""
values = list(sheet.values)
workbook_data.close() # 關閉文件
return values
data = read_excel("case.xlsx", "login")
print(data)
在之前提及過,測試用例的數據是列表嵌套字典的形式,而打印的數據則是列表嵌套元組的形式,並不符合預期,所以還需要進一步的轉換:
""" Python操作excel的思路: 1、先打開excel文件 2、選擇對應表格頁簽 3、讀取對應單元格數據 4、通過數據實現一定的操作 5、關閉excel文件 """
import openpyxl # 專門用於處理excel表格的庫,openpyxl擁有pandas的特性,並屬於輕量級庫,不會像pandas一樣更加復雜,更具優勢
from openpyxl.worksheet.worksheet import Worksheet
def read_excel(file_path, sheet_name ):
"""讀取excel的函數"""
workbook_data = openpyxl.load_workbook(file_path) # 打開名稱為case.xlsx的excel文檔
sheet: Worksheet = workbook_data[sheet_name] # 頁簽名為login,定位到login頁簽,指明sheet類型為Worksheet
# """如果我們想要獲取某一個單元格的數據,可以使用這個方式,但往往一個表格中有龐大的數據,我們並非通過這樣的方式獲取"""
# cell = sheet.cell(row=1, column=1) # 獲取單元格數據,row為行,column為列,代碼中表示的為第一行第一列的單元格
# print(cell.value) # 獲取第一行第一列的數據
"""更推薦的獲取方法是獲取所有數據,因為獲取的數據並非列表類型,我們還需要進一步進行數據轉換"""
values = list(sheet.values)
workbook_data.close() # 關閉文件
title = values[0]
rows = values[1:]
new_rows = [dict(zip(title, row)) for row in rows]
return new_rows
data = read_excel("case.xlsx", "login")
print(data)
好啦~以上就是本次文章分享的全部內容啦,你學會了嗎?希望能給大家帶來幫助哦!