介面自動化實戰之框架搭建
新建專案及python包
建立一個新的python專案,在下面建一個run.py檔案作為unittest的TestRunner來跑測試用例;再新建一個tests包放測試用例:
新建config包來存放配置檔案:
新建libs包存放第三方模組:
新建reports包存放執行測試用例後生成的測試報告:
新建data包存放呼叫介面和斷言時所需要準備的測試資料:
新建common包存放公共模組:
新建logs包存放日誌:
跑通用例
接著在tests包下新建一個test_demo.py,先不寫任何實質上的內容,僅僅是個為了測試的空殼。
- test_demo.py
import unittest
class Test_demo(unittest.TestCase):
#先什麼都不寫,pass當做這個用例100%能執行通過!
def test_demo(self):
pass
接著我們就開始寫run.py
- run.py
import unittest
import os
from datetime import datetime
from config import config
from libs.HTMLTestRunnerNew import HTMLTestRunner
#載入用例
loader = unittest.TestLoader()
#自動檢索所有測試用例
"""
問題1:路徑的重用
這裡我們準備傳入測試用例所在路徑:tests,直接在這裡用變數定義出來自然是最簡單的,
但後面可能還需要更多需要傳入路徑的場景,所以我們需要找個地方配置所有的路徑。而一
想到配置,我們就會想到放到config目錄下。但具體我們應該用什麼配置呢?yaml嗎?但
yaml只適合配置靜態的配置,路徑是會隨著專案的轉移而發生變化,所以我們可以用一個py
檔案來配置所有的路徑資訊。在config.py定義了測試用例的路徑後,我們可以直接import
過來。
@路徑配置詳見config.py
"""
cases = loader.discover(config.CASES_PATH)
"""
問題2:報告時間戳格式的生成
這裡我們需要定義報告的名稱。而每次生成的報告如果以同一檔名(如:report.html)命名
的話,就會覆蓋之前的報告內容。當我們需要找回歷史報告(如上個月的報告)時就找不到了,所以
我們需要用時間戳格式命名報告的檔名,這樣不僅執行時間可以一目瞭然,還能找到對應時間的
報告回顧。
"""
#定義時間戳
time_format = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
#測試報告檔名稱
report_name = "report-{}.html".format(time_format)
#測試報告路徑
report_path = os.path.join(config.REPORT_PATH,report_name)
#執行測試用例
with open(report_path,mode='wb') as f:
#這裡我們用第三方模組:HTMLTestRunnerNew來生成測試報告
runner = HTMLTestRunner(
f,
title = "介面自動化測試報告",
description = "測試報告",
tester = "tom"
)
#執行測試用例
runner.run(cases)
問題1中我們需要把專案中的所有包的路徑都存放到py檔案中,我們需要在包裡面新建一個config.py:
- config.py
import os
#配置檔案路徑
CONFIG_PATH = os.path.dirname(os.path.abspath(__file__))
#專案路徑
ROOT_PATH = os.path.dirname(CONFIG_PATH)
#測試用例路徑
CASES_PATH = os.path.join(ROOT_PATH,"tests")
#測試報告路徑
REPORT_PATH = os.path.join(ROOT_PATH,"reports")
在libs包下存放剛剛用到的第三方模組HTMLTestRunnerNew.py:
各個包、TestCase、TestRunner都準備好後,接下來我們去到run.py執行測tests下的所有測試用例,執行結果如下,表明unittest中的TestCase和TestRunner是能跑通的:
而如果執行時報了下面的錯,則表明測試用例是有問題的,要麼是缺少__init__.py檔案,要麼是測試用例命名不規範(注意,命名最好以test開頭),要麼是測試用例內部的程式碼出了問題:
通用模組的構建
我們需要把之前講到的各個測試框架的元件加到common中,包括:excel_handler、logging_handler、yaml_handler、request_handler、sql_handler:
excel_handler
import openpyxl
import pprint
class excel_handler():
"""初始化例項引數"""
def __init__(self,filepath):
self.filepath = filepath
self.workbook = None
"""定義open_file方法,返回workbook物件"""
def open_file(self):
workbook = openpyxl.load_workbook(self.filepath)
self.workbook = workbook
return workbook
"""通過workbook物件獲取sheet物件"""
def get_sheet(self,name):
workbook = self.open_file()
sheet = workbook[name]
return sheet
"""獲取表單裡的每一個單元格物件的value"""
def get_data(self,name):
#獲取表單物件
sheet = self.get_sheet(name)
#獲取表單物件中的所有行
rows = list(sheet.rows)
#定義一個列表,用來接收每一行的值
data = []
#定義一個列表,獲取所有的標題
tittles = []
#遍歷第一行rows[0],獲取所有行的value屬性,放入tittles中
for tittle in rows[0]:
tittles.append(tittle.value)
#遍歷第二行後的所有資料(排除掉第一行是因為已經遍歷完了第一行的標題)
for row in rows[1:]:
#定義一個字典,存放每一行的值,每一個值是一個鍵值對,key是標題,值是該行對應的value屬性。
row_data = {}
#遍歷拿到的每一行,獲取每一行的每一個單元格放入row_data中.其中key為標題,value為該單元格對應的值.
for index,cell in enumerate(row):
row_data[tittles[index]] = cell.value
#把每一行的資料放入data中
data.append(row_data)
return data
"""對單元格的value屬性賦值,寫入到excel中"""
def write(self, sheet_name, row, column, data):
sheet = self.get_sheet(sheet_name)
sheet.cell(row, column).value = data
self.save()
self.close()
"""對excel做修改後,儲存excel檔案"""
def save(self):
self.workbook.save(self.file_path)
"""關閉workbook物件,釋放記憶體"""
def close(self):
self.workbook.close()
logging_handler
import logging
def log_handler(
logger_name = "logger",
logger_level = "DEBUG",
stream_level = "DEBUG",
file_name = "None",
file_level = "DEBUG",
fmt = '%(asctime)s--%(filename)s--No:%(lineno)d--%(levelname)s:%(message)s',
):
#初始化日誌收集器
logger = logging.getLogger(logger_name)
#設定日誌收集器的日誌級別
logger.setLevel(logger_level)
#初始化流處理器
stream_handler = logging.StreamHandler()
#設定流處理器的日誌級別
stream_handler.setLevel(stream_level)
#將流處理器與日誌收集器繫結起來
logger.addHandler(stream_handler)
#設定格式
fmt = logging.Formatter(fmt)
#設定流處理器的日誌輸出格式
stream_handler.setFormatter(fmt)
#如果傳入的file_name不為空,則初始化檔案處理器
if file_name:
#初始化檔案處理器
file_handler = logging.FileHandler(file_name,encoding='UTF-8')
#設定檔案處理器的日誌級別
file_handler.setLevel(file_level)
#將檔案處理器與日誌收集器繫結起來
logger.addHandler(file_handler)
#設定檔案處理器的日誌輸出格式
file_handler.setFormatter(fmt)
return logger
yaml_handler
import yaml
def read_yaml(file):
"""讀取 yaml 檔案"""
with open(file, encoding='utf8') as f:
conf = yaml.load(f, Loader=yaml.SafeLoader)
return conf
def write_yaml(file, data):
with open(file, 'w', encoding='utf8') as f:
yaml.dump(data, f)
request_handler
import requests
import logging
def requests_handler(
#準備請求介面時所需要的引數:請求地址、請求方法、請求頭、url引數、form引數、json引數
url,
method = "get",
headers = None,
params = None,
data = None,
json = None,
):
"""由於requests裡面封裝的各種請求方法(get、post、put、delete、head等)最後都要呼叫request方法,所以
可以直接呼叫requests完成所有請求方法的呼叫,而不用再一個個請求方法封裝"""
req = requests.request(method,
url,
data = data,
json = json,
params = params,
headers = headers
)
try:
#由於介面最後返回的都是json格式的資料,所以這裡呼叫json方法返回json格式資料
return req.json()
except Exception as e:
#如果呼叫json方法報錯,則說明返回格式不是json格式,這時應該拋異常
logging.error("返回的格式不是json格式{}".format(e))
return None
sql_handler
import pymysql
from pymysql.cursors import DictCursor
class mysql_handler():
#初始化,準備需要建立資料庫連線的所有引數
def __init__(
self,
host = None,
port = 3306,
user = None,
password = None,
charset="utf8",
cursorclass=DictCursor
):
#建立資料庫連線,傳入準備好的引數
self.con = pymysql.connect(
host=host,
port=port,
user=user,
password=password,
charset=charset,
cursorclass=cursorclass
)
self.cursor = self.con.cursor()
#查詢方法,傳入需要執行查詢的sql,以及控制是選擇fetchall還是fetchone的引數is_one
def query(self,sql,is_one=True):
#呼叫遊標物件的execute方法執行查詢的sql
self.cursor.execute(sql)
#如果is_one為true,則只返回結果中的第一條記錄
if is_one:
return self.cursor.fetchone()
#如果is_one為false,則返回結果中的所有記錄
return self.cursor.fetchall()
#關閉遊標物件及連線物件
def close(self):
self.cursor.close()
self.con.close()
相關文章
- 介面自動化(四):框架搭建(Python)框架Python
- 介面自動化測試框架搭建總結框架
- 介面自動化測試框架搭建的思路框架
- pytest+request+allure 介面自動化框架搭建分享框架
- 介面自動化測試實戰之智慧場景如何攻破
- Jmeter+Ant+Jenkins介面自動化測試框架搭建for WindowsJMeterJenkins框架Windows
- Java語言搭建介面自動化框架學習八(鑑權)Java框架
- 基於Python+requests搭建的自動化框架-實現流程化的介面串聯Python框架
- 介面自動化測試框架 HttpFPT框架HTTP
- Java語言搭建介面自動化框架學習一(單介面請求和響應)Java框架
- 介面自動化之介面整理(抓包)
- 四.unittest介面自動化框架介紹框架
- 【python介面自動化】初識unittest框架Python框架
- Jmeter+Ant+Jenkins介面自動化框架JMeterJenkins框架
- 常用網路介面自動化測試框架框架
- 介面自動化測試之PHPUnit-框架程式碼編寫2PHP框架
- Web自動化之Headless Chrome編碼實戰WebChrome
- 介面自動化之實現日誌記錄封裝封裝
- 肖sir__po框架之ui自動化框架框架UI
- 關於介面測試——自動化框架的設計與實現框架
- Jmeter+Ant+Jenkins介面自動化框架(續)JMeterJenkins框架
- 基於Python的介面自動化實戰-基礎篇之讀寫配置檔案Python
- 搭建 WPF 上的 UI 自動化測試框架UI框架
- Playwright自動化測試工具之元素定位實戰
- 『居善地』介面測試 — 9、介面自動化框架的傳送郵件實現框架
- UI自動化測試實戰UI
- 基於RestAssured實現介面自動化REST
- Linux下搭建介面自動化測試平臺Linux
- Httpclient 介面自動化HTTPclient
- 全自動化介面
- 介面自動化之引數動態生成替換
- Keil中搭建自動化單元測試框架Unity框架Unity
- 『居善地』介面測試 — 7、介面自動化測試框架的設計與實現框架
- 測試開發之自動化篇-自動化測試框架設計框架
- [android]android自動化測試十三之monkeyRunner自動化框架Android框架
- 介面自動化與ui自動化區別UI
- 介面自動化測試框架--http請求的get、post方法的實現框架HTTP
- 肖sir__介面測試之python+rquest+unittest分層自動化框架Python框架