自动化测试Mock神器:轻松模拟HTTP请求..

260 篇文章 1 订阅
32 篇文章 0 订阅

背景

我们把接口的信息按照规定的格式都维护在excel文件中,通过代码实现调用excel,完成接口的自动化测试。这样,只需要负责人将主要逻辑写好之后,公司其他不会写代码的员工,也可以通过维护excel中的接口数据,完成整体项目的接口自动化。

本篇文章中可能代码会偏多,原谅我文笔不是很好,不知道怎么优化文字描述。。。直接上代码,哈哈哈。。。在写的过程中部分逻辑判断不是很完整,但是主要流程是可以实现的,大家就将就着看吧。

excel数据

excel文件中的数据为下图所示:

image.png

简单说明一下:

(1)id : 测试用例的编号,格式尽量为:case_01;

(2)请求名称:自己写,能看明白就行;

(3)url:接口的路径,也可以加上域名,我没写域名,因为域名在代码中配置了,这样可以在不同环境上运行同一套代码;

(4)是否运行:当前用例是否运行;

(5)请求类型:接口的请求方式;

(6)header:当前接口是否需要header;

(7)依赖id:当前接口需要依赖哪个接口,也就是依赖的这个接口的响应结果中的某个字段是当前接口的请求参数;

(8)依赖接口的返回数据:这个后面没有用到,大家自己看情况;

(9)数据依赖字段:依赖的数据字段名;

(10)请求数据:当前接口的请求数据,页面操作之后可在F12中复制即可;

(11)预期结果:可用来做断言

(12)实际结果:写入接口的响应结果,目前也没用,大家自行写入吧

业务流程

业务名称叫散件入库(这是我自己当时公司项目中的)

该业务流程接口有4个:先新增一个散件入库单(接口1),给这个散件入库单添加需要入库的产品(接口2),此时为待提交的状态,然后提交该散件入库单(接口3),提交之后为待审核的状态,再将该散件入库单审核通过(接口4)。其中每个接口都需要token验证,token在代码中使用登录接口单独提取,全局传入。

代码实现

下面是项目下的目录,方便大家看导入的包都在哪找,目录接口其实也不是特别的合理,大家按照自己项目中的习惯排列就好。

image.png

image.png

封装的请求函数send_requests.py

  1. import requests

  2. '''封装一个接口请求方法'''

  3. def send_requests(method, url, data=None, header=None):

  4. result = ''

  5. if method == "get":

  6. res = requests.get(url=url, json=data, headers=header)

  7. result = res.json()

  8. elif method == "post":

  9. res = requests.post(url=url, json=data, headers=header)

  10. result = res.json()

  11. elif method == "delete":

  12. res = requests.delete(url=url, json=data, headers=header)

  13. result = res.json()

  14. else:

  15. print("没有包含当前的请求方式!!!")

  16. return result

封装的日志函数logger.py

在测试用例的case上面加上装饰器(@decorate_log)实现就行

  1. import logging, time, os

  2. from functools import wraps

  3. import traceback

  4. """handlers是什么?"""

  5. # logging模块中包含的类

  6. # 用来自定义日志对象的规则(比如:设置日志输出格式、等级等)

  7. # 常用子类:StreamHandler、FileHandler

  8. # StreamHandler 控制台输出日志

  9. # FileHandler 日志输出到文件

  10. BASE_PATH = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))

  11. print(BASE_PATH)

  12. # 日志文件路径

  13. LOG_PATH = os.path.join(BASE_PATH, "log")

  14. if not os.path.exists(LOG_PATH):

  15. os.mkdir(LOG_PATH)

  16. class Logger():

  17. def __init__(self):

  18. # 创建日志路径和时间

  19. """ 知识点解析 #time strftime() 函数接收以时间元组,并返回以可读字符串表示的当地时间,格式由参数 format 决定。"""

  20. self.logname = os.path.join(LOG_PATH, "{}.log".format(time.strftime("%Y%m%d")))

  21. # 创建一个logger日志对象

  22. self.logger = logging.getLogger("log")

  23. # 设置默认的日志级别

  24. self.logger.setLevel(logging.DEBUG)

  25. # 创建日志格式对象

  26. self.formater = logging.Formatter(

  27. '[%(asctime)s][%(filename)s %(lineno)d][%(levelname)s]: %(message)s')

  28. # 创建FileHandler对象

  29. """mode = 'a'"""

  30. # a=append=追加,即 给文件保存写入内容,不是覆盖之前已有文件中内容,而是放在最后,追加到最后。

  31. # 一般append追加,适用于 log日志的处理:保留之前log,追加写入新log。

  32. self.filelogger = logging.FileHandler(self.logname, mode='a', encoding="UTF-8")

  33. # 创建StreamHandler对象

  34. self.console = logging.StreamHandler()

  35. # FileHandler对象自定义日志级别

  36. self.console.setLevel(logging.DEBUG)

  37. self.filelogger.setLevel(logging.DEBUG)

  38. # 设置两个地方的格式

  39. self.filelogger.setFormatter(self.formater)

  40. self.console.setFormatter(self.formater)

  41. # logger日志对象加载FileHandler对象

  42. self.logger.addHandler(self.filelogger)

  43. # logger日志对象加载StreamHandler对象

  44. self.logger.addHandler(self.console)

  45. Logger = Logger().logger

  46. def decorate_log(func):

  47. @wraps(func)

  48. def log(*args, **kwargs):

  49. Logger.info(f'------开始执行{func.__name__}用例------')

  50. try:

  51. func(*args, **kwargs)

  52. except Exception as e:

  53. Logger.error(f'------{func.__name__}用例执行失败,失败原因:{e}------')

  54. Logger.error(f"{func.__name__} 用例 is error,here are details:{traceback.format_exc()}")

  55. raise e

  56. else:

  57. Logger.info(f'------{func.__name__}执行成功------')

  58. return log

  59. @decorate_log

  60. def funmane_wangxiaoyu():

  61. print("************")

  62. assert 2 == 2

  63. if __name__ == '__main__':

  64. funmane_wangxiaoyu()

  65. # Logger.info("---测试开始---")

  66. # Logger.error("---测试结束---")

  67. # Logger.debug("---测试结束---")

'

运行

运行

封装的工具函数operation_json.py

  1. # include json library

  2. import json

  3. class OperationJson:

  4. def __init__(self, data_str):

  5. self.data_str = data_str

  6. # 将传入的str类型转化为json格式

  7. def get_data_json(self):

  8. json_object = json.loads(self.data_str)

  9. return json_object

  10. def dict_to_str(self):

  11. # json.dumps()函数将字典转化为字符串

  12. json_info = json.dumps(self.data_str)

  13. return json_info

  14. if __name__ == '__main__':

  15. b = '{"supplierSn": "1", "sparePartsType": "451776602776477696", "remarks": ""}'

  16. a = OperationJson(b).get_data_json()

  17. print(type(a))

  18. print(a)

  19. dict1 = {"age": "12"}

  20. c = OperationJson(dict1).dict_to_str()

  21. print(c)

封装的工具函数read_yaml.py

  1. import os

  2. import yaml

  3. class HandleYaml:

  4. """读取yaml"""

  5. def read_yaml(self, filename):

  6. path = os.path.dirname(os.path.dirname(__file__))

  7. datapath = path + filename

  8. with open(datapath, encoding='utf-8') as f:

  9. result = yaml.load(f, Loader=yaml.SafeLoader)

  10. return result

  11. do_yaml = HandleYaml()

'

运行

运行

封装获取常量data_config.py

  1. # 封装获取常量

  2. from common.send_requests import send_requests

  3. from util.read_yaml import do_yaml

  4. class global_var:

  5. # case_id

  6. Id = '0'

  7. request_name = '1'

  8. url = '2'

  9. run = '3'

  10. request_way = '4'

  11. header = '5'

  12. case_dependid = '6'

  13. data_depend = '7'

  14. field_depend = '8'

  15. data = '9'

  16. expect = '10'

  17. result = '11'

  18. # 获取caseid

  19. def get_id():

  20. return global_var.Id

  21. def get_request_name():

  22. return global_var.request_name

  23. def get_url():

  24. return global_var.url

  25. def get_run():

  26. return global_var.run

  27. def get_request_way():

  28. return global_var.request_way

  29. def get_header():

  30. return global_var.header

  31. def get_case_dependid():

  32. return global_var.case_dependid

  33. def get_data_depend():

  34. return global_var.data_depend

  35. def get_field_depend():

  36. return global_var.field_depend

  37. def get_data():

  38. return global_var.data

  39. def get_expect():

  40. return global_var.expect

  41. def get_result():

  42. return global_var.result

  43. def get_header_value():

  44. # 获取header,主要是需要包含变化的token

  45. """登录接口"""

  46. url_data = '\configs\url_data.yaml'

  47. url = do_yaml.read_yaml(url_data)["baseurl"] + '/auth/login'

  48. case_data_file = '\configs\login_data.yaml'

  49. username = do_yaml.read_yaml(case_data_file)['test_login']['login_data']['username']

  50. password = do_yaml.read_yaml(case_data_file)['test_login']['login_data']['password']

  51. data = {

  52. "username": username,

  53. "password": password

  54. }

  55. header1 = {"Content-Type": "application/json;charset=UTF-8"}

  56. result = send_requests("post", url, data, header=header1)

  57. access_token = result["data"]["access_token"]

  58. header = {

  59. "Content-Type": "application/json;charset=UTF-8",

  60. "access-token": access_token

  61. }

  62. return header

  63. if __name__ == '__main__':

  64. a = get_header_value()

  65. print(type(a))

  66. print(a)

操作excel函数:operation_excel.py

  1. import os

  2. import xlrd

  3. class OperationExcel:

  4. def __init__(self, file_name=None, sheet_id=None):

  5. if file_name:

  6. self.file_name = file_name

  7. self.sheet_id = sheet_id

  8. self.data = self.get_data()

  9. else:

  10. self.file_name = os.path.abspath(os.path.join(os.getcwd(), "..")) + "\data\PartsPurchase.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. # 写入excel数据

  26. def write_value(self, row, col, value):

  27. read_data = xlrd.open_workbook(self.file_name)

  28. write_data = copy(read_data)

  29. sheet_data = write_data.get_sheet(0)

  30. sheet_data.write(row, col, value)

  31. write_data.save(self.file_name)

  32. # 根据对应的caseid 找到对应行的内容

  33. def get_rows_data(self, case_id):

  34. row_num = self.get_row_num(case_id)

  35. rows_data = self.get_row_values(row_num)

  36. return rows_data

  37. # 根据对应的caseid 找到对应的行号``````````````````

  38. def get_row_num(self, case_id):

  39. num = 0

  40. clols_data = self.get_cols_data()

  41. for col_data in clols_data:

  42. if case_id in col_data:

  43. return num

  44. num = num + 1

  45. # 根据对应行号,找到该行的内容

  46. def get_row_values(self, row):

  47. tables = self.data

  48. row_data = tables.row_values(row)

  49. return row_data

  50. # 根据某一个获取某一列的内容

  51. def get_cols_data(self, col_id=None):

  52. if col_id != None:

  53. cols = self.data.col_values(col_id)

  54. else:

  55. cols = self.data.col_values(0)

  56. return cols

  57. if __name__ == '__main__':

  58. filename = os.path.abspath(os.path.join(os.getcwd(), "..")) + "\data\PartsPurchase.xls"

  59. opers = OperationExcel(file_name=filename, sheet_id=0)

  60. print(opers.get_cell_value(1, 1))

封装获取数据函数get_data.py

  1. from handle_data import data_config

  2. from handle_data.operation_excel import OperationExcel

  3. from util.operation_json import OperationJson

  4. class GetData:

  5. opera_excel = None

  6. def __init__(self, filename, sheetid):

  7. self.opera_excel = OperationExcel(

  8. file_name=filename, sheet_id=sheetid)

  9. # def __init__(self):

  10. # self.opera_excel = OperationExcel(

  11. # file_name=os.path.abspath(os.path.join(os.getcwd(), "..")) + "\data\PartsPurchase.xls", sheet_id=0)

  12. # 获取excel行数,就是case的个数

  13. def get_case_lines(self):

  14. return self.opera_excel.get_lines()

  15. # 是否执行

  16. def get_is_run(self, row):

  17. flag = None

  18. col = int(data_config.get_run())

  19. run_model = self.opera_excel.get_cell_value(row, col)

  20. if run_model == 'yes':

  21. flag = True

  22. else:

  23. flag = False

  24. return flag

  25. # 是否携带header

  26. def is_header(self, row):

  27. col = int(data_config.get_header())

  28. header = self.opera_excel.get_cell_value(row, col)

  29. return header

  30. # def header1(self, row):

  31. # col = int(data_config.get_header())

  32. # header = self.opera_excel.get_cell_value(row, col)

  33. # header = data_config.get_header_value()

  34. # return header

  35. # def headervalue(self, row):

  36. # col = int(data_config.get_header())

  37. # header = self.opera_excel.get_cell_value(row, col)

  38. # header = data_config.get_aut_value()

  39. # return header

  40. # return header, data_config.get_header_value()

  41. # def is_header(self,row):

  42. # header = data_config.get_header_value()

  43. # return header

  44. # if header != '':

  45. # return header

  46. # else:

  47. # return None

  48. # 获取请求方式

  49. def get_request_method(self, row):

  50. col = int(data_config.get_request_way())

  51. request_method = self.opera_excel.get_cell_value(row, col)

  52. return request_method

  53. # 获取url

  54. def get_request_url(self, row):

  55. col = int(data_config.get_url())

  56. url = self.opera_excel.get_cell_value(row, col)

  57. return url

  58. # 获取请求数据

  59. def get_request_data(self, row):

  60. col = int(data_config.get_data())

  61. data = self.opera_excel.get_cell_value(row, col)

  62. if data == '':

  63. return None

  64. return data

  65. # 通过获取关键字拿到 searchjson data数据

  66. def get_data_for_json(self, row):

  67. # opera_json = OperationJson() # 源代码

  68. # request_data = opera_json.get_data(self.get_request_data(row))

  69. opera_json = OperationJson(self.get_request_data(row))

  70. request_data = opera_json.get_data_json()

  71. if request_data == '':

  72. return None

  73. return request_data

  74. # 获取预期结果

  75. def get_expect_data(self, row):

  76. col = int(data_config.get_expect())

  77. expect = self.opera_excel.get_cell_value(row, col)

  78. if expect == '':

  79. return None

  80. return expect

  81. def write_result(self, row, value):

  82. col = int(data_config.get_result())

  83. self.opera_excel.write_value(row, col, value)

  84. # 判断是否有case依赖

  85. def is_depend(self, row):

  86. col = int(data_config.get_case_dependid())

  87. depend_case_id = self.opera_excel.get_cell_value(row, col)

  88. if depend_case_id == "":

  89. return None

  90. else:

  91. return depend_case_id

  92. # 获取依赖数据的key

  93. def get_depend_key(self, row):

  94. col = int(data_config.get_data_depend())

  95. depend_key = self.opera_excel.get_cell_value(row, col)

  96. if depend_key == "":

  97. return None

  98. else:

  99. return depend_key

  100. # 获取数据依赖字段

  101. def get_depend_field(self, row):

  102. col = int(data_config.get_field_depend())

  103. data = self.opera_excel.get_cell_value(row, col)

  104. if data == "":

  105. return None

  106. else:

  107. return data

有依赖case的处理逻辑:dependent_data.py

  1. from common.send_requests import send_requests

  2. from util.read_yaml import do_yaml

  3. class DependentDataclass:

  4. # 通过依赖的caseid找到所在行row, 把行传进去之后可以获取依赖接口的响应结果

  5. def __init__(self, data):

  6. self.data = data

  7. self.opera_excel = data.opera_excel

  8. def DependentData(self, depend_case, header_token):

  9. print("此接口依赖:" + depend_case)

  10. # 通过caseid获取所在的行号,找到该行所对应的值

  11. depend_row = self.opera_excel.get_row_num(depend_case)

  12. url_data = '\configs\url_data.yaml'

  13. url1 = self.data.get_request_url(depend_row)

  14. url = do_yaml.read_yaml(url_data)["baseurl"] + url1

  15. # print(url)

  16. method = self.data.get_request_method(depend_row)

  17. request_data = self.data.get_data_for_json(depend_row)

  18. header = self.data.is_header(depend_row)

  19. # 获取该行是否依赖

  20. depend_case = self.data.is_depend(depend_row)

  21. # 判断依赖行的case中是否也依赖另外的caseID

  22. if depend_case != None:

  23. print("依赖的caseid也依赖其他的接口!暂未写")

  24. else:

  25. print("该case不依赖其他接口!独立执行!")

  26. # 判断依赖行的case中header的取值

  27. if header == "yes":

  28. header = header_token

  29. # print("1header:" + str(header))

  30. depend_response_data = send_requests(method=method, url=url, data=request_data, header=header)

  31. else:

  32. depend_response_data = send_requests(method=method, url=url, data=request_data)

  33. return depend_response_data

域名配置url_data.yaml

下面的地址是项目中的地址,外网可以访问,所以我不能透露,抱歉哦,嘻嘻嘻

  1. #预发布环境

  2. #预发布环境测试地址

  3. baseurl: http://yufabu****************

  4. subject: "这是系统预发布环境的接口测试报告"

  5. ##练习环境

  6. ##练习环境地址

  7. #baseurl: http://lianxi****************

  8. #subject: "这是系统练习环境的接口测试报告"

登录参数:login_data.yaml

  1. # 登录参数

  2. test_login:

  3. header:

  4. "Content-Type": "application/json"

  5. login_data:

  6. "username": "admin"

  7. "password": "123456"

  8. "expected": "登录成功"

单例对象:MyClass.py

  1. # 单例对象

  2. import time

  3. from configs.Singleton import Singleton

  4. @Singleton

  5. class MyClass(object):

  6. # 请求头

  7. header_token = None

  8. # 创建字典,用于存储每个已执行接口的返回对象

  9. dict = {}

  10. def __init__(self):

  11. time.sleep(1)

  12. if __name__ == "__main__":

  13. cls1 = MyClass()

  14. cls2 = MyClass()

  15. print(id(cls1) == id(cls2)) # True

  16. print(id(cls1))

  17. print(id(cls2))

单例类装饰器:Singleton.py

  1. import threading

  2. # 双重检查加锁单例类装饰器

  3. class Singleton(object):

  4. _instance_lock = threading.Lock()

  5. def __init__(self, cls):

  6. self._cls = cls

  7. self.uniqueInstance = None

  8. def __call__(self):

  9. if self.uniqueInstance is None:

  10. with self._instance_lock:

  11. if self.uniqueInstance is None:

  12. self.uniqueInstance = self._cls()

  13. return self.uniqueInstance

'

运行

运行

报告的配置conftest.py

  1. from datetime import datetime

  2. from py.xml import html

  3. import pytest

  4. from util.read_yaml import do_yaml

  5. @pytest.mark.optionalhook

  6. def pytest_html_results_summary(prefix, summary, postfix):

  7. prefix.extend([html.p("测试人: wangxiaoyu")])

  8. @pytest.mark.parametrize

  9. def pytest_configure(config):

  10. url_data = '\configs\url_data.yaml'

  11. report_url = do_yaml.read_yaml(url_data)["baseurl"]

  12. report_subject = do_yaml.read_yaml(url_data)["subject"]

  13. # config._metadata.pop("JAVA_HOME") # 删除java_home

  14. config._metadata["项目名称"] = report_subject # 添加项目名称

  15. config._metadata["接口地址"] = report_url # 添加接口地址

  16. @pytest.mark.optionalhook

  17. def pytest_html_results_table_header(cells):

  18. cells.insert(2, html.th("Description")) # 表头添加Description

  19. cells.insert(3, html.th("Time", class_="sortable time", col="time"))

  20. cells.pop(-1) # 删除link

  21. @pytest.mark.optionalhook

  22. def pytest_html_results_table_row(report, cells):

  23. cells.insert(2, html.td(report.description)) # 表头对应的内容

  24. cells.insert(3, html.td(datetime.now(), class_="col-time"))

  25. cells.pop(-1) # 删除link

  26. @pytest.mark.hookwrapper

  27. def pytest_runtest_makereport(item, call): # Description取值为用例说明__doc__

  28. outcome = yield

  29. report = outcome.get_result()

  30. report.description = str(item.function.__doc__)

  31. # report.nodeid = report.nodeid.encode("utf-8").decode("unicode_escape")

  32. report.nodeid = report.nodeid.encode("unicode_escape").decode("utf-8")

发送电子邮件的配置send_email.py

  1. import smtplib,os

  2. from email.mime.text import MIMEText

  3. from util.read_yaml import do_yaml

  4. cwd_path = os.getcwd()

  5. result_path = os.path.join(cwd_path, "report")

  6. report_path = os.path.join(result_path, "report.html")

  7. # print(report_path)

  8. def send_mail():

  9. '''发送测试报告邮件'''

  10. smtps_server = "smtp.qq.com"

  11. port = 465

  12. sender = "*******@qq.com" # 涉及隐私

  13. psw = "**w********beaa" # 涉及隐私

  14. receiver = ["*******@qq.com"] # 涉及隐私

  15. f = open(report_path, 'rb')

  16. mail_body = f.read().decode('gbk')

  17. f.close()

  18. url_data = '\configs\url_data.yaml'

  19. report_subject = do_yaml.read_yaml(url_data)["subject"]

  20. subject = report_subject

  21. msg = MIMEText(mail_body, 'html', 'utf8')

  22. msg['from'] = sender

  23. msg['to'] = ",".join(receiver)

  24. msg['subject'] = subject

  25. server = smtplib.SMTP_SSL(smtps_server, port)

  26. server.connect(smtps_server, port)

  27. server.login(sender, psw)

  28. server.sendmail(sender, receiver, msg.as_string())

  29. server.quit()

  30. print("测试邮件发送成功")

  31. if __name__ == '__main__':

  32. send_mail()

测试用例test_PartsPurchaseByexcel.py

  1. import ast

  2. import json

  3. import os

  4. import pytest

  5. import pytest_html

  6. from common.logger import decorate_log

  7. from common.send_requests import send_requests

  8. from configs.MyClass import MyClass

  9. from handle_data.data_config import get_header_value

  10. from handle_data.dependent_data import DependentDataclass

  11. from handle_data.get_data import GetData

  12. from util.read_yaml import do_yaml

  13. '''通过调用excel中的数据测试散件入库'''

  14. class test_PartsPurchaseByexcel:

  15. def __init__(self, header_token, file_name, sheet_id):

  16. self.header_token = header_token

  17. self.data = GetData(file_name, sheet_id)

  18. self.DependentDataclass = DependentDataclass(self.data)

  19. def sparePartsPurchaseByexcel(self):

  20. # data = GetData()

  21. rows_count = self.data.get_case_lines()

  22. for i in range(1, rows_count):

  23. is_run = self.data.get_is_run(i)

  24. if is_run:

  25. # print("用例执行!")

  26. # 获取该行的URL

  27. # url = self.data.get_request_url(i)

  28. url_data = '\configs\url_data.yaml'

  29. url1 = self.data.get_request_url(i)

  30. url = do_yaml.read_yaml(url_data)["baseurl"] + url1

  31. # 获取该行的请求方式

  32. method = self.data.get_request_method(i)

  33. # 获取该行的请求数据,json格式

  34. request_data = self.data.get_data_for_json(i)

  35. # 获取该行预期结果

  36. expect = self.data.get_expect_data(i)

  37. # 获取该行header

  38. header = self.data.is_header(i)

  39. # 获取该行是否依赖

  40. depend_case = self.data.is_depend(i)

  41. # 当前执行接口行的caseid

  42. caseid = self.data.opera_excel.get_cell_value(i, 0)

  43. # 判断依赖的id是否为空

  44. if depend_case != None:

  45. print("依赖caseid不为空,继续!")

  46. request_data_dict = None

  47. # self.depend_data = DependentData(depend_case)

  48. # 判断id对应的返回值字典是否存在,存在则表示之前执行过该接口,不再重复执行

  49. if depend_case in MyClass().dict:

  50. depend_response_data = MyClass().dict[depend_case]

  51. else:

  52. # 通过依赖的caseid找到所在行row,把行传进去之后可以获取依赖接口的响应结果

  53. depend_response_data = self.DependentDataclass.DependentData(depend_case, self.header_token)

  54. MyClass().dict[depend_case] = depend_response_data

  55. # 获取依赖字段

  56. depend_key = self.data.get_depend_field(i) # 假如依赖的是id

  57. depend_keys = depend_key.split(',')

  58. for key in depend_keys:

  59. print("当前依赖的字段:", key)

  60. depend_value = depend_response_data["data"][key] # 得到所依赖接口的id对应的值

  61. request_data_dict = request_data

  62. if depend_value != None and key in request_data_dict:

  63. # 用所依赖接口响应结果中取到的值替换当前接口请求中的依赖字段的值

  64. request_data_dict[key] = depend_value

  65. request_data_str = json.dumps(request_data_dict)

  66. request_data = ast.literal_eval(request_data_str)

  67. # request_data2 = json.dumps({depend_key: depend_value}) # 请求数据=依赖的返回数据

  68. # request_data = json.dumps(request_data2)

  69. if header == "yes":

  70. header = self.header_token

  71. # print("2header:" + str(header))

  72. depend_response_data = send_requests(method=method, url=url, data=request_data, header=header)

  73. MyClass().dict[caseid] = depend_response_data

  74. # return depend_response_data

  75. else:

  76. print("没有header,这是没有header的执行请求,没写没写没写没写!!!!!!")

  77. # return depend_response_data

  78. else:

  79. print("该case不依赖其他接口!独立执行!没写没写没写")

  80. else:

  81. print("用例不执行!")

  82. @decorate_log

  83. def test_sparePartsPurchaseByexcel():

  84. ''' 测试散件入库 '''

  85. cls1: MyClass = MyClass() # 全局参数单例对象初始化

  86. cls1.header_token = get_header_value()

  87. header_token = MyClass().header_token

  88. file_name = os.path.abspath(os.path.join(os.getcwd(), "..")) + "\wxy_test_chelingzhuByExcel\data\PartsPurchase.xls"

  89. print(file_name)

  90. sheet_id = 0

  91. runn = test_PartsPurchaseByexcel(header_token, file_name, sheet_id)

  92. runn.sparePartsPurchaseByexcel()

运行入口run.py

  1. import pytest

  2. import send_email

  3. if __name__ == '__main__':

  4. pytest.main(["-sv", "--html=./report/report.html", "--self-contained-html"])

  5. # pytest.main()

  6. send_email.send_mail()

大功告成

运行之后会给你的QQ邮箱发送测试报告,如下图,虽然丑点但是能看明白!!!

image.png

 

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

 

          视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值