自动化测试接口PYTHON

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import xlrd
import requests
import json
import logging
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
import jsonpath
import sys
import traceback

#日志定义
logging.basicConfig(level=logging.DEBUG,  # log level
                    format='[%(asctime)s] %(levelname)s [%(funcName)s: %(filename)s, %(lineno)d] %(message)s',  # log格式
                    datefmt='%Y-%m-%d %H:%M:%S',  # 日期格式
                    filename='log.txt',  # 日志输出文件
                    filemode='a')  # 追加模式
class Config:
    global PHP_API_DOMAIN #php接口域名
    global JAVA_API_DOMAIN #java接口域名
    global TEST_CASE_PATH  #测试用例excel的路径
    global TEST_CASE_LIST  #测试用例转换后的集合<字典>
    global PARAMS #存储结果变量
    global CURRENT_REQUEST_HEADER #存储当前请求的请求头
    global CURRENT_REQUEST_PARAM #存储当前请求的请求数据
    global ALL_REQUEST_RESULT
    global CURRENT_REQUEST_STATUS

    def __init__(self,php_api_domain,java_api_domain,test_case_path):
        self.PHP_API_DOMAIN = php_api_domain
        self.TEST_CASE_PATH = test_case_path
        self.JAVA_API_DOMAIN = java_api_domain
        self.TEST_CASE_LIST = []
        self.PARAMS = {}
        self.CURRENT_REQUEST_HEADER = {}
        self.CURRENT_REQUEST_PARAM = {}
        self.ALL_REQUEST_RESULT = []
        self.CURRENT_REQUEST_STATUS = True


headers = {'Accept': 'application/json, text/javascript, */*',
               'Accept-Encoding':'gzip, deflate, br',
               'Accept-Language':'zh-CN,zh;q=0.9',
               'Connection':'Keep-Alive',
               'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063'}

class request_handler:
    test_case = {}
    result_obj = {}
    assert_obj = {}
    assert_result = True
    need_assert = True
    def __init__(self, test_case):
        self.test_case = test_case
        self.main()
        self.return_entity()

    def main(self):
        self.request(self.test_case)
        if self.need_assert:
            self.setting_param()

    def return_entity(self):
        return_entity = {}
        return_entity['成功状态'] = self.assert_result
        return_entity['请求结果数据'] = self.result_obj
        return_entity['断言结果'] = self.assert_obj
        return_entity['用例数据'] = self.test_case
        return_entity['请求参数'] = config.CURRENT_REQUEST_PARAM
        return_entity['请求头'] = config.CURRENT_REQUEST_HEADER
        logging.info(return_entity)
        if not self.assert_result:
            config.ALL_REQUEST_RESULT.append(return_entity)
            config.CURRENT_REQUEST_STATUS = False
        else:
            config.CURRENT_REQUEST_STATUS = True

    def request(self,test_case):
        try:
            if test_case['method'] == 'GET':
                self.result_obj = self.request_get(test_case)
            if test_case['method'] == 'POST':
                self.result_obj = self.request_post(test_case)
            self.assert_handler()
        except Exception as e:
            self.need_assert = False
            self.assert_result = False
            self.result_obj = {"status_code": "error", "error_message": e}
            traceback.print_exc()
            info = traceback.format_exc()
            print(info)

    def request_get(self,object):
        url = self.get_url(object['url'],object['type'])
        head = headers
        if isinstance(object['header'],list):
            head = self.get_config_param(object['header'], head)
        request_body = {}
        if isinstance(json.loads(object['data']),dict):
            request_body = self.get_config_param(json.loads(object['data']), request_body)
        print("GET URL:"+url)
        config.CURRENT_REQUEST_HEADER = head
        config.CURRENT_REQUEST_PARAM = request_body
        response = requests.get(url=url, params=request_body,headers=head)
        return {"status_code" : response.status_code, "response_content": response.text}

    def request_post(self,object):
        head = headers
        #将header中的数据添加到请求中
        if isinstance(json.loads(object['header']),dict):
            head = self.get_config_param(json.loads(object['header']),head)
        url = self.get_url(object['url'], object['type'])
        #将data中的动态参数从共享参数中添加到数据中
        request_body = {}
        if isinstance(json.loads(object['data']),dict):
            request_body = self.get_config_param(json.loads(object['data']),request_body)
        print("POST URL:" + url+";param:"+str(request_body))
        config.CURRENT_REQUEST_HEADER = head
        config.CURRENT_REQUEST_PARAM = request_body
        response = requests.post(url, request_body, headers=head)
        return {"status_code": response.status_code, "response_content": response.text}

    def get_config_param(self,list,object):
        for param_name in list.keys():
            param_value = list[param_name]
            if not str(param_value).startswith("$P_"):
                object[param_name] = param_value
            else:
                body_value = config.PARAMS[param_value] if param_value in config.PARAMS.keys() else param_value
                object[param_name] = body_value
        return object

    def get_url(self,path,type):
        request_url = (config.PHP_API_DOMAIN + '/' + path) if type == 'php' else (config.JAVA_API_DOMAIN + '/' + path)
        return request_url

    def assert_handler(self):
        test_case = self.test_case
        result_obj = self.result_obj
        self.assert_obj = {"测试用例名称:": test_case['case_name']}
        # 访问接口直接报错直接
        if result_obj['status_code'] == 'error':
            self.assert_obj = dict(self.assert_obj.items(), {"请求状态:": "错误", "错误信息:": result_obj['error_message']}.items())
            self.need_assert = False
            self.assert_result = False
            return
        # 状态大于300的异常直接处理
        if result_obj['status_code'] >= 300:
            self.assert_obj['请求状态'] = result_obj['status_code']
            self.assert_obj['错误信息'] = result_obj['response_content']
            self.need_assert = False
            self.assert_result = False
            return
        # 请求状态为成功,判断业务状态
        buiess_content = json.loads(result_obj['response_content'])
        expect_res = json.loads(test_case['expect_res'])
        # 校验规则
        for ruler in expect_res:
            matcher = jsonpath.jsonpath(buiess_content, ruler['rule'])
            if isinstance(matcher,bool):
                self.assert_obj['请求状态'] = result_obj['status_code']
                self.assert_obj['错误信息'] = '规则:' + ruler['rule'] + '值不匹配,期望是:' + str(ruler['value']) + ',返回是:' + str(
                    matcher)
                self.assert_result = False
                break
            elif len(matcher) == 0:
                self.assert_obj['请求状态'] = result_obj['status_code']
                self.assert_obj['错误信息'] = '规则:' + ruler['rule'] + '提取出的数组长度为0'
                self.assert_result = False
                break
            elif ruler['type'] == 'value':  # 对值进行比较
                if matcher[0] == ruler['value']:
                    continue
                else:
                    self.assert_obj['请求状态'] = result_obj['status_code']
                    self.assert_obj['错误信息'] = '规则:' + ruler['rule'] + '值不匹配,期望是:' + str(ruler['value']) + ',返回是:' + str(
                        matcher[0])
                    self.assert_result = False
                    break
            elif ruler['type'] == 'length':  # 对数组长度进行比较
                if len(matcher) == ruler['value']:
                    continue
                else:
                    self.assert_obj['请求状态'] = result_obj['status_code']
                    self.assert_obj['错误信息'] = '规则:' + ruler['rule'] + '大小不匹配,期望是:' + str(ruler['value']) + ',返回是:' + str(
                        len(matcher))
                    self.assert_result = False
                    break
            else:
                self.assert_obj['请求状态'] = result_obj['status_code']
                self.assert_obj['错误信息'] = '规则:' + ruler['rule'] + '错误'
                self.assert_result = False
                break

    def setting_param(self):
        actives = json.loads(self.test_case['active'])
        buiess_content = json.loads(self.result_obj['response_content'])
        for active in actives:
            try:
                p_name = active['p_name']
                p_value = jsonpath.jsonpath(buiess_content, active['p_value'])
                if isinstance(p_value, bool):
                    p_value = ''
                elif len(p_value) == 0:
                    p_value = ''
                else:
                    p_value = p_value[0]
                config.PARAMS[p_name] = p_value
            except Exception as e:
                traceback.print_exc()
                info = traceback.format_exc()
                print(info)

def read_excel():
    wb = xlrd.open_workbook(config.TEST_CASE_PATH)
    sh = wb.sheet_by_name('Sheet1')
    #处理 Excel的数据
    for row_ndex in range(sh.nrows):
        test_case = dict(zip(sh.row_values(0), sh.row_values(row_ndex)))
        try:
            if row_ndex == 0:
                continue
            request_handler(test_case)
            if test_case['error_continue'] == 0 and not config.CURRENT_REQUEST_STATUS:
                break

        except Exception as e:
            traceback.print_exc()
            info = traceback.format_exc()
            print(info)
            #config.ALL_REQUEST_RESULT.append({"测试用例": test_case, "请求异常": e})
    #发送邮件通知成功与否
    message  = ''
    for result_record in  config.ALL_REQUEST_RESULT:
        message += json.dumps(result_record,ensure_ascii=False) +'\n\n\n'

    send_email(message)

def send_email(message):
    if len(message) == 0:
        return
    my_sender = '[email protected]'  # 发件人邮箱账号
    my_pass = 'TongZhi@1218'  # 发件人邮箱密码
    my_user = '[email protected]'  # 收件人邮箱账号,我这边发送给自己
    ret = True
    try:
        msg = MIMEText(message, 'plain', 'utf-8')
        msg['From'] = formataddr(["小课接口测试报告", my_sender])  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
        msg['To'] = formataddr(["250", my_user])  # 括号里的对应收件人邮箱昵称、收件人邮箱账号
        msg['Subject'] = "小课接口测试报告"  # 邮件的主题,也可以说是标题

        server = smtplib.SMTP_SSL("imap.exmail.qq.com", 465)  # 发件人邮箱中的SMTP服务器,端口是25
        server.login(my_sender, my_pass)  # 括号中对应的是发件人邮箱账号、邮箱密码
        server.sendmail(my_sender, [my_user, ], msg.as_string())  # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
        server.quit()  # 关闭连接

    except Exception as e:  # 如果 try 中的语句没有执行,则会执行下面的 ret=False
        traceback.print_exc()
        info = traceback.format_exc()
        print(info)
        ret = False
    if ret:
        print("发送邮件成功")
    else:
        print('发送邮件失败')

#config = Config(r'http://test-keepapi.kuaizaixuetang.com', r'http://192.168.1.221:8917',r'G:\python_project\test_api\test_case.xlsx')
if __name__ == '__main__':
    argv = sys.argv
    if len(sys.argv) != 4:
        print('参数个数不正确')
    php_api = argv[1]
    java_api = argv[2]
    excel_path = argv[3]
    config = Config(php_api, java_api, excel_path)
    read_excel()

EXCEL案列

猜你喜欢

转载自www.cnblogs.com/wangshunyao/p/10563722.html