一、Python+unittest+requests+HTMLTestRunner 完整的接口自動化測試框架搭建_00——框架結構簡解
首先配置好開發環境,下載安裝Python並下載安裝pycharm,在pycharm中創建項目功能目錄。如果不會的可以百度Google一下,該內容網上的講解還是比較多比較全的!
大家可以先簡單了解下該項目的目錄結構介紹,后面會針對每個文件有詳細注解和代碼。
common:
——configDb.py:這個文件主要編寫數據庫連接池的相關內容,本項目暫未考慮使用數據庫來存儲讀取數據,此文件可忽略,或者不創建。本人是留着以后如果有相關操作時,方便使用。
——configEmail.py:這個文件主要是配置發送郵件的主題、正文等,將測試報告發送並抄送到相關人郵箱的邏輯。
——configHttp.py:這個文件主要來通過get、post、put、delete等方法來進行http請求,並拿到請求響應。
——HTMLTestRunner.py:主要是生成測試報告相關
——Log.py:調用該類的方法,用來打印生成日志
result:
——logs:生成的日志文件
——report.html:生成的測試報告
testCase:
——test01case.py:讀取userCase.xlsx中的用例,使用unittest來進行斷言校驗
testFile/case:
——userCase.xlsx:對下面test_api.py接口服務里的接口,設計了三條簡單的測試用例,如參數為null,參數不正確等
caselist.txt:配置將要執行testCase目錄下的哪些用例文件,前加#代表不進行執行。當項目過於龐大,用例足夠多的時候,我們可以通過這個開關,來確定本次執行哪些接口的哪些用例。
config.ini:數據庫、郵箱、接口等的配置項,用於方便的調用讀取。
getpathInfo.py:獲取項目絕對路徑
geturlParams.py:獲取接口的URL、參數、method等
readConfig.py:讀取配置文件的方法,並返回文件中內容
readExcel.py:讀取Excel的方法
runAll.py:開始執行接口自動化,項目工程部署完畢后直接運行該文件即可
test_api.py:自己寫的提供本地測試的接口服務
test_sql.py:測試數據庫連接池的文件,本次項目未用到數據庫,可以忽略
二、Python+unittest+requests+HTMLTestRunner完整的接口自動化測試框架搭建_01——測試接口服務
首先,我們想搭建一個接口自動化測試框架,前提我們必須要有一個可支持測試的接口服務。有人可能會說,現在我們的環境不管測試環境,還是生產環境有現成的接口。但是,一般工作環境中的接口,不太滿足我們框架的各種條件。舉例如,接口a可能是get接口b可能又是post,等等等等。因此我決定自己寫一個簡單的接口!用於我們這個框架的測試!
按第一講的目錄創建好文件,打開test_api.py,寫入如下代碼
import flask import json from flask import request ''' flask: web框架,通過flask提供的裝飾器@server.route()將普通函數轉換為服 ''' # 創建一個服務,把當前這個python文件當做一個服務 server = flask.Flask(__name__) # @server.route()可以將普通函數轉變為服務 登錄接口的路徑、請求方式 @server.route('/login', methods=['get', 'post']) def login(): # 獲取通過url請求傳參的數據 username = request.values.get('name') # 獲取url請求傳的密碼,明文 pwd = request.values.get('pwd') # 判斷用戶名、密碼都不為空 if username and pwd: if username == 'xiaoming' and pwd == '111': resu = {'code': 200, 'message': '登錄成功'} return json.dumps(resu, ensure_ascii=False) # 將字典轉換字符串 else: resu = {'code': -1, 'message': '賬號密碼錯誤'} return json.dumps(resu, ensure_ascii=False) else: resu = {'code': 10001, 'message': '參數不能為空!'} return json.dumps(resu, ensure_ascii=False) if __name__ == '__main__': server.run(debug=True, port=8888, host='127.0.0.1')
執行test_api.py,在瀏覽器中輸入http://127.0.0.1:8888/login?name=xiaoming&pwd=11199回車,驗證我們的接口服務是否正常~
變更我們的參數,查看不同的響應結果確認接口服務一切正常
三、Python+unittest+requests+HTMLTestRunner完整的接口自動化測試框架搭建_02——配置文件讀取
在我們第二講中,我們已經通過flask這個web框架創建好了我們用於測試的接口服務,因此我們可以把這個接口抽出來一些參數放到配置文件,然后通過一個讀取配置文件的方法,方便后續的使用。同樣還有郵件的相關配置~
按第一講的目錄創建好config.ini文件,打開該文件寫入如下:
# -*- coding: utf-8 -*- [HTTP] scheme = http baseurl = 127.0.0.1 port = 8888 timeout = 10.0 [EMAIL] on_off = on; subject = 接口自動化測試報告 app = Outlook addressee = songxiaobao@qq.com cc = zhaobenshan@qq.com
在HTTP中,協議http,baseURL,端口,超時時間。
在郵件中on_off是設置的一個開關,=on打開,發送郵件,=其他不發送郵件。subject郵件主題,addressee收件人,cc抄送人。
在我們編寫readConfig.py文件前,我們先寫一個獲取項目某路徑下某文件絕對路徑的一個方法。按第一講的目錄結構創建好getpathInfo.py,打開該文件
import os def get_Path(): path = os.path.split(os.path.realpath(__file__))[0] return path if __name__ == '__main__':# 執行該文件,測試下是否OK print('測試路徑是否OK,路徑為:', get_Path())
填寫如上代碼並執行后,查看輸出結果,打印出了該項目的絕對路徑:
繼續往下走,同理,按第一講目錄創建好readConfig.py文件,打開該文件,以后的章節不在累贅
import os import configparser import getpathInfo#引入我們自己的寫的獲取路徑的類 path = getpathInfo.get_Path()#調用實例化,還記得這個類返回的路徑為C:\Users\songlihui\PycharmProjects\dkxinterfaceTest config_path = os.path.join(path, 'config.ini')#這句話是在path路徑下再加一級,最后變成C:\Users\songlihui\PycharmProjects\dkxinterfaceTest\config.ini config = configparser.ConfigParser()#調用外部的讀取配置文件的方法 config.read(config_path, encoding='utf-8') class ReadConfig(): def get_http(self, name): value = config.get('HTTP', name) return value def get_email(self, name): value = config.get('EMAIL', name) return value def get_mysql(self, name):#寫好,留以后備用。但是因為我們沒有對數據庫的操作,所以這個可以屏蔽掉 value = config.get('DATABASE', name) return value if __name__ == '__main__':#測試一下,我們讀取配置文件的方法是否可用 print('HTTP中的baseurl值為:', ReadConfig().get_http('baseurl')) print('EMAIL中的開關on_off值為:', ReadConfig().get_email('on_off'))
執行下readConfig.py,查看數據是否正確
一切OK
四、Python+unittest+requests+HTMLTestRunner完整的接口自動化測試框架搭建_03——讀取Excel中的case
配置文件寫好了,接口我們也有了,然后我們來根據我們的接口設計我們簡單的幾條用例。首先在前兩講中我們寫了一個我們測試的接口服務,針對這個接口服務存在三種情況的校驗。正確的用戶名和密碼,賬號密碼錯誤和賬號密碼為空
我們根據上面的三種情況,將對這個接口的用例寫在一個對應的單獨文件中testFile\case\userCase.xlsx ,userCase.xlsx內容如下:
緊接着,我們有了用例設計的Excel了,我們要對這個Excel進行數據的讀取操作,繼續往下,我們創建readExcel.py文件
import os import getpathInfo# 自己定義的內部類,該類返回項目的絕對路徑 #調用讀Excel的第三方庫xlrd from xlrd import open_workbook # 拿到該項目所在的絕對路徑 path = getpathInfo.get_Path() class readExcel(): def get_xls(self, xls_name, sheet_name):# xls_name填寫用例的Excel名稱 sheet_name該Excel的sheet名稱 cls = [] # 獲取用例文件路徑 xlsPath = os.path.join(path, "testFile", 'case', xls_name) file = open_workbook(xlsPath)# 打開用例Excel sheet = file.sheet_by_name(sheet_name)#獲得打開Excel的sheet # 獲取這個sheet內容行數 nrows = sheet.nrows for i in range(nrows):#根據行數做循環 if sheet.row_values(i)[0] != u'case_name':#如果這個Excel的這個sheet的第i行的第一列不等於case_name那么我們把這行的數據添加到cls[] cls.append(sheet.row_values(i)) return cls if __name__ == '__main__':#我們執行該文件測試一下是否可以正確獲取Excel中的值 print(readExcel().get_xls('userCase.xlsx', 'login')) print(readExcel().get_xls('userCase.xlsx', 'login')[0][1]) print(readExcel().get_xls('userCase.xlsx', 'login')[1][2])
結果為:
完全正確~
五、Python+unittest+requests+HTMLTestRunner完整的接口自動化測試框架搭建_04——requests請求
配置文件有了,讀取配置文件有了,用例有了,讀取用例有了,我們的接口服務有了,我們是不是該寫對某個接口進行http請求了,這時候我們需要使用pip install requests來安裝第三方庫,在common下configHttp.py,configHttp.py的內容如下:
import requests import json class RunMain(): def send_post(self, url, data): # 定義一個方法,傳入需要的參數url和data # 參數必須按照url、data順序傳入 result = requests.post(url=url, data=data).json() # 因為這里要封裝post方法,所以這里的url和data值不能寫死 res = json.dumps(result, ensure_ascii=False, sort_keys=True, indent=2) return res def send_get(self, url, data): result = requests.get(url=url, params=data).json() res = json.dumps(result, ensure_ascii=False, sort_keys=True, indent=2) return res def run_main(self, method, url=None, data=None): # 定義一個run_main函數,通過傳過來的method來進行不同的get或post請求 result = None if method == 'post': result = self.send_post(url, data) elif method == 'get': result = self.send_get(url, data) else: print("method值錯誤!!!") return result if __name__ == '__main__': # 通過寫死參數,來驗證我們寫的請求是否正確 result1 = RunMain().run_main('post', 'http://127.0.0.1:8888/login', {'name': 'xiaoming','pwd':'111'}) result2 = RunMain().run_main('get', 'http://127.0.0.1:8888/login', 'name=xiaoming&pwd=111') print(result1) print(result2)
執行該文件,驗證結果正確性:
我們發現和瀏覽器中進行請求該接口,得到的結果一致,說明沒有問題,一切OK
六、Python+unittest+requests+HTMLTestRunner完整的接口自動化測試框架搭建_05——參數動態化
在上一講中,我們寫了針對我們的接口服務,設計的三種測試用例,使用寫死的參數(result = RunMain().run_main('post', 'http://127.0.0.1:8888/login', 'name=xiaoming&pwd='))來進行requests請求。本講中我們寫一個類,來用於分別獲取這些參數,來第一講的目錄創建geturlParams.py,geturlParams.py文件中的內容如下:
import readConfig as readConfig readconfig = readConfig.ReadConfig() class geturlParams():# 定義一個方法,將從配置文件中讀取的進行拼接 def get_Url(self): new_url = readconfig.get_http('scheme') + '://' + readconfig.get_http('baseurl') + ':8888' + '/login' + '?' #logger.info('new_url'+new_url) return new_url if __name__ == '__main__':# 驗證拼接后的正確性 print(geturlParams().get_Url())
通過將配置文件中的進行拼接,拼接后的結果:http://127.0.0.1:8888/login?和我們請求的一致
七、Python+unittest+requests+HTMLTestRunner完整的接口自動化測試框架搭建_06——unittest斷言
未完成