• Python+requests+unittest+excel接口自动化测试框架


    一、框架结构:

    工程目录

    二、Case文件设计

    三、基础包 base

    3.1 封装get/post请求(runmethon.py)

    1. imp
    2. import json
    3. class RunMethod:
    4. def post_main(self,url,data,header=None):
    5. res = None
    6. if header !=None:
    7. res = requests.post(url=url,data=data,headers=header)
    8. else:
    9. res = requests.post(url=url,data=data)
    10. return res.json()
    11. def get_main(self,url,data=None,header=None):
    12. res = None
    13. if header !=None:
    14. res = requests.get(url=url,data=data,headers=header,verify=False)
    15. else:
    16. res = requests.get(url=url,data=data,verify=False)
    17. return res.json()
    18. def run_main(self,method,url,data=None,header=None):
    19. res = None
    20. if method == 'Post':
    21. res = self.post_main(url,data,header)
    22. else:
    23. res = self.get_main(url,data,header)
    24. return json.dumps(res,ensure_ascii=False,sort_keys=True,indent=2)

    3.2 封装mock(mock.py)

    1. from mock import mock
    2. #模拟mock 封装
    3. def mock_test(mock_method,request_data,url,method,response_data):
    4. mock_method = mock.Mock(return_value=response_data)
    5. res = mock_method(url,method,request_data)
    6. return res

    四、数据操作包 operation_data4.1 获取excel单元格中的内容(get_data.py)  

    1. #coding:utf-8
    2. from tool.operation_excel import OperationExcel
    3. import data_config
    4. from tool.operation_json import OperetionJson
    5. from tool.connect_db import OperationMysql
    6. class GetData:
    7. def __init__(self):
    8. self.opera_excel = OperationExcel()
    9. #去获取excel行数,就是case的个数
    10. def get_case_lines(self):
    11. return self.opera_excel.get_lines()
    12. #获取是否执行
    13. def get_is_run(self,row):
    14. flag = None
    15. col = int(data_config.get_run())
    16. run_model = self.opera_excel.get_cell_value(row,col)
    17. if run_model == 'yes':
    18. flag = True
    19. else:
    20. flag = False
    21. return flag
    22. #是否携带header
    23. def is_header(self,row):
    24. col = int(data_config.get_header())
    25. header = self.opera_excel.get_cell_value(row,col)
    26. if header != '':
    27. return header
    28. else:
    29. return None
    30. #获取请求方式
    31. def get_request_method(self,row):
    32. col = int(data_config.get_run_way())
    33. request_method = self.opera_excel.get_cell_value(row,col)
    34. return request_method
    35. #获取url
    36. def get_request_url(self,row):
    37. col = int(data_config.get_url())
    38. url = self.opera_excel.get_cell_value(row,col)
    39. return url
    40. #获取请求数据
    41. def get_request_data(self,row):
    42. col = int(data_config.get_data())
    43. data = self.opera_excel.get_cell_value(row,col)
    44. if data == '':
    45. return None
    46. return data
    47. #通过获取关键字拿到data数据
    48. def get_data_for_json(self,row):
    49. opera_json = OperetionJson()
    50. request_data = opera_json.get_data(self.get_request_data(row))
    51. return request_data
    52. #获取预期结果
    53. def get_expcet_data(self,row):
    54. col = int(data_config.get_expect())
    55. expect = self.opera_excel.get_cell_value(row,col)
    56. if expect == '':
    57. return None
    58. return expect
    59. #通过sql获取预期结果
    60. def get_expcet_data_for_mysql(self,row):
    61. op_mysql = OperationMysql()
    62. sql = self.get_expcet_data(row)
    63. res = op_mysql.search_one(sql)
    64. return res.decode('unicode-escape')
    65. def write_result(self,row,value):
    66. col = int(data_config.get_result())
    67. self.opera_excel.write_value(row,col,value)
    68. #获取依赖数据的key
    69. def get_depend_key(self,row):
    70. col = int(data_config.get_data_depend())
    71. depent_key = self.opera_excel.get_cell_value(row,col)
    72. if depent_key == "":
    73. return None
    74. else:
    75. return depent_key
    76. #判断是否有case依赖
    77. def is_depend(self,row):
    78. col = int(data_config.get_case_depend())
    79. depend_case_id = self.opera_excel.get_cell_value(row,col)
    80. if depend_case_id == "":
    81. return None
    82. else:
    83. return depend_case_id
    84. #获取数据依赖字段
    85. def get_depend_field(self,row):
    86. col = int(data_config.get_field_depend())
    87. data = self.opera_excel.get_cell_value(row,col)
    88. if data == "":
    89. return None
    90. else:
    91. return data 

    4.2 获取excel中每个列(data_config.py)

    1. #coding:utf-8
    2. class global_var:
    3. #case_id
    4. Id = '0'
    5. request_name = '1'
    6. url = '2'
    7. run = '3'
    8. request_way = '4'
    9. header = '5'
    10. case_depend = '6'
    11. data_depend = '7'
    12. field_depend = '8'
    13. data = '9'
    14. expect = '10'
    15. result = '11'
    16. #获取caseid
    17. def get_id():
    18. return global_var.Id
    19. #获取url
    20. def get_url():
    21. return global_var.url
    22. def get_run():
    23. return global_var.run
    24. def get_run_way():
    25. return global_var.request_way
    26. def get_header():
    27. return global_var.header
    28. def get_case_depend():
    29. return global_var.case_depend
    30. def get_data_depend():
    31. return global_var.data_depend
    32. def get_field_depend():
    33. return global_var.field_depend
    34. def get_data():
    35. return global_var.data
    36. def get_expect():
    37. return global_var.expect
    38. def get_result():
    39. return global_var.result
    40. def get_header_value():
    41. return global_var.header

      

    4.3 解决数据依赖(dependent.py )

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    #coding:utf-8

     import sys

     import json

     sys.path.append('C:/Users/lxz/Desktop/InterFace_JIA')

     from tool.operation_excel import OperationExcel

     from base.runmethod import RunMethod

     from operation_data.get_data import GetData

     from jsonpath_rw import jsonpath,parse

     class DependdentData:

     def __init__(self,case_id):

     self.case_id = case_id

     self.opera_excel = OperationExcel()

     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_for_json(row_num)

     #header = self.data.is_header(row_num)

     method = self.data.get_request_method(row_num)

     url = self.data.get_request_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()

     json_exe = parse(depend_data)

     madle = json_exe.find(response_data)

     return [math.value for math in madle][0]

      

     if __name__ == '__main__':

     order = {

     "data": {

     "_input_charset""utf-8",

     "body""京东订单-1710141907182334",

     "it_b_pay""1d",

     "notify_url""http://order.imooc.com/pay/notifyalipay",

     "out_trade_no""1710141907182334",

     "partner""2088002966755334",

     "payment_type""1",

     "seller_id""yangyan01@tcl.com",

    "service""mobile.securitypay.pay",

    "sign": "kZBV53KuiUf5HIrVLBCcBpWDg%2FnzO%2BtyEnBqgVYwwBtDU66Xk8VQUTbVOqDjrNymCupkVhlI%2BkFZq1jOr8C554KsZ7Gk7orC9dDbQl

    pr%2BaMmdjO30JBgjqjj4mmM%2Flphy9Xwr0Xrv46uSkDKdlQqLDdGAOP7YwOM2dSLyUQX%2Bo4%3D",

     "sign_type""RSA",

     "string": "_input_charset=utf-8&body=京东订单-1710141907182334&it_b_pay=1d¬ify_url=http://order.imooc.com/pay/

    notifyalipay&out_trade_no=1710141907182334&partner=2088002966755334&payment_type=1&seller_id=yangyan01@

    tcl.com&service=mobile.securitypay.pay&subject=京东订单-1710141907182334&total_fee=299&sign=kZBV53KuiUf5H

    IrVLBCcBpWDg%2FnzO%2BtyEnBqgVYwwBtDU66Xk8VQUTbVOqDjrNymCupkVhlI%2BkFZq1jOr8C554KsZ7Gk7orC9dDbQlpr%2BaMmdjO30

    JBgjqjj4mmM%2Flphy9Xwr0Xrv46uSkDKdlQqLDdGAOP7YwOM2dSLyUQX%2Bo4%3D&sign_type=RSA",

     "subject""京东订单-1710141907182334",

     "total_fee"299

     },

     "errorCode"1000,

     "errorDesc""成功",

     "status"1,

     "timestamp"1507979239100

     }

     res = "data.out_trade_no"

     json_exe = parse(res)

     madle = json_exe.find(order)

     print [math.value for math in madle][0]

    五、工具类包 tool5.1 操作excel (operation_excel.py)

    1. #coding:utf-8
    2. import xlrd
    3. from xlutils.copy import copy
    4. class OperationExcel:
    5. def __init__(self,file_name=None,sheet_id=None):
    6. if file_name:
    7. self.file_name = file_name
    8. self.sheet_id = sheet_id
    9. else:
    10. self.file_name = '../dataconfig/case1.xls'
    11. self.sheet_id = 0
    12. self.data = self.get_data()
    13. #获取sheets的内容
    14. def get_data(self):
    15. data = xlrd.open_workbook(self.file_name)
    16. tables = data.sheets()[self.sheet_id]
    17. return tables
    18. #获取单元格的行数
    19. def get_lines(self):
    20. tables = self.data
    21. return tables.nrows
    22. #获取某一个单元格的内容
    23. def get_cell_value(self,row,col):
    24. return self.data.cell_value(row,col)
    25. #写入数据
    26. def write_value(self,row,col,value):
    27. '''
    28. 写入excel数据
    29. row,col,value
    30. '''
    31. read_data = xlrd.open_workbook(self.file_name)
    32. write_data = copy(read_data)
    33. sheet_data = write_data.get_sheet(0)
    34. sheet_data.write(row,col,value)
    35. write_data.save(self.file_name)
    36. #根据对应的caseid 找到对应行的内容
    37. def get_rows_data(self,case_id):
    38. row_num = self.get_row_num(case_id)
    39. rows_data = self.get_row_values(row_num)
    40. return rows_data
    41. #根据对应的caseid找到对应的行号
    42. def get_row_num(self,case_id):
    43. num = 0
    44. clols_data = self.get_cols_data()
    45. for col_data in clols_data:
    46. if case_id in col_data:
    47. return num
    48. num = num+1
    49. #根据行号,找到该行的内容
    50. def get_row_values(self,row):
    51. tables = self.data
    52. row_data = tables.row_values(row)
    53. return row_data
    54. #获取某一列的内容
    55. def get_cols_data(self,col_id=None):
    56. if col_id != None:
    57. cols = self.data.col_values(col_id)
    58. else:
    59. cols = self.data.col_values(0)
    60. return cols
    61. if __name__ == '__main__':
    62. opers = OperationExcel()
    63. print opers.get_cell_value(1,2)

    5.2判断字符串包含,判断字典是否相等(common_util.py)

    1. #coding:utf-8
    2. import json
    3. class CommonUtil:
    4. def is_contain(self,str_one,str_two):
    5. '''
    6. 判断一个字符串是否再另外一个字符串中
    7. str_one:查找的字符串
    8. str_two:被查找的字符串
    9. '''
    10. flag = None
    11. if isinstance(str_one,unicode):
    12. str_one = str_one.encode('unicode-escape').decode('string_escape')
    13. return cmp(str_one,str_two)
    14. if str_one in str_two:
    15. flag = True
    16. else:
    17. flag = False
    18. return flag
    19. def is_equal_dict(self,dict_one,dict_two):
    20. '''
    21. 判断两个字典是否相等
    22. '''
    23. if isinstance(dict_one,str):
    24. dict_one = json.loads(dict_one)
    25. if isinstance(dict_two,str):
    26. dict_two = json.loads(dict_two)
    27. return cmp(dict_one,dict_two)

    5.3 操作header(operation_herder.py)

    1. #coding:utf-8
    2. import requests
    3. import json
    4. from operation_json import OperetionJson
    5. class OperationHeader:
    6. def __init__(self,response):
    7. self.response = json.loads(response)
    8. def get_response_url(self):
    9. '''
    10. 获取登录返回的token的url
    11. '''
    12. url = self.response['data']['url'][0]
    13. return url
    14. def get_cookie(self):
    15. '''
    16. 获取cookie的jar文件
    17. '''
    18. url = self.get_response_url()+"&callback=jQuery21008240514814031887_1508666806688&_=1508666806689"
    19. cookie = requests.get(url).cookies
    20. return cookie
    21. def write_cookie(self):
    22. cookie = requests.utils.dict_from_cookiejar(self.get_cookie())
    23. op_json = OperetionJson()
    24. op_json.write_data(cookie)
    25. if __name__ == '__main__':
    26. url = "http://www.jd.com/passport/user/login"
    27. data = {
    28. "username":"18513199586",
    29. "password":"111111",
    30. "verify":"",
    31. "referer":"https://www.jd.com"
    32. }
    33. res = json.dumps(requests.post(url,data).json())
    34. op_header = OperationHeader(res)
    35. op_header.write_cookie()

    5.4 操作json文件(operation_json.py)

    1. #coding:utf-8
    2. import json
    3. class OperetionJson:
    4. def __init__(self,file_path=None):
    5. if file_path == None:
    6. self.file_path = '../dataconfig/user.json'
    7. else:
    8. self.file_path = file_path
    9. self.data = self.read_data()
    10. #读取json文件
    11. def read_data(self):
    12. with open(self.file_path) as fp:
    13. data = json.load(fp)
    14. return data
    15. #根据关键字获取数据
    16. def get_data(self,id):
    17. print type(self.data)
    18. return self.data[id]
    19. #写json
    20. def write_data(self,data):
    21. with open('../dataconfig/cookie.json','w') as fp:
    22. fp.write(json.dumps(data))
    23. if __name__ == '__main__':
    24. opjson = OperetionJson()
    25. print opjson.get_data('shop')

    5.5 操作数据库(connect_db.py)

    1. #coding:utf-8
    2. import MySQLdb.cursors
    3. import json
    4. class OperationMysql:
    5. def __init__(self):
    6. self.conn = MySQLdb.connect(
    7. host='localhost',
    8. port=3306,
    9. user='root',
    10. passwd='123456',
    11. db='le_study',
    12. charset='utf8',
    13. cursorclass=MySQLdb.cursors.DictCursor
    14. )
    15. self.cur = self.conn.cursor()
    16. #查询一条数据
    17. def search_one(self,sql):
    18. self.cur.execute(sql)
    19. result = self.cur.fetchone()
    20. result = json.dumps(result)
    21. return result
    22. if __name__ == '__main__':
    23. op_mysql = OperationMysql()
    24. res = op_mysql.search_one("select * from web_user where Name='ailiailan'")
    25. print res

    5.6 发送报告邮件(send_email.py)

    1. #coding:utf-8
    2. import smtplib
    3. from email.mime.text import MIMEText
    4. class SendEmail:
    5. global send_user
    6. global email_host
    7. global password
    8. email_host = "smtp.163.com"
    9. send_user = "jiaxiaonan666@163.com"
    10. password = "jia_668"
    11. def send_mail(self,user_list,sub,content):
    12. user = "jiaxiaonan"+"<"+send_user+">"
    13. message = MIMEText(content,_subtype='plain',_charset='utf-8')
    14. message['Subject'] = sub
    15. message['From'] = user
    16. message['To'] = ";".join(user_list)
    17. server = smtplib.SMTP()
    18. server.connect(email_host)
    19. server.login(send_user,password)
    20. server.sendmail(user,user_list,message.as_string())
    21. server.close()
    22. def send_main(self,pass_list,fail_list):
    23. pass_num = float(len(pass_list))
    24. fail_num = float(len(fail_list))
    25. count_num = pass_num+fail_num
    26. #90%
    27. pass_result = "%.2f%%" %(pass_num/count_num*100)
    28. fail_result = "%.2f%%" %(fail_num/count_num*100)
    29. user_list = ['609037724@qq.com']
    30. sub = "接口自动化测试报告"
    31. content = "此次一共运行接口个数为%s个,通过个数为%s个,失败个数为%s,通过率为%s,失败率为%s" %(count_num,pass_num,fail_num,pass_result,fail_result )
    32. self.send_mail(user_list,sub,content)
    33. if __name__ == '__main__':
    34. sen = SendEmail()
    35. sen.send_main([1,2,3,4],[2,3,4,5,6,7]) 

     
    

    六、主函数

    1. run_test.py
    2. #coding:utf-8
    3. import sys
    4. sys.path.append("C:/Users/lxz/Desktop/InterFace_JIA")
    5. from base.runmethod import RunMethod
    6. from operation_data.get_data import GetData
    7. from tool.common_util import CommonUtil
    8. from operation_data.dependent_data import DependdentData
    9. from tool.send_email import SendEmail
    10. from tool.operation_header import OperationHeader
    11. from tool.operation_json import OperetionJson
    12. class RunTest:
    13. def __init__(self):
    14. self.run_method = RunMethod()
    15. self.data = GetData()
    16. self.com_util = CommonUtil()
    17. self.send_mai = SendEmail()
    18. #程序执行的
    19. def go_on_run(self):
    20. res = None
    21. pass_count = []
    22. fail_count = []
    23. #10 0,1,2,3
    24. rows_count = self.data.get_case_lines()
    25. for i in range(1,rows_count):
    26. is_run = self.data.get_is_run(i)
    27. if is_run:
    28. url = self.data.get_request_url(i)
    29. method = self.data.get_request_method(i)
    30. request_data = self.data.get_data_for_json(i)
    31. expect = self.data.get_expcet_data_for_mysql(i)
    32. header = self.data.is_header(i)
    33. depend_case = self.data.is_depend(i)
    34. if depend_case != None:
    35. self.depend_data = DependdentData(depend_case)
    36. #获取的依赖响应数据
    37. depend_response_data = self.depend_data.get_data_for_key(i)
    38. #获取依赖的key
    39. depend_key = self.data.get_depend_field(i)
    40. request_data[depend_key] = depend_response_data
    41. if header == 'write':
    42. res = self.run_method.run_main(method,url,request_data)
    43. op_header = OperationHeader(res)
    44. op_header.write_cookie()
    45. elif header == 'yes':
    46. op_json = OperetionJson('../dataconfig/cookie.json')
    47. cookie = op_json.get_data('apsid')
    48. cookies = {
    49. 'apsid':cookie
    50. }
    51. res = self.run_method.run_main(method,url,request_data,cookies)
    52. else:
    53. res = self.run_method.run_main(method,url,request_data)
    54. if self.com_util.is_equal_dict(expect,res) == 0:
    55. self.data.write_result(i,'pass')
    56. pass_count.append(i)
    57. else:
    58. self.data.write_result(i,res)
    59. fail_count.append(i)
    60. self.send_mai.send_main(pass_count,fail_count)
    61. #将执行判断封装
    62. #def get_cookie_run(self,header):
    63. if __name__ == '__main__':
    64. run = RunTest()
    65. run.go_on_run()

    Python接口自动化测试零基础入门到精通(2023最新版)

  • 相关阅读:
    3D游戏建模学习路线
    软件产品质量如何保障?找对软件测试公司是关键
    DevOps简介
    Mybatis Mapper接口和xml绑定的多种方式、内部实现原理和过程
    利用代码生成工具快速生成基于SqlSugar框架的Winform界面项目
    JVM之垃圾回收器一
    5┃音视频直播系统之 WebRTC 中的协议UDP、TCP、RTP、RTCP详解
    【计算机网络】期末复习(全是大题)
    聚类算法模型评价指标
    Python-Flask快速上手
  • 原文地址:https://blog.csdn.net/m0_68405758/article/details/133866870