刷題[安洵杯 2019]不是檔案上傳
環境說明:
1.WIN 7, 64位
2.Python3.4.3 (pip-8.1.2)
3.Requests —>pip install requests
4.Unittest —>unittest 框架是python自帶的單元測試框架,python2.1及其以後的版本已將unittest作為一個標準塊放入python開發包中,所以unittest不用單獨安裝。
5.測試報告利用HTMLTestRunner生成。
測試思路:
1、先把每個http介面一個一個寫指令碼測試。(提交的json串直接放在data字典中,這裡沒有用到excel等寫測試用例,測試用例直接用指令碼實現。)
2、寫完所有介面的測試指令碼後,由於一個介面有好幾個測試用例,所有要把同一個介面的py指令碼封裝成方法,每一個介面封裝成一個介面類。
3、用testsuite直接呼叫這些介面類,構造測試集;或利用unittest自動識別測試用例,TestLoader類中提供的discover()方法。
(命名規則:介面名稱要以test_XXX開頭)
就好把所有的介面測試用例連起來構建自動化測試了。
4、最後利用HTMLTestRunner生成測試報告。
PUT:上傳指定的URL,一般是修改,可以理解為資料庫中的update。 DELETE:刪除指定資源。 在介面測試中,一般來說,post建立資料,get獲取建立成功後的所有資料和指定的資料,put可以對建立成功後的資料 進行修改,delete是指定的資源。
目錄結構:
單個介面測試例子:
post(修改)
import requests import json def get_token(): url1 = "https://**********/Token/get" content = {'appId':'***','appSecret':'******'} web = requests.get(url=url1,params=content) print(web.url) print(web.text) ty = web.text a = json.loads(ty) b = a.get('Data') apptoken = b.get('Token') return apptoken if __name__ == '__main__': get_token()
get(查詢)
import requests
import json
def test_qualification_add():
url = "http://xxx.xxx.xxx/audit/api/xxx/get" #測試的介面url
headers = {"Content-Type":"application/json"}
data = { #介面傳送的引數
"token": "abcdefg",
"id": 1,
"param": {
"QuId":1
}
}
r = requests.post(url = url,json = data,headers = headers) #傳送請求
#return r.json
print (r.text) #獲取響應報文
print (r.status_code)
if __name__=="__main__":
test_qualification_add()
requests.post和requests.request兩種寫法,都可以實現請求。
在進行介面測試的過程中對傳入的引數進行邊界值測試、錯誤推導測試、等價類測試等測試方法進行測試。那麼一個介面就要設很多測試用例。
下面是封裝為介面類的例子:
(一個介面地址一個類,每一個方法是一條測試用例)
(setUp()、tearDown()方法會分別作用於每個測試用例的開始和結束,如果每個類中的setUp()、tearDown(),所做的事情一樣,那麼可以封裝一個自己的測試類,如程式碼:)
import requests
import json
import unittest
class MyTest(unittest.TestCase): #封裝測試環境的初始化和還原的類
def setUp(self): #放對資料可操作的程式碼,如對mysql、momgodb的初始化等,這裡不對資料庫進行操作!
print("start test")
pass
def tearDown(self): #與setUp()相對
print("end test")
pass
class test_xxx_get(MyTest): #把這個介面封裝一個類,下面的方法是具體的測試用例
'''介面名稱:獲取資質''' #這個描述介面名稱
def test_xxx_get(self):
'''測試用例1:哈哈''' #這個描述介面用例名稱
self.url = "http://xxx.xxx.xxx/audit/api/xxx/get" #請求url
self.headers = {"Content-Type":"application/json"}
self.data = { #請求引數
"token": "abcdefg",
"id": 1,
"param": {
"QuId": 14
}
} #self.用在方法屬性中,表示是該方法的屬性,不會影響其他方法的屬性。
r = requests.post(url = self.url,json = self.data,headers = self.headers)
#return r.json()
print (self.r.text)
print (self.r.status_code)
self.assertIn("true",self.r.text) #斷言判斷介面返回是否符合要求,可以寫多個斷言!
if __name__=="__main__":
unittest.main()
unittest提供了全域性的main()方法,使用它可以方便的將一個單元測試木塊變成可以直接執行的測試指令碼;
main()方法使用TestLoader類來搜尋所有包含在該木塊中以“test”命名開頭的測試方法,並自動執行它;
執行方法的預設順序是:根據ASCII碼的順序載入測試用例,數字與字母的順序為:0-9,A-Z,a-z。所以以A開頭的測試用例方法會優先執行,以a開頭會後執行。
所以每一個介面類、測試用例要以test*命名,如下圖:
(測試用例放在同一個資料夾:)
runtest.py寫法:
import unittest
import json
import requests
from HTMLTestRunner import HTMLTestRunner
import time
#載入測試檔案 (有幾多個介面就載入幾多個,一個一個加進來)
import test_creative_add
import test_creative_get
import test_qualification_add
import test_qualification_get
import test_qualification_reflesh
#構造測試集
suite = unittest.TestSuite() #例項化
#TestSuite類的addTest()方法把不同測試類中的測試方法組裝到測試套件中。
#增加測試用例==》介面檔名.介面類(方法也就是這個介面的其他用例),要把每一個測試用例都增加進來!!!
suite.addTest(test_creative_add.test_creative_add("test_creative_add")) #增加創意
suite.addTest(test_creative_get.test_creative_get("test_creative_get")) #獲取創意
suite.addTest(test_qualification_add.test_qualification_add("test_qualification_add"))#增加資質
suite.addTest(test_qualification_get.test_qualification_get("test_qualification_get"))#獲取資質
suite.addTest(test_qualification_reflesh.test_qualification_reflesh("test_qualification_reflesh"))#更新資質
if __name__=="__main__":
testunit = unittest.TestSuite()
testunit.addTest(suite)
#按照一定的格式獲取當前的時間
now = time.strftime("%Y-%m-%d %H_%M_%S")
#定義報告存放路徑
filename = './' + now + 'test_result.html'
fp = open(filename,"wb")
#定義測試報告
runner = HTMLTestRunner(stream = fp,
title = "xxx介面測試報告",
description = "測試用例執行情況:")
#執行測試
runner.run(testunit)
fp.close() #關閉檔案物件把資料寫進磁碟
如果有幾百條測試用例,在runtest指令碼中一個個增加測試用例,那麼就很麻煩啦,其實用discover()一步就搞掂了。
discover函式介紹:
discover(start_dir,pattern=’test.py’,top_level_dir=None)
找到指定目錄下所有測試模組,並可遞迴查到子目錄下的測試木塊,只有匹配到的檔名才會被載入。如果啟動的不是頂層目錄,那麼頂層目錄必然單獨指定。
start_dir:要測試的木塊名或測試用例的目錄。
pattent=‘test.py’:表示用例檔名的匹配原則。此處匹配檔名一test開頭的所有.py型別檔案,表示任意多個字元。
top_level_dir=None :測試木塊的頂層目錄,如果沒有頂層目錄,預設為None。
這裡測試用例都放在同一個目錄,都以test.py的形式!!(如上圖)
runtest2.py寫法:
import unittest
import json
import requests
from HTMLTestRunner import HTMLTestRunner
import time
#定義測試用例的目錄為當前目錄
test_dir = './'
discover = unittest.defaultTestLoader.discover(test_dir,pattern = 'test*.py')
if __name__=="__main__":
#按照一定的格式獲取當前的時間
now = time.strftime("%Y-%m-%d %H-%M-%S")
#定義報告存放路徑
filename = './' + now + 'test_result.html'
fp = open(filename,"wb")
#定義測試報告
runner = HTMLTestRunner(stream = fp,
title = "xxx介面測試報告",
description = "測試用例執行情況:")
#執行測試
runner.run(discover)
fp.close() #關閉報告檔案
整合自動化測試傳送測試報告:
runtest_mail.py
import unittest
import requests
from HTMLTestRunner import HTMLTestRunner
import time
import os
import smtplib
from email.mime.text import MIMEText
from email.header import Header
#======定義傳送郵件========
def send_mail(file_new):
f = open(file_new,'rb')
mail_body = f.read()
f.close()
msg = MIMEText(mail_body,'html','utf-8')
msg['Subject'] = Header('xxx介面自動化測試報告','utf-8')
smtp = smtplib.SMTP()
smtp.connect('smtp.sina.com')
smtp.login('[email protected]','xxx336..')
smtp.sendmail('[email protected]','[email protected]',msg.as_string())
smtp.quit()
print('郵件已發出!注意查收。')
#======查詢測試目錄,找到最新生成的測試報告======
def new_report(test_report):
lists = os.listdir(test_report)
lists.sort(key=lambda fn:os.path.getmtime(test_report + '\\' + fn))
file_new = os.path.join(test_report,lists[-1])
print(file_new)
return file_new
if __name__ == "__main__":
test_dir = "D:\\dsp_testpro\\test_case"
test_report = "D:\\dsp_testpro\\test_report"
discover = unittest.defaultTestLoader.discover(test_dir,
pattern = 'test*.py')
#按照一定的格式獲取當前的時間
now = time.strftime("%Y-%m-%d_%H-%M-%S-")
#定義報告存放路徑
filename = test_report + "\\" + now + 'result.html'
fp = open(filename,'wb')
#定義測試報告
runner = HTMLTestRunner(stream = fp,
title = "xxx介面測試報告",
description = "測試用例執行情況:")
#執行測試
runner.run(discover)
fp.close() #關閉報告檔案
new_report = new_report(test_report)
send_mail(new_report)
郵件如下:
瞭解更多,加入我們,642830685,免費領取最新軟體測試大廠面試資料和Python自動化、介面、框架搭建學習資料!技術大牛解惑答疑,同行一起交流。