簡書已停更,歡迎轉到個人博客查看對應教程:https://www.cnblogs.com/superhin/p/10339002.html
課程目錄
Python接口測試實戰1(上)- 接口測試理論
Python接口測試實戰1(下)- 接口測試工具的使用
Python接口測試實戰2 - 使用Python發送請求
Python接口測試實戰3(上)- Python操作數據庫
Python接口測試實戰3(下)- unittest測試框架
Python接口測試實戰4(上) - 接口測試框架實戰
Python接口測試實戰4(下) - 框架完善:用例基類,用例標簽,重新運行上次失敗用例
Python接口測試實戰5(上) - Git及Jenkins持續集成
Python接口測試實戰5(下) - RESTful、Web Service及Mock Server
更多學習資料請加添加作者微信:superz-han獲取
本節內容
- 數據分離 - 從Excel中讀取數據
- 增加log功能
- 發送郵件
- 使用配置文件
- 框架整理
數據分離 - 從Excel中讀取數據
之前的用例中,數據直接寫在代碼文件里,不利于修改和構造數據
這里我們使用Excel保存測試數據,實現代碼和數據的分離
新建Excel文件test_user_data.xlsx
包含兩個工作簿TestUserLogin
和TestUserReg
,并復制到項目根目錄下
更新: excel表格中,增加一個headers列,內容為json格式, 如下
TestUserLogin
case_name | url | method | headers | data | expect_res |
---|---|---|---|---|---|
test_user_login_normal | http://115.28.108.130:5000/api/user/login/ | POST | {} | {"name": "張三","password":"123456"} | <h1>登錄成功</h1> |
test_user_login_password_wrong | http://115.28.108.130:5000/api/user/login/ | POST | {} | {"name": "張三","password":"1234567"} | <h1>失敗,用戶名或密碼錯誤</h1> |
TestUserReg
case_name | url | method | headers | data | expect_res |
---|---|---|---|---|---|
test_user_reg_normal | http://115.28.108.130:5000/api/user/login/ | POST | {} | {"name": "范冰冰","password":"123456"} | "{"code: "100000","msg": "成功,"data": {""name": "范冰冰,"password": "e10adc3949ba59abbe56e057f20f883e"}}" |
test_user_reg_exist | http://115.28.108.130:5000/api/user/login/ | POST | {} | {"name": "張三","password":"123456"} | "{"code": "100001","msg": "失敗,用戶已存在","data": {"name": "張三","password":"e10adc3949ba59abbe56e057f20f883e"}}" |
Excel讀取方法:
Python我們使用三方庫xlrd來讀取Excel
安裝方法: pip install xlrd
import xlrd
wb = xlrd.open_workbook("test_user_data.xlsx") # 打開excel
sh = wb.sheet_by_name("TestUserLogin") # 按工作簿名定位工作表
print(sh.nrows) # 有效數據行數
print(sh.ncols) # 有效數據列數
print(sh.cell(0, 0).value) # 輸出第一行第一列的值`case_name`
print(sh.row_values(0)) # 輸出第1行的所有值(列表格式)
# 將數據和標題組裝成字典,使數據更清晰
print(dict(zip(sh.row_values(0), sh.row_values(1))))
# 遍歷excel,打印所有的數據
for i in range(sh.nrows):
print(sh.row_values(i))
結果:
3
5
case_name
['case_name', 'url', 'method', 'data', 'expect_res']
{'case_name': 'test_user_login_normal', 'url': 'http://115.28.108.130:5000/api/user/login/', 'method': 'POST', 'data': '{"name": "張三","password":"123456"}', 'expect_res': '<h1>登錄成功</h1>'}
['case_name', 'url', 'method', 'data', 'expect_res']
['test_user_login_normal', 'http://115.28.108.130:5000/api/user/login/', 'POST', '{"name": "張三","password":"123456"}', '<h1>登錄成功</h1>']
['test_user_login_password_wrong', 'http://115.28.108.130:5000/api/user/login/', 'POST', '{"name": "張三","password":"1234567"}', '<h1>失敗,用戶不存在</h1>']
封裝讀取excel操作:
新建read_excel.py
我們的目的是獲取某條用例的數據,需要3個參數,excel數據文件名(data_file),工作簿名(sheet),用例名(case_name)
如果我們只封裝一個函數,每次調用(每條用例)都要打開一次excel并遍歷一次,這樣效率比較低。
我們可以拆分成兩個函數,一個函數excel_to_list(data_file, sheet)
,一次獲取一個工作表的所有數據,另一個函數get_test_data(data_list, case_name)
從所有數據中去查找到該條用例的數據。
import xlrd
def excel_to_list(data_file, sheet):
data_list = [] # 新建個空列表,來乘裝所有的數據
wb = xlrd.open_workbook(data_file) # 打開excel
sh = wb.sheet_by_name(sheet) # 獲取工作簿
header = sh.row_values(0) # 獲取標題行數據
for i in range(1, sh.nrows): # 跳過標題行,從第二行開始取數據
d = dict(zip(header, sh.row_values(i))) # 將標題和每行數據組裝成字典
data_list.append(d)
return data_list # 列表嵌套字典格式,每個元素是一個字典
def get_test_data(data_list, case_name):
for case_data in data_list:
if case_name == case_data['case_name']: # 如果字典數據中case_name與參數一致
return case_data
# 如果查詢不到會返回None
if __name__ == '__main__': # 測試一下自己的代碼
data_list = excel_to_list("test_user_data.xlsx", "TestUserLogin") # 讀取excel,TestUserLogin工作簿的所有數據
case_data = get_test_data(data_list, 'test_user_login_normal') # 查找用例'test_user_login_normal'的數據
print(case_data)
輸出結果:
{'case_name': 'test_user_login_normal', 'url': 'http://115.28.108.130:5000/api/user/login/', 'method': 'POST', 'data': '{"name": "張三","password":"123456"}', 'expect_res': '<h1>登錄成功</h1>'}
用例中使用方法
test_user_login.py 部分
import unittest
import requests
from read_excel import * # 導入read_excel中的方法
import json # 用來轉化excel中的json字符串為字典
class TestUserLogin(unittest.TestCase):
@classmethod
def setUpClass(cls): # 整個測試類只執行一次
cls.data_list = excel_to_list("test_user_data.xlsx", "TestUserLogin") # 讀取該測試類所有用例數據
# cls.data_list 同 self.data_list 都是該類的公共屬性
def test_user_login_normal(self):
case_data = get_test_data(self.data_list, 'test_user_login_normal') # 從數據列表中查找到該用例數據
if not case_data: # 有可能為None
print("用例數據不存在")
url = case_data.get('url') # 從字典中取數據,excel中的標題也必須是小寫url
data = case_data.get('data') # 注意字符串格式,需要用json.loads()轉化為字典格式
expect_res = case_data.get('expect_res') # 期望數據
res = requests.post(url=url, data=json.loads(data)) # 表單請求,數據轉為字典格式
self.assertEqual(res.text, expect_res) # 改為assertEqual斷言
if __name__ == '__main__': # 非必要,用于測試我們的代碼
unittest.main(verbosity=2)
test_user_reg.py部分
import unittest
import requests
from db import *
from read_excel import *
import json
class TestUserReg(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.data_list = excel_to_list("test_user_data.xlsx", "TestUserReg") # 讀取TestUserReg工作簿的所有數據
def test_user_reg_normal(self):
case_data = get_test_data(self.data_list, 'test_user_reg_normal')
if not case_data:
print("用例數據不存在")
url = case_data.get('url')
data = json.loads(case_data.get('data')) # 轉為字典,需要取里面的name進行數據庫檢查
expect_res = json.loads(case_data.get('expect_res')) # 轉為字典,斷言時直接斷言兩個字典是否相等
name = data.get("name") # 范冰冰
# 環境檢查
if check_user(name):
del_user(name)
# 發送請求
res = requests.post(url=url, json=data) # 用data=data 傳字符串也可以
# 響應斷言(整體斷言)
self.assertDictEqual(res.json(), expect_res)
# 數據庫斷言
self.assertTrue(check_user(name))
# 環境清理(由于注冊接口向數據庫寫入了用戶信息)
del_user(name)
if __name__ == '__main__': # 非必要,用于測試我們的代碼
unittest.main(verbosity=2)
增加log功能
新建config.py文件
import logging
logging.basicConfig(level=logging.DEBUG, # log level
format='[%(asctime)s] %(levelname)s [%(funcName)s: %(filename)s, %(lineno)d] %(message)s', # log格式
datefmt='%Y-%m-%d %H:%M:%S', # 日期格式
filename='log.txt', # 日志輸出文件
filemode='a') # 追加模式
if __name__ == '__main__':
logging.info("hello")
運行后在當前目錄下生成log.txt
,內容如下:
[2018-09-11 18:08:17] INFO [<module>: config.py, 38] hello
Log Level:
- CRITICAL: 用于輸出嚴重錯誤信息
- ERROR: 用于輸出錯誤信息
- WARNING: 用于輸出警示信息
- INFO: 用于輸出一些提升信息
- DEBUG: 用于輸出一些調試信息
優先級 CRITICAL > ERROR > WARNING > INFO > DEBUG
指定level = logging.DEBUG
所有等級大于等于DEBUG的信息都會輸出
若指定level = logging.ERROR
WARNING,INFO,DEBUG小于設置級別的信息不會輸出
日志格式:
- %(levelno)s: 打印日志級別的數值
- %(levelname)s: 打印日志級別名稱
- %(pathname)s: 打印當前執行程序的路徑,其實就是sys.argv[0]
- %(filename)s: 打印當前執行程序名
- %(funcName)s: 打印日志的當前函數
- %(lineno)d: 打印日志的當前行號
- %(asctime)s: 打印日志的時間
- %(thread)d: 打印線程ID
- %(threadName)s: 打印線程名稱
- %(process)d: 打印進程ID
- %(message)s: 打印日志信息
項目使用log
將所有print改為log,如db.py
部分
import pymysql
from config import *
# 封裝數據庫查詢操作
def query_db(sql):
conn = get_db_conn()
cur = conn.cursor()
logging.debug(sql) # 輸出執行的sql
cur.execute(sql)
conn.commit()
result = cur.fetchall()
logging.debug(result) # 輸出查詢結果
cur.close()
conn.close()
return result
# 封裝更改數據庫操作
def change_db(sql):
conn = get_db_conn()
cur = conn.cursor()
logging.debug(sql) # 輸出執行的sql
try:
cur.execute(sql)
conn.commit()
except Exception as e:
conn.rollback()
logging.error(str(e)) # 輸出錯誤信息
finally:
cur.close()
conn.close()
用例中使用
import unittest
import requests
from read_excel import * # 導入read_excel中的方法
import json # 用來轉化excel中的json字符串為字典
from config import *
class TestUserLogin(unittest.TestCase):
@classmethod
def setUpClass(cls): # 整個測試類只執行一次
cls.data_list = excel_to_list("test_user_data.xlsx", "TestUserLogin") # 讀取該測試類所有用例數據
# cls.data_list 同 self.data_list 都是該類的公共屬性
def test_user_login_normal(self):
case_data = get_test_data(self.data_list, 'test_user_login_normal') # 從數據列表中查找到該用例數據
if not case_data: # 有可能為None
logging.error("用例數據不存在")
url = case_data.get('url') # excel中的標題也必須是小寫url
data = case_data.get('data') # 注意字符串格式,需要用json.loads()轉化為字典格式
expect_res = case_data.get('expect_res') # 期望數據
res = requests.post(url=url, data=json.loads(data)) # 表單請求,數據轉為字典格式
logging.info("測試用例:{}".format('test_user_login_normal'))
logging.info("url:{}".format(url))
logging.info("請求參數:{}".format(data))
logging.info("期望結果:{}".format(expect_res))
logging.info("實際結果:{}".format(res.text)
self.assertEqual(res.text, expect_res) # 斷言
if __name__ == '__main__':
unittest.main(verbosity=2)
項目下log.txt
輸出結果:
[2018-09-13 10:34:49] INFO [log_case_info: case_log.py, 8] 測試用例:test_user_login_normal
[2018-09-13 10:34:49] INFO [log_case_info: case_log.py, 9] url:http://115.28.108.130:5000/api/user/login/
[2018-09-13 10:34:49] INFO [log_case_info: case_log.py, 10] 請求參數:{"name": "張三","password":"123456"}
[2018-09-13 10:34:49] INFO [log_case_info: case_log.py, 11] 期望結果:<h1>登錄成功</h1>
[2018-09-13 10:34:49] INFO [log_case_info: case_log.py, 12] 實際結果:<h1>登錄成功</h1>
因為每個用例都要輸出很多log信息,我們封裝一個case_log
的函數
項目下新建case_log.py
from config import *
import json
def log_case_info(case_name, url, data, expect_res, res_text):
if isinstance(data,dict):
data = json.dumps(data, ensure_ascii=False) # 如果data是字典格式,轉化為字符串
logging.info("測試用例:{}".format(case_name))
logging.info("url:{}".format(url))
logging.info("請求參數:{}".format(data))
logging.info("期望結果:{}".format(expect_res))
logging.info("實際結果:{}".format(res_text)
簡化后的用例log輸出
import unittest
import requests
from read_excel import *
import json
from config import *
from case_log import log_case_info # 導入方法
class TestUserLogin(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.data_list = excel_to_list("test_user_data.xlsx", "TestUserLogin")
def test_user_login_normal(self):
case_data = get_test_data(self.data_list, 'test_user_login_normal')
if not case_data:
logging.error("用例數據不存在")
url = case_data.get('url')
data = case_data.get('data')
expect_res = case_data.get('expect_res')
res = requests.post(url=url, data=json.loads(data))
log_case_info('test_user_login_normal', url, data, expect_res, res_text) # 輸出用例log信息
self.assertEqual(res.text, expect_res)
if __name__ == '__main__':
unittest.main(verbosity=2)
發送郵件
在生成報告后我們希望框架能自動把報告發送到我們的郵箱中。和outlook,foxmail等郵件客戶端一樣,Python中發送郵件需要通過Email的smtp服務發送。
首先需要確認用來發送郵件的郵箱是否啟用了smtp服務
發送郵件分3步
- 編寫郵件內容(Email郵件需要專門的MIME格式)
- 組裝Email頭(發件人,收件人,主題)
- 連接smtp服務器并發送郵件
import smtplib # 用于建立smtp連接
from email.mime.text import MIMEText # 郵件需要專門的MIME格式
# 1. 編寫郵件內容(Email郵件需要專門的MIME格式)
msg = MIMEText('this is a test email', 'plain', 'utf-8') # plain指普通文本格式郵件內容
# 2. 組裝Email頭(發件人,收件人,主題)
msg['From'] = 'test_results@sina.com' # 發件人
msg['To'] = '2375247815@qq.com' # 收件人
msg['Subject'] = 'Api Test Report' # 郵件主題
# 3. 連接smtp服務器并發送郵件
smtp = smtplib.SMTP_SSL('smtp.sina.com') # smtp服務器地址 使用SSL模式
smtp.login('自己的郵箱地址', '自己的郵箱密碼') # 用戶名和密碼
smtp.sendmail("接收郵件地址1", "接收郵件地址2", msg.as_string())
smtp.quit()
中文郵件主題、HTML郵件內容,及附件
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart # 混合MIME格式,支持上傳附件
from email.header import Header # 用于使用中文郵件主題
# 1. 編寫郵件內容
with open('report.html', encoding='utf-8') as f: # 打開html報告
email_body = f.read() # 讀取報告內容
msg = MIMEMultipart() # 混合MIME格式
msg.attach(MIMEText(email_body, 'html', 'utf-8')) # 添加html格式郵件正文(會丟失css格式)
# 2. 組裝Email頭(發件人,收件人,主題)
msg['From'] = 'test_results@sina.com' # 發件人
msg['To'] = '2375247815@qq.com' # 收件人
msg['Subject'] = Header('接口測試報告', 'utf-8') # 中文郵件主題,指定utf-8編碼
# 3. 構造附件1,傳送當前目錄下的 test.txt 文件
att1 = MIMEText(open('report.html', 'rb').read(), 'base64', 'utf-8') # 二進制格式打開
att1["Content-Type"] = 'application/octet-stream'
att1["Content-Disposition"] = 'attachment; filename="report.html"' # filename為郵件中附件顯示的名字
msg.attach(att1)
# 4. 連接smtp服務器并發送郵件
smtp = smtplib.SMTP_SSL('smtp.sina.com') # smtp服務器地址 使用SSL模式
smtp.login('test_results@sina.com', 'hanzhichao123') # 用戶名和密碼
smtp.sendmail("test_results@sina.com", "2375247815@qq.com", msg.as_string())
smtp.sendmail("test_results@sina.com", "superhin@126.com", msg.as_string()) # 發送給另一個郵箱
smtp.quit()
封裝發送郵件方法
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart # 混合MIME格式,支持上傳附件
from email.header import Header # 用于使用中文郵件主題
from config import *
def send_email(report_file):
msg = MIMEMultipart() # 混合MIME格式
msg.attach(MIMEText(open(report_file, encoding='utf-8').read(), 'html', 'utf-8')) # 添加html格式郵件正文(會丟失css格式)
msg['From'] = 'test_results@sina.com' # 發件人
msg['To'] = '2375247815@qq.com' # 收件人
msg['Subject'] = Header('接口測試報告', 'utf-8') # 中文郵件主題,指定utf-8編碼
att1 = MIMEText(open(report_file, 'rb').read(), 'base64', 'utf-8') # 二進制格式打開
att1["Content-Type"] = 'application/octet-stream'
att1["Content-Disposition"] = 'attachment; filename="report.html"' # filename為郵件中附件顯示的名字
msg.attach(att1)
try:
smtp = smtplib.SMTP_SSL('smtp.sina.com') # smtp服務器地址 使用SSL模式
smtp.login('test_results@sina.com', 'hanzhichao123') # 用戶名和密碼
smtp.sendmail("test_results@sina.com", "2375247815@qq.com", msg.as_string())
smtp.sendmail("test_results@sina.com", "superhin@126.com", msg.as_string()) # 發送給另一個郵箱
logging.info("郵件發送完成!")
except Exception as e:
logging.error(str(e))
finally:
smtp.quit()
run_all.py中結束后發送郵件
import unittest
from HTMLTestReportCN import HTMLTestRunner
from config import *
from send_email import send_email
logging.info("================================== 測試開始 ==================================")
suite = unittest.defaultTestLoader.discover("./")
with open("report.html", 'wb') as f: # 改為with open 格式
HTMLTestRunner(stream=f, title="Api Test", description="測試描述", tester="卡卡").run(suite)
send_email('report.html') # 發送郵件
logging.info("================================== 測試結束 ==================================")
使用配置文件
和項目的log配置一樣,數據庫服務器地址,郵件服務地址我們一般放到配置文件config.py
中
import logging
import os
# 項目路徑
prj_path = os.path.dirname(os.path.abspath(__file__)) # 當前文件的絕對路徑的上一級,__file__指當前文件
data_path = prj_path # 數據目錄,暫時在項目目錄下
test_path = prj_path # 用例目錄,暫時在項目目錄下
log_file = os.path.join(prj_path, 'log.txt') # 也可以每天生成新的日志文件
report_file = os.path.join(prj_path, 'report.html') # 也可以每次生成新的報告
# log配置
logging.basicConfig(level=logging.DEBUG, # log level
format='[%(asctime)s] %(levelname)s [%(funcName)s: %(filename)s, %(lineno)d] %(message)s', # log格式
datefmt='%Y-%m-%d %H:%M:%S', # 日期格式
filename=log_file, # 日志輸出文件
filemode='a') # 追加模式
# 數據庫配置
db_host = '127.0.0.1' # 自己的服務器地址
db_port = 3306
db_user = 'test'
db_passwd = '123456'
db = 'api_test'
# 郵件配置
smtp_server = 'smtp.sina.com'
smtp_user = 'test_results@sina.com'
smtp_password = 'hanzhichao123'
sender = smtp_user # 發件人
receiver = '2375247815@qq.com' # 收件人
subject = '接口測試報告' # 郵件主題
修改db.py
,send_email.py
,run_all.py
等對配置文件的引用
db.py
部分
import pymysql
from config import *
# 獲取連接方法
def get_db_conn():
conn = pymysql.connect(host=db_host, # 從配置文件中讀取
port=db_port,
user=db_user,
passwd=db_passwd, # passwd 不是 password
db=db,
charset='utf8') # 如果查詢有中文,需要指定測試集編碼
send_email.py
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from config import *
def send_email(report_file):
msg = MIMEMultipart()
msg.attach(MIMEText(open(report_file, encoding='utf-8').read(), 'html', 'utf-8'))
msg['From'] = 'test_results@sina.com'
msg['To'] = '2375247815@qq.com'
msg['Subject'] = Header(subject, 'utf-8') # 從配置文件中讀取
att1 = MIMEText(open(report_file, 'rb').read(), 'base64', 'utf-8') # 從配置文件中讀取
att1["Content-Type"] = 'application/octet-stream'
att1["Content-Disposition"] = 'attachment; filename="{}"'.format(report_file) # 參數化一下report_file
msg.attach(att1)
try:
smtp = smtplib.SMTP_SSL(smtp_server) # 從配置文件中讀取
smtp.login(smtp_user, smtp_password) # 從配置文件中讀取
smtp.sendmail(sender, receiver, msg.as_string())
logging.info("郵件發送完成!")
except Exception as e:
logging.error(str(e))
finally:
smtp.quit()
run_all.py
import unittest
from HTMLTestReportCN import HTMLTestRunner
from config import *
from send_email import send_email
logging.info("================================== 測試開始 ==================================")
suite = unittest.defaultTestLoader.discover(test_path) # 從配置文件中讀取用例路徑
with open(report_file, 'wb') as f: # 從配置文件中讀取
HTMLTestRunner(stream=f, title="Api Test", description="測試描述").run(suite)
send_email(report_file) # 從配置文件中讀取
logging.info("================================== 測試結束 ==================================")
框架整理
當前所有文件(配置文件,公共方法,測試用例,數據,報告,log)都在項目根目錄下,隨著用例的增加和功能的補充,文件會越來越多,不便于維護和管理,因此我們要建立不同的文件夾,對文件進行分類組織
- 在項目中新建以下文件夾:
- config: 存放項目配置文件
- data: 存放用例數據文件
- lib: 公共方法庫
- log: 存放日志文件
- report: 存放報告文件
- test: 存放測試用例
- user: 存放user模塊用例 (模塊下要有
__init__.py
,這樣里面的用例才能讀取到)
- user: 存放user模塊用例 (模塊下要有
- 將配置文件
config.py
移動到config目錄下,將數據文件test_user_data.xlsx
移動到data目錄下,將公共方法db.py
send_email.py
case_log.py
read_excel.py
HTMLTestReportCN.py
移動到lib目錄下,將測試用例test_user_login.py
test_user_reg.py
移動到test/user目錄下,保留run_all.py
在項目根目錄下,如圖:
整理后的項目結構 - 修改配置文件
config/config.py
部分
import logging
import os
# 項目路徑
prj_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 當前文件的上一級的上一級目錄(增加一級)
data_path = os.path.join(prj_path, 'data') # 數據目錄
test_path = os.path.join(prj_path, 'test') # 用例目錄
log_file = os.path.join(prj_path, 'log', 'log.txt') # 更改路徑到log目錄下
report_file = os.path.join(prj_path, 'report', 'report.html') # 更改路徑到report目錄下
- 修改對配置文件及公共方法的引用
為避免相對路徑導包出錯的問題,我們統一把導包搜索路徑(sys.path)提升到項目根目錄下,如
lib/db.py
lib/db.py
部分
import pymysql
import sys
sys.path.append('..') # 提升一級到項目更目錄下
from config.config import * # 從項目根目錄下導入
測試用例test_user_login.py
部分
import unittest
import requests
import json
import os # 增加了一個os,需要用來組裝路徑
import sys
sys.path.append("../..") # 提升2級到項目根目錄下
from config.config import * # 從項目路徑下導入
from lib.read_excel import * # 從項目路徑下導入
from lib.case_log import log_case_info # 從項目路徑下導入
class TestUserLogin(unittest.TestCase):
@classmethod
def setUpClass(cls): # 整個測試類只執行一次
cls.data_list = excel_to_list(os.path.join(data_path, "test_user_data.xlsx"),"TestUserLogin") # 增加data路徑
run_all.py
import unittest
from lib.HTMLTestReportCN import HTMLTestRunner # 修改導入路徑
from config.config import * # 修改導入路徑
from lib.send_email import send_email # 修改導入路徑
logging.info("================================== 測試開始 ==================================")
suite = unittest.defaultTestLoader.discover(test_path) # 從配置文件中讀取
with open(report_file, 'wb') as f: # 從配置文件中讀取
HTMLTestRunner(stream=f, title="Api Test", description="測試描述").run(suite)
send_email(report_file) # 從配置文件中讀取
logging.info("================================== 測試結束 ==================================")
- 如果同一文件夾下的方法相互引用(如
lib/read_excel.py
假如需要引用lib/db.py
),也需要采用這種從項目路徑下導入的方式run_all.py
直接在項目路徑下,不需要提升sys.path,無需相對導入我們自己的包時,如read_excel.py
,不需要提升
- 運行
run_all.py
,根據log和報告調試代碼,直至所有用例全部通過
源碼下載鏈接:https://pan.baidu.com/s/1RzwAlUMHwG4FQmeS-yB9rw 密碼:rvq1