python之接口自動化測試框架
梳理python+unittest接口自動化測試框架的思路:
1.確定目錄:
cases:存放測試用例的py文件;config:存放一些數據庫,環境地址等固定不變的信息;
core:核心的文件,
cases:測試用例test_cj.py,代碼如下:
import unittest import os import jsonpath from core.my_requests import MyRequest from conf.setting import default_host from core.tools import mysql from core.tools import r as redisclass Cj(unittest.TestCase): username=‘autotest_lyh78910‘#自動化測試註冊的用戶 password=‘aA123456‘#類變量 def test_reg(self):#post請求,請求參數為username,pwd,cpwd. ‘‘‘註冊接口‘‘‘ url=‘/api/user/user_reg‘ new_url=os.path.join(default_host,url) data={‘username‘:self.username,‘pwd‘:self.password,‘cpwd‘:self.password} r=MyRequest() result=r.post(new_url,data)#result是個字典 self.assertEqual(1,result.get(‘status‘),msg=‘註冊接口不通 %s‘%result.get(‘sql_file‘)) #判斷請求接口是否通,1表示成功,0,2都是失敗,接口不通,這條語句下面的都不會執行 error_code=result.get(‘sql_file‘).get(‘error_code‘) self.assertEqual(0,error_code,msg="註冊失敗!%s"result.get(‘sql_file‘)) sql=‘select * from app_myuser where username="%s;‘%self.username sql_res=mysql.execute_one(sql)#數據庫查詢結果 self.assertIsNotNone(sql_res)#若數據庫表裏有新註冊的用戶名,說明註冊成功。判斷這個結果是否為空 def login(self):#post請求 ‘‘‘登錄‘‘‘ url=‘/api/user/login‘ new_url=os.path.join(default_host,url) data={‘username‘:self.username,‘passwd‘:self.password} r=MyRequest() result=r.post(new_url,data) self.assertEqual(1,result.get(‘status‘),msg=‘登錄接口不通!%s‘%result.get(‘sql_file‘)) sign=get_real_value(‘sign‘,result)#從返回值裏面取到sign值 self.assertIsNotNone(sign,msg=‘登錄失敗!%s‘result)#校驗sign是否為空 userid=get_real_value(‘userId‘,result)從返回值裏面取到userId值 return userid,sign def choujiang(self):#get請求 ‘‘‘抽獎‘‘‘ url=default_host+‘/api/product/choice‘ userid, sign = self.login()#調用函數,直接拿到函數的兩個返回值 data={‘userid‘:userid,‘sign‘:sign} r=MyRequest(url,data) result=r.get() self.assertEqual(1,result.get(‘status‘),msg=‘抽獎接口不通!%s‘%result.get(‘sql_file‘)) redis_key=‘choujiang:%s‘%self.username count=redis.get(redis_key)#抽獎次數,redis裏面key值是字符串 self.assertEqual(‘1‘,count,msg=‘抽獎次數錯誤%s‘result) sql=‘select count(*) as cishu from app_record where user_id=%s;‘%userid cishu=mysql.execute_one(sql).get(‘cishu‘) #本來fetchall()返回的是list,但指定了dict # #{‘cishu‘:1} self.assertEqual(1,cishu,msg=‘抽獎記錄沒有落到數據庫裏面!‘) def test_choujiang(self):#抽獎流程 ‘‘‘抽獎流程測試‘‘‘ self.reg() self.choujiang() def tearDownClass(cls):#類裏面的所有測試用例執行完之後,都會執行它 ‘‘‘註冊數據清除‘‘‘ sql=‘delete * from app_myuser where username="%s";‘%cls.username mysql.execute_one(sql) key=‘choujiang:%s‘%cls.username redis.delete(key) print("測試數據清理完成!")
測試用例裏寫按接口參數發送請求,判斷結果,判斷結果用斷言essertEqual(a,b),essertIsNotNone()判斷,還有接口流程
my_request.py 定義一個類MyRequest,裏面有post()和get()方法,發送請求後,返回響應數據res={"status":0,"data":res.json()},代碼如下:
import requests import nnlog import os from conf.setting import LOG_PATH class MyRequest: log_file_name = os.path.join(LOG_PATH,‘MyRequest.log‘)#日子文件名 time_out = 10 #請求超時時間 def __init__(self,url,data=None,headers=None,file=None): self.url = url self.data = data self.headers = headers self.file = file def post(self): try: req = requests.post(self.url,data=self.data,headers=self.headers, files=self.file,timeout=self.time_out) except Exception as e: res = {"status":0,"sql_file":e.args} #0代表請求失敗 else: try: res = {"status":1,"sql_file":req.json()} #1代表返回的json except Exception as e: res = {"status":2,"sql_file":req.text} #2代表返回不是json log_str = ‘url: %s 請求方式:post sql_file:%s ,返回數據:%s‘%(self.url,self.data,res) self.write_log(log_str) return res def get(self): try: req = requests.get(self.url,params=self.data,headers=self.headers,timeout=self.time_out) except Exception as e: res = {"status":0,"sql_file":req.args} #0代表請求失敗 else: try: res = {"status":1,"sql_file":req.json()} #1代表返回的json except Exception as e: res = {"staus":2,"sql_file":req.text} #2代表返回不是json log_str = ‘url: %s get請求 sql_file:%s ,返回數據:%s‘%(self.url,self.data,res) self.write_log(log_str) return res @classmethod def write_log(cls,content): log = nnlog.Logger(cls.log_file_name) log.debug(content)
發送請求後,執行用例前,先備份數據庫mysqldump -uroot -p12345 -Pxxxx -hxxx.xxx.xxx.xxx >xxx/a.sql,自動化測試執行後,把原數據庫名稱改掉:
rename database main to main_20190220,再創建原數據庫main,把備份的數據恢復進去。mysql -uroot -p123456 -Pxxx -hxxxxx <xxxx/a.sql
op_data.py文件主要寫數據庫的備份和恢復。
bin:start.py文件,主要寫運行測試的過程
import unittest
import datatime
from BeautifulReport import BeautifulReport
def run_case():
sql_file=bak_db()#備份數據庫
suite=unittest.Testsuite()#創建測試集合
cases=unittest.defualltTestloader.discover(Case_path,‘test*.py‘)#找到所有測試用例
for case in cases:
suite.addTest(case)#把每個測試用例加到測試集合中
report=BeautifulReport.BeautifulReport(suite)#運行測試集合,產生報告
report_path=make_today_dir()#創建報告的今天的目錄
file_name=‘report_%s.html‘%datatime.datatime.now().strftime(‘%H%M%S)#報告文件
report.report(filename=file_name,description="接口測試“,log_path=path)#產生報告
abs_path=os.path.join(report_path,file_name)#報告的路徑
send_mail(content,abs_path)#發送郵件
恢復數據庫
python之接口自動化測試框架