接口自动化脚本设计思路总结

核心思路

账号登录返回"result_token",通过"result_token"传参返回"accesstoken"值,而"accesstoken"值贯穿每一个接口,故要把公用的"accesstoken"值进行封装

解决思路:

  1. 把公共的sdk_header、sdk_Authorizationr、fish_Authorization进行封装调用,减少代码的输入;
  2. 把公共"accesstoken"值单独抽出来,用yaml文件去管理;
  3. 写一个读yaml文件的get_accesstoken()函数放到re_token.py,去读取需要的"accesstoken"值;
  4. 其它脚本全部调用re_token.py里面的get_accesstoken()函数,然后传参;
  5. "accesstoken"值动态获取可以写个login_result_token()函数和get_accesstoken()放到Base_Config.py,获取到之后把"accesstoken"值写入到yaml文件,保证每次"accesstoken"值都是最新的;
  6. Run_Mail_Report.py脚本 里重点有email、Report、Testcase用例集脚本;
  7. 优化Run_Mail_Report.py脚本,新增write_yaml()函数,用来运行所有用例之前获取最新的"accesstoken"值写入yaml文件,出最新的报告结果;

目录结构思路:

  • public文件夹: 存放yaml文件、Base_Config.py脚本、re_token.py脚本;


    接口自动化脚本设计思路总结_第1张图片
    public文件夹.png
  • Test_Case文件夹: 存放所有的用例testcase


    接口自动化脚本设计思路总结_第2张图片
    Test_Case.png
  • common文件夹: 存放HTMLtestRunner文件(根据自身喜好修改模板结构)


    接口自动化脚本设计思路总结_第3张图片
    common文件夹.png
  • result_report文件夹: 存放每次执行的测试报告,方便跟踪定位每次测试结果


    接口自动化脚本设计思路总结_第4张图片
    result_report文件夹.png
  • Run_Mail_Report.py脚本运行所有的测试用例,发送邮件及最新的测试报告


    接口自动化脚本设计思路总结_第5张图片
    Run_Mail_Report.png

封装公共脚本参考:

Base_Config.py

'''
Created on 2019年5月17日

@author:  Yvon_fajin
'''
import requests,sys
sys.path.append('../public/')
import re_token

def get_SDK_header():
    headers = {
        "User-Agent": "Android Device","App-Channel": "XXXX",
        "Connection": "Keep-Alive","Content-Type":"XXXX","Host":"XXXX",
        "App-GameId": "10000","App-DeviceNum": "XXXX"}
    header = headers
    return header

'''  
手机号账户登录
'''  

def login_result_token():
    
    '''获取手机号登录成功'''
    
    header = get_SDK_header()
#     print(header)
    base_url = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    params = {"password":"XXXX","phone":"XXXX"}
    r = requests.post(url = base_url,headers = header, json = params ,verify = False)
    result = r.json()
    result_token = result["data"]
    return result_token

def get_accesstoken():
    base_url = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    header = get_SDK_header()
    result_token = login_result_token() 
    params = {"deviceType":1,"requestToken":result_token}
    r = requests.post(url = base_url,headers = header, json = params ,verify = False)
    result = r.json()
    #获取access_token
#     with open(base_dir(),'w') as f:
#         f.write(result['data']['accessToken'])
    access_token = result['data']['accessToken']
    return access_token

def get_Authorization():
     
    user_Token = re_token.get_accesstoken()
#     return user_Token
    headers = {"User-Agent": "XXXX",
               "App-Channel": "XXXX","App-client-version": "1.2.2.9",
               "Authorization": user_Token,
               "Connection": "Keep-Alive",
               "Content-Type":"XXXX",
               "Host":"XXXX"}
    header = headers
    return header

def get_SDK_Authorization():
    
        user_Token = re_token.get_accesstoken()

        headers = {
        "User-Agent": "Android Device",
        "App-Channel": "XXXX","App-client-version": "XXXX",
        "App-DeviceNum": "XXXX",
        "Authorization": user_Token,
        "App-GameId": "XXXX",
        "Connection": "Keep-Alive","XXXX}
        header = headers
        return header

'''  
QQ登录
'''  

def get_QQlogintoken():
    
    '''获取QQ token'''
    
    header = get_SDK_header()
#     print(header)
    base_url = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    params = {"headImg":"XXXX",
              "nickName":"XXXX","openId":"XXXX",
              "visitorToken":""}
    r = requests.post(url = base_url,headers = header, json = params ,verify = False)
    result = r.json()
    result_token = result["data"]["requestToken"]
    return result_token


def get_QQaccesstoken():
    
    '''获取QQ accesstoken'''
    
    base_url = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    header = get_SDK_header()
    result_token = get_QQlogintoken() 
    params = {"deviceType":1,"requestToken":result_token}
    r = requests.post(url = base_url,headers = header, json = params ,verify = False)
    result = r.json()
    #获取access_token
#     with open(base_QQdir(),'w') as f:
#         f.write(result['data']['accessToken'])
    access_token = result['data']['accessToken']
    return access_token


def get_QQAuthorization():
     
    user_Token = re_token.get_QQaccesstoken()
    
    headers = {"User-Agent": "XXXX",
               "App-Channel": "XXXX","App-client-version": "XXXX",
               "Authorization": user_Token,
               "Connection": "Keep-Alive",
               "Content-Type":"XXXX",
               "Host":"XXXX"}
    header = headers
    return header

def get_SDK_QQAuthorization():
    
        user_Token = re_token.get_QQaccesstoken()

        headers = {
        "User-Agent": "XXXX",
        "App-Channel": "XXXX","App-client-version": "XXXX",
        "App-DeviceNum": "XXXX",
        "Authorization": user_Token,
        "App-GameId": "10000",
        "Connection": "Keep-Alive","Content-Type":"XXXX}
        header = headers
        return header

if __name__ == '__main__':
    
    accesstoken = get_accesstoken()
    print(accesstoken)
#     write_yaml(accesstoken)
#     print(get_accesstoken())
    print("********************加油2019************************")
#     print(get_wechatlogintoken())

re_token.py

'''
Created on 2019年5月16日

@author:  Yvon_fajin
'''
import yaml,os

cur = os.path.dirname(os.path.realpath(__file__))

def get_accesstoken(yamlName="accesstoken.yaml"):
    '''
          从accesstoken.yaml读取accesstoken值
    :param yamlName: 配置文件名称
    :return: assesstoken值
    '''
    p = os.path.join(cur, yamlName)
    f = open(p)
    a = f.read()
    t = yaml.load(a)
    f.close()
    return t['accesstoken']

def get_QQaccesstoken(yamlName="QQaccesstoken.yaml"):
    '''
          从QQaccesstoken.yaml读取accesstoken值
    :param yamlName: 配置文件名称
    :return: assesstoken值
    '''
    p = os.path.join(cur, yamlName)
    f = open(p)
    a = f.read()
    t = yaml.load(a)
    f.close()
    return t['accesstoken']

if __name__ =="__main__":
    print(get_accesstoken())

测试用例脚本参考

test_01_Phone_Login.py

#coding=UTF-8
'''
Created on 2018年9月19日

@author:  Yvon_fajin
'''

import unittest,requests,json,sys
sys.path.append('../public/')
import Base_Config

class RequestToken(unittest.TestCase):
    '''手机号登录'''
    
    def setUp(self):
        self.base_url = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
        self.header = Base_Config.get_SDK_header()
 
    def tearDown(self):
#         print(self.result)
        print(json.dumps(self.result,sort_keys=True,ensure_ascii = False,indent=4,separators=(', ', ': ')))

    def test_LoginRequestToken_phone_null(self):
        '''手机号为空'''
        params = {"password":"XXXXXXXXXXX","phone":""}
        r = requests.post(url=self.base_url,headers = self.header, json = params ,verify=False)
#         login_ret = requests.post(url=login_url, headers = header_csdk_header_configure params,verify=False)
        self.result = r.json()
        self.assertEqual(self.result['code'],400)
        self.assertEqual(self.result['message'], "参数错误")
        
        
    def test_LoginRequestToken_password_null(self):
        '''密码为空'''
        params = {"password":"","phone":"XXXX"}
        r = requests.post(url=self.base_url,headers = self.header, json = params ,verify=False)
        self.result = r.json()
        self.assertEqual(self.result['code'],400)
        self.assertEqual(self.result['message'], "参数错误")
    
    def test_LoginRequestToken_password_phone_null(self):
        '''密码和手机号都输入为空'''
        params = {"password":"","phone":""}
        r = requests.post(url=self.base_url,headers = self.header, json = params ,verify=False)
        self.result = r.json()
        self.assertEqual(self.result['code'],400)
        self.assertEqual(self.result['message'], "参数错误")
        
    def test_LoginRequestToken_password_phone_error(self):
        '''密码和手机号输入错误'''
        params = {"password":"123456","phone":"123456"}
        r = requests.post(url=self.base_url,headers = self.header, json = params ,verify=False)
        self.result = r.json()
        self.assertEqual(self.result['code'],101)
        self.assertEqual(self.result['message'], "用户不存在或密码错误")
    
    def test_LoginRequestToken_password_phone_right(self):
        '''手机号和密码输入正确'''
        params = {"password":"XXXXXXXXXXX","phone":"XXXXXXXXXX"}
        r = requests.post(url=self.base_url,headers = self.header, json = params ,verify=False)
        self.result = r.json()
        self.assertEqual(self.result['code'],200)

  
if __name__ == '__main__':
    unittest.main()

发送邮件、测试报告、执行测试用例

Run_Mail_Report.py

'''
Created on 2019年5月17日

@author: Yvon_fajin
'''
# coding:utf-8
import time, sys, unittest, smtplib, os
sys.path.append('./API_Test')
sys.path.append('../public/')
from common.HTMLTestRunner import HTMLTestRunner
# from common.HTMLTestRunner_cn2 import HTMLTestRunner
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.mime.text import MIMEText
from ruamel import yaml
import Base_Config

#======================定义yaml文件存放accesstoken======================

curpath = os.path.dirname(os.path.realpath(__file__))

def write_yaml(value):
    ''' 
        把获取到的accesstoken值写入到yaml文件
    :param value:
    :return:
    '''

    ypath = os.path.join(curpath,"public" ,"accesstoken.yaml")
#     print(ypath)
    # 需写入的内容
    t = {"accesstoken": value}
    # 写入到yaml文件
    with open(ypath, "w", encoding="utf-8") as f:
        yaml.dump(t, f, Dumper=yaml.RoundTripDumper)

def write_QQyaml(value):
    ''' 
        把获取到的accesstoken值写入到yaml文件
    :param value:
    :return:
    '''

    ypath = os.path.join(curpath,"public" ,"QQaccesstoken.yaml")
#     print(ypath)
    # 需写入的内容
    t = {"accesstoken": value}
    # 写入到yaml文件
    with open(ypath, "w", encoding="utf-8") as f:
        yaml.dump(t, f, Dumper=yaml.RoundTripDumper)

#======================定义发送邮件======================

def send_mail(file_new):
    '''file_new是指最新的测试报告'''
    f = open(file_new,'rb')
    mail_body = f.read()
    f.close()
    
    msg = MIMEMultipart()
    '''邮件标题'''
    msg['Subject'] = Header('XXXXXX接口测试报告' ,'utf-8')
    msg['from'] = '[email protected]'
#     msg['to'] = '[email protected]'
    msg['to'] = '[email protected]'
    

    '''邮件正文'''
    zhengwen = "各位,详情测试结果请见附件文档"
    msg.attach(MIMEText(zhengwen, 'plain')) 
    
    
    '''附件测试报告 '''
    att= MIMEText(mail_body,'html','utf-8')
    now1 = time.strftime("%Y-%m-%d %H")
    att.add_header('Content-Disposition', 'attachment', filename= (now1 + 'XXXXXReport.html'))
    msg.attach(att)
#     
#发送邮件
    #要发送的服务器
    smtpserver = 'smtp.yeah.net'
    #要发送的邮箱用户名/密码
    user = '[email protected]'
    password = 'XXXXXXXX'
    #发送的邮箱
    sender = '[email protected]'
    #接收的邮箱
#     receiver = '[email protected]'
    receiver = '[email protected]'
    

#连接发送邮件
    smtp = smtplib.SMTP()
    smtp.connect(smtpserver)
    smtp.login(user,password )
    smtp.sendmail(sender,receiver,msg.as_string())
    print('email has send out !')
    smtp.quit()
 
#======================查找测试报告的目录,找到最新生成的测试报告======================
'''按时间获取最新的测试报告'''
def new_report(testreport):
    lists = os.listdir(testreport)
    lists.sort(key = lambda fn: os.path.getatime(testreport + '\\' + fn))
    file_new = os.path.join(testreport,lists[-1])
    print(file_new)
    return file_new

#指定测试用例为当前文件夹下的目录
test_dir = './Test_Case'
#discover = unittest.defaultTestLoader.discover(test_dir, pattern='*_test.py')
discover = unittest.defaultTestLoader.discover(test_dir, pattern='Test_*')

if __name__ == '__main__':
    #报告存放的路径
    result_report_dir= 'result_report/'
 
    '''实时当前的时间'''
    now = time.strftime("%Y-%m-%d %H_%M_%S")
    file_name = result_report_dir + '\\' + now +'result.html'
    fp = open(file_name,'wb')    
    #定义测试报告
    runner =HTMLTestRunner(stream = fp,title ='XXX接口测试报告',description='接口用例执行情况:',tester='Yvon_fajin')                              
    runner.run(discover)
    fp.close() #关闭报告文件
    new_report = new_report(result_report_dir)
    send_mail(new_report)
    
    '''把accesstoken写入yaml'''
    accesstoken =Base_Config.get_accesstoken()
    write_yaml(accesstoken)
    accesstoken =Base_Config.get_QQaccesstoken()
    write_QQyaml(accesstoken)

测试报告

接口自动化脚本设计思路总结_第6张图片
接口测试报告.png

你可能感兴趣的:(接口自动化脚本设计思路总结)