python接口自动化测试框架

前言

忘记从哪篇文章得到的框架了,后面还可以按需优化,整体还行吧,目前比较简单,不过也可以在项目中使用,下面记录下

框架

测试数据

xls格式的文件,jinrongcase.xls

python接口自动化测试框架_第1张图片

整体形式

python+request+excel/html_report+sendmail,

代码结构

先看下结构(其实这里可以把7拿出来,建立一个testcase文件夹,将测试用例独立出来,再搞一个run文件夹专门放启动代码的脚本):

python接口自动化测试框架_第2张图片

说明下:他的测试结果有两种呈现方式,一个是 在原测试用例excel中写入实际测试结果的excel文件:

python接口自动化测试框架_第3张图片

还有一个就是html的一个report:

python接口自动化测试框架_第4张图片

如果在项目中使用,个人建议后期把他的html的report优化下,改成用HTMLTestRunner(网上有,搜一下)这个文件输出的报告,会好看一点,比如下面这个(后期有时间或者有机会我会优化好提供出来):

python接口自动化测试框架_第5张图片

详细介绍

自动化测试的思路:

处理数据→请求数据→断言结果→输出报告→邮件通知

1. 数据预处理

处理数据,这个地方使用的是python的 wlrd库,读写excel文件

excelutils.py→excel用例读取,获取用例条数,用例内容,另外额外提供了一个写入excel的方法,为后期将测试结果写回到excel做准备,

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author : zhh
# @Tel    : 1871253****
# @Time   : 2020/3/25 22:05
# @File   : demo.py

import xlrd
from xlutils.copy import copy

'''
本部分是读取excel里面的测试用例。获取其中的内容

'''

class ExcelUtils:
    # 初始化的函数
    def __init__(self, excel_file="../dataconfig/jinrongcase.xls",table_index=0):
        #打开工作簿
        workbook = xlrd.open_workbook(excel_file)
        # 获取对应的表
        self.table = workbook.sheets()[table_index]
        self.excel_file = excel_file
        self.workbook = workbook
    # 能够获取当前多少个测试用例
    def getCaseCount(self):
        return self.table.nrows # 表格的行数

    # 获取单元格内容
    def getExcelData(self, row, col):
        return self.table.cell_value(row, col)

    # 写入单元格内容
    def writeExcelData(self, row, col, value):
        #先重新打开工作簿
        read_data = xlrd.open_workbook(self.excel_file)
        #copy复制保留
        write_data = copy(read_data)
        #获取第一个工作表
        sheet_data = write_data.get_sheet(0)
        #写入内容
        sheet_data.write(row, col, value)
        #保存
        write_data.save(self.excel_file)


# if __name__ == '__main__':
#     excelUtils = ExcelUtils()
#     print(excelUtils.getCaseCount())
#     print(excelUtils.getExcelData(0, 5))
#     excelUtils.writeExcelData(3, 12, "我我我")

varsutils.py →索引类,索引数字是对照excel表格的测试用例来定义的,主要方面后期数据二次处理时excel中各列数据的获取,

python接口自动化测试框架_第6张图片

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author : zhh
# @Tel    : 1871253****
# @Time   : 2020/3/25 22:05
# @File   : demo.py

from selenium.webdriver.common.by import By


# 定义索引的工具类
class VarUtils:
    # id的索引
    ID = 0
    # 请求名称的索引
    REQUEST_NAME = 1
    # 请求地址的索引
    REQUEST_URL = 2
    # 请求方式的索引
    REQUEST_METHOD = 3
    # 请求参数的索引
    REQUEST_PARAMS = 4
    # 请求头的索引
    REQUEST_HEADERS = 5
    # 预期结果的索引
    EXPECT_RESULT = 6
    # 实际结果的索引
    ACTUAL_RESULT = 7
    # 是否通过的索引
    IS_PASSED = 8

datautils.py→数据的二次处理,工具类,详细的提取接口请求需要的数据,分类封装各种方法

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author : zhh
# @Tel    : 1871253****
# @Time   : 2020/3/25 22:05
# @File   : demo.py

import json
# 数据工具类
from common.excelutils import ExcelUtils
from common.varutils import VarUtils


class DataUtils:
    def __init__(self):
        # 用到excelUtils对象
        self.excelutils = ExcelUtils()

    # 获取用例id
    def getCaseId(self, row):
        return self.excelutils.getExcelData(row, VarUtils.ID)

    # 获取用例名称
    def getCaseName(self, row):
        return self.excelutils.getExcelData(row, VarUtils.REQUEST_NAME)

    # 获取请求方式
    def getRequestMethod(self, row):
        return self.excelutils.getExcelData(row, VarUtils.REQUEST_METHOD)

    # 获取请求地址
    def getRequestUrl(self, row):
        return self.excelutils.getExcelData(row, VarUtils.REQUEST_URL)

    # 获取请求参数
    def getRequestParams(self, row):
        param = self.excelutils.getExcelData(row, VarUtils.REQUEST_PARAMS)
        if param != "":
            return json.loads(self.excelutils.getExcelData(row, VarUtils.REQUEST_PARAMS))
        else:
            return {}

    # 获取请求头
    def getRequestHeaders(self, row):
        result = self.excelutils.getExcelData(row, VarUtils.REQUEST_HEADERS)
        if result == None or result == "" or result == "否":
            return None
        else:
            return result

    # 获取预期结果
    def getExpectResult(self, row):
        str = self.excelutils.getExcelData(row, VarUtils.EXPECT_RESULT)
        return str

    # 设置实际结果
    def setActualResult(self, row, dict):
        str = json.dumps(dict, indent=4, ensure_ascii=False, sort_keys=True)
        self.excelutils.writeExcelData(row, VarUtils.ACTUAL_RESULT, str)

    # 设置是否通过 boolean类型
    def setIsPassed(self, row, flag):
        if flag == True:
            self.excelutils.writeExcelData(row, VarUtils.IS_PASSED, "通过")
        else:
            self.excelutils.writeExcelData(row, VarUtils.IS_PASSED, "不通过")


if __name__ == '__main__':
    str = '{"atatus": "200","cata": "null","bsg": "哈哈"}'
    # 通过loads将字符串转换成字典
    dict = json.loads(str)
    print(dict.get("status"))
    # 将字典转换成json字符串
    str = json.dumps(dict, indent=4, ensure_ascii=False, sort_keys=True)
    print(str)

2. request库请求接口 

requestutils.py →请求接口的工具类,一个get请求方法,一个post 请求方法(如果还有其他请求方式可以自己添加方法),一个执行请求 的方法,注意get请求的参数是字符串拼接url,post传参是放到请求体的json串,最终返回的结果都转成json

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author : zhh
# @Tel    : 1871253****
# @Time   : 2020/3/25 22:05
# @File   : demo.py
import json
import requests


class RequestUtils(object):
    # 执行get请求
    def __doGet(self, url, params=None, headers=None):
        result = {}
        if headers is None:
            result = requests.get(url, params=params).json()
        else:
            result = requests.get(url, params=params, headers=headers).json()
        return result

    # 执行post请求
    def __doPost(self, url, data, headers=None):
        # 判断是否有请求头
        result = None
        if headers == None:
            result = requests.post(url, data=json.dumps(data)).json()
        else:
            result = requests.post(url, data=json.dumps(data), headers=headers).json()
        return result

    # 执行外界调用
    def doRequest(self, url, method, data, headers):
        if method == "GET":
            return self.__doGet(url, params=data, headers=headers)
        elif method == "POST":
            return self.__doPost(url, data=data, headers=headers)
        else:
            raise Exception("没有声明请求方式,请在接口用例中声明")

# if __name__ == '__main__':
#     requestutils = RequestUtils()
#     result = requestutils.doRequest("http://127.0.0.1:8081/stest/user/login.action", "GET", {
#         "password": "123",
#         "username": "zhangsan"
#     }, None)
#     print(result)

3. html报告工具类

reportutils.py→输出html的测试报告,有一说一这个很简陋,在项目中使用建议换成HtmlTestRunner.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author : zhh
# @Tel    : 1871253****
# @Time   : 2020/3/25 22:05
# @File   : demo.py
import time


class ReportUtils:
    # 定义总用例个数
    sum_case_count = 0
    # 定义通过的用例个数
    pass_case_count = 0

    def export_report(self, list):
        # 打开文件
        filename = "../reports/" + time.strftime("%Y%m%d%H%M%S", time.localtime())+".html"
        stream = open(file=filename, mode="w", encoding="UTF-8")
        stream.write(
            ''
            ''
            '')

        for case in list:
            # 获取编号id信息
            id = case["id"]
            # 获取用例名称
            name = case["name"]
            # 获取url地址
            url = case["url"]
            # 是否通过
            is_pass = case["is_pass"]
            is_pass_str = None
            if is_pass == True:
                is_pass_str = "通过"
            else:
                is_pass_str = "不通过"

            stream.write('' % (id, name, url, is_pass_str))

        stream.write(
            '

自动化接口测试报告

用例编号' '用例名称url地址是否通过
%s%s%s%s
总结' '总用例个数:%d个 通过了%d个' '
' % ( self.sum_case_count,self.pass_case_count))

4. 发送邮件工具类

sendemail.py→发送邮件的工具类,写明邮件标题,邮件内容,和要发送的附件路径,然后指定要发送的人员邮箱(人员很多的话建议邮箱可以存在一个excel读取来获取),调用发送邮件方法即可

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author : zhh
# @Tel    : 1871253****
# @Time   : 2020/3/25 22:05
# @File   : demo.py

import smtplib

import os
from email.mime.text import MIMEText

import zmail


import importlib,sys
importlib.reload(sys)


class SendMail:


    def get_new_report(self,test_url):
        # 列举test_dir目录下的所有文件名,结果以列表的形式返回
        lists = os.listdir(test_url)
        # sort按key的关键字进行升序排列,lambda的入参fn为lists列表的元素,获取问价的最新修改时间,
        # 所以最终以文件时间从小到大排序
        # 最后对lists元素,按文件修改时间大小从小到大排序
        lists.sort(key=lambda fn: os.path.getmtime(test_url + '\\' + fn))
        # 获取最新文件的绝对路径,列表中最后一个值,文件夹+文件名
        file_path = os.path.join(test_url, lists[-1])
        return file_path

    def sndMail(self, title, content_text, attachments):
        # 附件路径
        # 你的邮件内容
        mail_content = {
            'title': title,  # 标题
            'content_text': content_text,  # 邮件内容文字
            'attachments': attachments  # 附件路径
        }

        # 使用你的邮件账户名和密码登录服务器
        server = zmail.server('[email protected]', '测试结束')
        # 多个接收邮箱,单个收件人的话,直接是receiver='[email protected]'
        receiver = ['1871253****@163.com', '1679019***@qq.com']
        # 发送邮件
        server.send_mail(receiver, mail_content)

5.  写接口测试用例,断言结果

financialtest.py→写testcase,也是用了unittest框架,写用例,然后把用例执行结果生成测试报告,邮件发送

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author : zhh
# @Tel    : 1871253****
# @Time   : 2020/3/25 22:05
# @File   : demo.py

import unittest
import time
from common.datautils import DataUtils
from common.excelutils import ExcelUtils
from common.reportutils import ReportUtils
from common.requestutils import RequestUtils
from common.sendmail import SendMail

import importlib, sys

importlib.reload(sys)


class FinancialTest(unittest.TestCase):
    def setUp(self):
        # 定义三个工具类
        self.dataUtils = DataUtils()
        self.excelUtils = ExcelUtils()
        self.requestUtils = RequestUtils()
        # 定义报告工具类
        self.reportUtils = ReportUtils()
        self.SendMail = SendMail()
        pass

    def tearDown(self):
        pass

    def testA(self):
        list = []
        # 读出所有的接口测试用例
        count = self.excelUtils.getCaseCount()
        # 遍历所有的用例,执行
        for row in range(1, count):
            dict = {}
            # 根据行获取需要的内容
            # 根据行获取url
            url = self.dataUtils.getRequestUrl(row)
            # 获取请求方式
            method = self.dataUtils.getRequestMethod(row)
            # 获取请求参数
            params = self.dataUtils.getRequestParams(row)
            # 获取请求头
            headers = self.dataUtils.getRequestHeaders(row)
            # 获取预期结果
            expetedResult = self.dataUtils.getExpectResult(row)
            # 将用例信息封装到字典中
            dict["id"] = row
            dict["name"] = self.dataUtils.getCaseName(row)
            dict["url"] = url

            # 执行相应的请求
            actualResult = self.requestUtils.doRequest(url, method=method, data=params, headers=headers)
            # =====判断预期结果是否和实际结果一致====
            errorcode = 0
            errorcode = actualResult["error_code"]
            actualMsg = actualResult["reason"]

            if str(errorcode) in expetedResult and actualMsg in expetedResult:
                print("---通过---")
                dict["is_pass"] = True
                self.dataUtils.setIsPassed(row, True)
                # 通过的个数加一
                self.reportUtils.pass_case_count += 1
            else:
                dict["is_pass"] = False
                self.dataUtils.setIsPassed(row, False)
                # 往表格中写入实际结果
                self.dataUtils.setActualResult(row, actualResult)
            # 将字典装到列表中
            list.append(dict)
        # 对总用例个数进行赋值
        self.reportUtils.sum_case_count = count - 1
        # 执行导出报告
        self.reportUtils.export_report(list)

        time.sleep(5)
        # 找到最新的报告
        file_path = self.SendMail.get_new_report(r"D:\pyproject\lenovo\reports")
        # 发送邮件
        self.SendMail.sndMail('接口自动化测试', '各位同事们好,这是接口测试结果,请查收', file_path)

你可能感兴趣的:(python,测试用例,开发语言)