python+requests+excel 接口自動化測試框架(二)

前言:該篇重點講數據依賴、cookie處理和發送郵件(部分方法在第一篇中已經編寫)

一、 數據依賴簡單說明

接口B的請求數據依賴於接口A的返回數據,即爲數據依賴。比如說:接口B(圖2)是一個支付接口,接口A(圖1)是一個訂單提交接口。接口B中請求數據trade_number的值來源於接口A的響應數據out_trade_no的值

                                                      圖 1

                                                       圖 2

二、 解決數據依賴方法封裝

創建文件 dataconfig/dependent_data.py

from utils.operation_excel import OperationExcel
from base.run_method import RunMethod
from dataconfig.get_data import GetData
import json
from jsonpath_rw import jsonpath,parse


class DependentData(object):
    def __init__(self, case_id):
        self.opera_excel = OperationExcel()
        self.case_id = case_id
        self.data = GetData()

    # 通過case_id獲取該case_id的整行數據
    def get_case_line_data(self):
        rows_data = self.opera_excel.get_rows_data(self.case_id)
        return rows_data

    # 執行依賴測試,獲取結果
    def run_dependent(self):
        run_method = RunMethod()
        row_num = self.opera_excel.get_row_num(self.case_id)
        request_data = self.data.get_data_from_json(row_num)
        method = self.data.get_request_method(row_num)
        url = self.data.get_url(row_num)
        res = run_method.run_main(method, url, request_data)
        return json.loads(res)

    # 根據依賴的key去獲取執行依賴測試的case響應,然後返回
    def get_data_for_key(self, row):
        # 依賴的返回數據的格式要注意層級關係
        depend_data = self.data.get_depend_key(row)
        response_data = self.run_dependent()
        # jsonpath_rw類似於xpath
        json_exe = parse(depend_data)
        # 從響應數據結果集中找到依賴的返回數據
        model = json_exe.find(response_data)
        # 類似於for循環,i是字典類型的
        return [math.value for math in model][0]

三、 cookie處理簡單說明

訪問某些接口前需要登錄,即需要攜帶cookies才能訪問成功,則需要先訪問登錄接口,然後把cookies信息存儲在json文件中

實例:接口A(登錄接口)請求後,自動調用接口B。接口B使用接口A中的token作爲請求數據,且返回cookies。訪問接口C時,必須攜帶cookies才能訪問成功,如下圖所示,接口順序依次是A、B和C

用例修改如下,運行時會判斷“是否攜帶header”字段的值:

四、 封裝處理cookies方法

1. 創建 utils/operation_header.py

import requests
import json
from utils.operation_json import OperationJson


class OperationHeader(object):
    def __init__(self, response):
        self.response = json.loads(response)

    # 獲取登錄返回的響應數據中url的內容,根據實際接口情況來編寫該方法
    def get_response_url(self):
        url = self.response['data']['url'][0]
        return url

    # 獲取cookie的jar文件
    def get_cookie(self):
        # 請求數據中除了url,還有另外兩個參數callback和_
        url = self.get_response_url()+"&callback=jQuery21008240514814031887_1508666806688&_=1508666806689"
        cookie = requests.get(url).cookies
        return cookie

    def write_cookie(self):
        cookie = requests.utils.dict_from_cookiejar(self.get_cookie())
        op_json = OperationJson()
        op_json.write_data(cookie)

2. 創建空文件data/cookie.json ,運行程序後該文件中存儲cookies的值

五、 發送郵件

創建文件 utils/send_mail.py

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.mime.text import MIMEText
import smtplib


class SendEmail(object):
    def send_mail(self, user_list, subject, content, file):

        smtpserver = 'smtp.qq.com'
        user = '[email protected]'
        password = "XXX"
        sender = '[email protected]'
        receives = user_list

        # 構造郵件對象
        msg = MIMEMultipart('mixed')
        # 定義郵件的標題
        subject = subject
        # HTML郵件正文,定義成字典
        msg['Subject'] = Header(subject, "utf-8")
        msg['From'] = sender
        msg['To'] = ','.join(receives)
        # 構造文字內容
        text_plain = MIMEText(content)
        msg.attach(text_plain)
        # 構造附件
        text_attr = MIMEText(file, 'base64', 'utf-8')
        text_attr["Content-Type"] = 'application/octet-stream'
        text_attr['Content-Disposition'] = 'attachment; filename = "report.xls"'
        msg.attach(text_attr)

        # 郵箱設置時勾選了SSL加密連接,進行防垃圾郵件,SSL協議端口號要使用465???
        smtp = smtplib.SMTP_SSL(smtpserver, 465)
        # 向服務器標識用戶身份
        smtp.helo(smtpserver)
        # 向服務器返回確認結果
        smtp.ehlo(smtpserver)
        # 登錄郵箱的賬號和授權密碼
        smtp.login(user, password)

        print("start send email...")
        # 開始進行郵件的發送,msg表示已定義的字典
        smtp.sendmail(sender, receives, msg.as_string())
        smtp.quit()
        print("send email end")

    def send_main(self, pass_list, fail_list):
        pass_num = float(len(pass_list))
        fail_num = float(len(fail_list))
        count_num = pass_num + fail_num
        pass_result = "%.2f%%" % (pass_num/count_num*100)
        fail_result = "%.2f%%" % (fail_num / count_num * 100)

        user_list = ["[email protected]"]
        subject = "接口自動化測試報告"
        content = "此次一共運行接口個數爲%s個,通過個數爲%s個,失敗個數爲%s,通過率爲%s,失敗率爲%s" % (count_num, pass_num, fail_num, pass_result, fail_result)
        file = open("../data/imooc_case.xls", 'rb').read()
        self.send_mail(user_list, subject, content, file)

六、 連接數據庫

創建文件 utils/connect_db.py

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
import pymysql
import json


class OperationMysql(object):
    def __init__(self):
        self.connect = pymysql.Connect(
            host='localhost',
            port=3306,
            user='admin',
            passwd='111111',
            db='MySQL',
            charset='utf8'
        )
        self.cur = self.connect.cursor()

    # 查詢一條數據
    def search_one(self, sql):
        # 用execute系列方法執行sql
        self.cur.execute(sql)
        # fetchone()每次獲取一條記錄
        result = self.cur.fetchone()
        # result = self.cur.fetchall()
        result = json.dumps(result)
        return result

七、 修改run_test.py文件(添加數據依賴、cookies處理和發送郵件)

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
from base.run_method import RunMethod
from dataconfig.get_data import GetData
from dataconfig.dependent_data import DependentData
from utils.operation_header import OperationHeader
from utils.operation_json import OperationJson
from utils.common_util import CommonUtil
from utils.send_mail import SendEmail


class RunTest(object):
    def __init__(self):
        self.data = GetData()
        self.run_method = RunMethod()
        self.com_util = CommonUtil()
        self.send_mail = SendEmail()

    # 執行程序
    def go_on_run(self):
        pass_count = []
        fail_count = []
        # 下標從0開始
        rows_count = self.data.get_case_lines()
        # 從下標1開始循環取數據,忽略第一行表頭數據
        for i in range(1, rows_count):
            is_run = self.data.get_is_run(i)
            if is_run:
                method = self.data.get_request_method(i)
                url = self.data.get_url(i)
                # data = self.data.get_request_data(i)
                data = self.data.get_data_from_json(i)
                headers = self.data.get_is_header(i)
                # expect = self.data.get_expect_data_from_mysql(i)
                expect = self.data.get_expect_data(i)
                depend_case = self.data.get_is_depend(i)
                '''
                暫時沒用到數據依賴
                '''
                if depend_case != None:
                    self.depend_data = DependentData(depend_case)
                    # 獲取依賴的響應數據
                    depend_response_data = self.depend_data.get_data_for_key(i)
                    # 獲取數據依賴字段
                    depend_key = self.data.get_depend_field(i)
                    # 請求數據中的“數據依賴字段"的值更新成“依賴的返回數據”
                    data[depend_key] = depend_response_data
                if headers == "write":
                    res = self.run_method.run_main(method, url, data)
                    op_header = OperationHeader(res)
                    op_header.write_cookie()

                elif headers == "yes":
                    op_json = OperationJson('../data/cookie.json')
                    cookie = op_json.get_data('apsid')
                    cookies = {
                        'apsid': cookie
                    }
                    res = self.run_method.run_main(method, url, data, cookies)

                else:
                    res = self.run_method.run_main(method, url, data)

                if self.com_util.is_contain(expect, res):
                    self.data.write_result(i, 'pass')
                    pass_count.append(i)
                else:
                    self.data.write_result(i, res)
                    fail_count.append(i)
        print("成功的用例數:", len(pass_count))
        print("失敗的用例數:", len(fail_count))
        self.send_mail.send_main(pass_count, fail_count)


if __name__ == '__main__':
    run = RunTest()
    run.go_on_run()

運行結果:

備註:數據依賴未調試通,暫時刪除了需要用到數據依賴的接口

八、 項目目錄:

九、 持續集成

1. 使用jenkins,配置項目信息。具體步驟:新建任務(選擇第一個自由風格)->使用自定義的工作空間(目錄是要運行的文件所在的路徑),如圖1->構建選擇“執行windows批處理命令”,並輸入如下命令,如圖2

                                                                                                     圖1

                                                                  圖2

2.運行結果如下:

3.報錯解決辦法:

https://blog.csdn.net/changyixue/article/details/100707205

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章