項(xiàng)目背景
公司內(nèi)部產(chǎn)品昭灵,大都采用B/S架構(gòu)。由于大部分項(xiàng)目都在開發(fā)階段,版本迭代快烂完,界面不穩(wěn)定试疙,故而使用UI自動化不太現(xiàn)實(shí)。針對此種情況窜护,接口測試較為有效效斑,所以就使用RobotFramework搭建了一個簡單的接口測試框架。
RobotFramework簡介
RobotFramework是一個款關(guān)鍵字驅(qū)動的開源自動化測試框架柱徙。測試用例位于HTML或者TSV(以tab分隔值)文件缓屠,在使用測試庫中實(shí)現(xiàn)的關(guān)鍵字來測試運(yùn)行的程序。因?yàn)镽obotFramework是靈活可擴(kuò)展的护侮,所以它很適合于測試具有多種接口的復(fù)雜軟件:用戶接口敌完,命令行,web service羊初,編程接口等等滨溉。當(dāng)然接口只是一部分,web UI长赞,移動端晦攒,該框架都游刃有余。接口測試工具得哆,框架比較多脯颜,為何選擇了rf,是因?yàn)橛兄跍y試人員快速上手贩据,學(xué)習(xí)成本較低栋操,統(tǒng)一語法便于管理。
封裝的公共庫
基于robotframework實(shí)現(xiàn)接口自動化饱亮,使用requestlibrary庫矾芙,該庫基于python的requests庫實(shí)現(xiàn),由于在接口數(shù)量太多的時候近上,使用該庫的關(guān)鍵字編寫用例時影響速度剔宪,故而我又對requests封裝了一下,以至于更高效的編寫測試用例壹无。先看一下我自己封裝的庫:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
__author__ = 'LiBin'
__mtime__ = '16/6/13'
┏┓ ┏┓
┏┛┻━━━┛┻┓
┃ ? ┃
┃ ┳┛ ┗┳ ┃
┃ ┻ ┃
┗━┓ ┏━┛
┃ ┗━━━┓
┃ 神獸保佑 ┣┓
┃ 永無BUG葱绒! ┏┛
┗┓┓┏━┳┓┏┛
┃┫┫ ┃┫┫
┗┻┛ ┗┻┛
"""
import json
import requests
import time
import hashlib
import random
import pymysql
__version__ = '0.1'
class PublicLibrary(object):
def __int__(self):
pass
def getCoding(self, strInput):
u"""
獲取編碼格式
"""
if isinstance(strInput, unicode):
return "unicode"
try:
strInput.decode("utf8")
return 'utf8'
except:
pass
try:
strInput.decode("gbk")
return 'gbk'
except:
pass
def tran2UTF8(self, strInput):
"""
轉(zhuǎn)化為utf8格式
"""
strCodingFmt = self.getCoding(strInput)
if strCodingFmt == "utf8":
return strInput
elif strCodingFmt == "unicode":
return strInput.encode("utf8")
elif strCodingFmt == "gbk":
return strInput.decode("gbk").encode("utf8")
def tran2GBK(self, strInput):
"""
轉(zhuǎn)化為gbk格式
"""
strCodingFmt = self.getCoding(strInput)
if strCodingFmt == "gbk":
return strInput
elif strCodingFmt == "unicode":
return strInput.encode("gbk")
elif strCodingFmt == "utf8":
return strInput.decode("utf8").encode("gbk")
def md5(self, init_str):
"""
md5加密
"""
m = hashlib.md5()
m.update(init_str)
return m.hexdigest()
def eval_dict(self, strInput):
u"""接收字符串直接轉(zhuǎn)成需要類型,例
| eval dict | str |
"""
strInput = eval(strInput)
return strInput
def random_num(self, num):
"""
隨機(jī)出給出數(shù)字位數(shù)的數(shù)字
"""
number = ''
for i in random.sample(range(10), int(num)):
number += ''.join(str(i))
return number
def req(
self,
login_msg,
url,
method,
data=None,
headers=None):
u"""專用,有登錄狀態(tài),例
| run interface test tenant | login_msg,url,method,data,headers
"""
session = requests.Session()
url = self.tran2UTF8(url)
method = self.tran2UTF8(method)
if login_msg:
login_msg = self.eval_dict(login_msg)
md5_pwd = self.md5(login_msg['passwd'])
login_msg['passwd'] = md5_pwd
if data:
data = self.eval_dict(data)
if headers:
headers = self.eval_dict(headers)
else:
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
results = 'connection error'
# 先登錄
r = session.post('https://xxxxxx.cn/login',
data=json.dumps(login_msg), headers=headers)
print "*******************************"
print u"登錄狀態(tài)信息"
print r.status_code
print r.content
print "*******************************"
try:
if method == "post":
if isinstance(data, dict):
data = json.dumps(data)
results = session.post(
url, data=data, headers=headers, verify=False)
elif method == "get":
results = session.get(
url, params=data, headers=headers, verify=False)
elif method == 'delete':
results = session.delete(url, headers=headers, verify=False)
return results
except requests.ConnectionError as e:
return e
def con_db(self, sql):
db = pymysql.connect(
host="1.1.5.2",
user="xxx",
passwd="xxx",
db="xxx",
charset='utf8')
cursor = db.cursor()
cursor.execute(sql)
data = cursor.fetchone()
db.close()
return data
其中的req函數(shù)即是對request的一層簡單封裝,省掉了接口的每次登錄狀態(tài)格遭。
如何編寫用例
用例的內(nèi)容一般是發(fā)起請求,拿到結(jié)果留瞳,結(jié)果驗(yàn)證拒迅。
上述用例中即為發(fā)起請求、拿到結(jié)果、與數(shù)據(jù)庫的數(shù)據(jù)進(jìn)行對比璧微。
如何跑
我們的用例使用git管理作箍,項(xiàng)目在Jenkins每次構(gòu)建后會自動跑一次,當(dāng)然如果希望多次跑前硫,就自己在Jenkins上添加時間調(diào)度吧胞得。每次構(gòu)建完成后,相關(guān)人員會收到測試結(jié)果屹电,如果發(fā)現(xiàn)問題可以及時修改阶剑。
以上就是使用RobotFramework做的一個簡單的接口自動化測試框架(肯定還有一些地不完善)希望幫助到有需要的人。