添加基础配置数据——软件自动化测试入门攻略(4)

发表于:2024-3-07 09:46

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:杨定佳    来源:51Testing软件测试网原创

  11.6.2  添加基础配置数据
  配置文件config.ini是整个接口测试项目的基础数据,也是常用的一些数据,例如host、登录用户名和密码等。在此文件中添加基本的数据,添加的内容如下:
  [base]
  host = http://121.41.112.70
  base_url = %(host)s/index.php
  [login]
  url = /api/leadmall/login
  headers = {"Content-Type": "application/json; charset=UTF-8"}
  body = {"mobile":"18888888888", "password":"xA123456"}
  在此项目中,我们添加了base和login两部分配置内容,base下添加了host和base_url变量,login下添加了url、headers和body变量。其中,%(host)s表示引用host的值。
  本次练习配置文件config.ini和测试用例文件“登录.xlsx”中的mobile和password均是假信息,读者在练习时需要根据搭建的Leadshop项目进行修改。也可直接使用Leadshop体验地址:https://demo.leadshop.vip/index.php,账户和密码可查看Leadshop说明文档:https://gitee.com/leadshop/leadshop。
  其中,ini文件是Initialization File的缩写,即初始化文件,属于配置文件的一种。ini文件由节、键、值组成,节用来区分不同用途的参数区,键就是我们常说的变量,引用键就是获取值。如上配置文件中[login]就是节,url=/api/leadmall/login中url为键,/api/leadmall/login为值。
  11.6.3  读取配置文件内容
  配置文件中添加了一些常用的变量,接下来需要读取这些变量。在Python中可使用configparser模块读取INI文件,我们在common\read_config.py文件中添加读取配置文件的代码,如下所示:
  # chapter11\common\read_config.py
  import os
  from pathlib import Path
  from configparser import ConfigParser
  # 从当前文件开始,查找配置文件 config.ini
  current_file = os.path.realpath(__file__)
  config_path = Path(current_file).parent.parent.joinpath("config.ini")
  config = ConfigParser()
  config.read(config_path, encoding="UTF-8")
  # 常用的变量可直接定义,方便后面直接引用
  base_url = config.get("base", "base_url")
  login = config["login"]
  首先通过os模块读取当前文件的read_config.py的路径,再通过Path类提供的一些方法从当前文件中找到配置文件config.ini。然后实例化一个config=ConfigParser()对象,接着读取INI文件,最后通过get(section, option)或config[section][option]方式读取变量。对于一些使用频率比较高的变量可直接读取出来定义成变量,例如base_url,login节,由于login节下的url、headers、body基本都是同时使用,因此只需要读到login节即可,使用时再通过login["url"]、login["headers"]和login["body"]的方式读取。
  下面对添加的代码进行测试,在common\read_config.py文件中添加打印base_url、login["url"]、login["headers"]和login["body"]代码,如下所示:
  if __name__ == '__main__':
      print(base_url)
      print(login["url"], login["headers"], login["body"], sep="\n")
  执行脚本common\read_config.py,控制台输出的内容如下:
  http://121.41.112.70/index.php
  /api/leadmall/login
  {"Content-Type": "application/json; charset=UTF-8"}
  {"mobile":"18888888888", "password":"xA123456"}
  可以看到,输出内容正是配置文件中的base_url、login["url"]、login["headers"]和login["body"]值。
  11.6.4  获取测试用例数据
  获取测试用例数据就是读取case下Excel文件中的测试用例数据,并将其返回。在core\get_case.py文件中添加读取测试用例数据函数,如下所示:
  # chapter11\core\get_case.py
  import os
  import glob
  from pathlib import Path
  import pandas as pd
  # 设置 pandas 展示的最大列数
  pd.options.display.max_columns = 20
  def get_case_file(file_path):
      """读取固定目录下所有的Excel文件"""
      # 匹配 xlsx、xls、xlsm测试文件
      if os.path.exists(file_path):
          return glob.glob(f"{file_path}/*.xls*")
      else:
          print(f"路径 {file_path} 不存在")
          return []
  def get_sheet_names(file):
      """读取某个Excel文件中所有的Sheet名称"""
      try:
          xlsx = pd.ExcelFile(file)
          return xlsx.sheet_names
      except Exception as e:
          print(f"打开文件 {file} 失败")
          return []
  def get_sheet_case(file, sheet):
      """获取Excel中单个Sheet表格中的测试用例数据"""
      df = pd.read_excel(file, sheet_name=sheet, keep_default_na=False)
      # "是否执行","用例编号", "用例名称", "接口地址", "请求方式"列有空值就去除所在用例
      df.dropna(axis=0, how='any', subset=["是否执行", "用例编号", "用例名称", "接口地址", 
  "请求方式"], inplace=True)
      # 只保留 "是否执行"="是" 的数据行
      df = df.loc[df[(df.是否执行 == "是")].index.tolist(), :]
      # 只保留列"用例编号", "用例名称", "接口地址", "请求方式", "请求头", "请求参数", 
  "预期结果类型", "预期值"
      df = df[["用例编号", "用例名称", "接口地址", "请求方式", "请求头", "请求参数", 
  "预期结果类型", "预期结果"]]
      return df
  def get_case(path):
      """依次读取所有Excel下所有Sheet表格中的测试用例数据"""
      files = get_case_file(path)
      for file in files:
          sheets = get_sheet_names(file)
          for sheet in sheets:
              yield get_sheet_case(file, sheet)
  current_file = os.path.realpath(__file__)
  def get_login_case():
      """获取登录测试用例数据"""
      login_case_path = Path(current_file).parent.parent.joinpath("case", "login_case")
      return get_case(login_case_path)
  def get_change_pwd_case():
      """获取修改密码测试用例数据"""
      login_case_path = Path(current_file).parent.parent.joinpath("case", "change_pwd_case")
      return get_case(login_case_path)
  def get_all_case():
      """获取case目录下所有的Excel文件中测试用例,不包含子孙目录下的测试用例"""
      case_path = Path(current_file).parent.parent.joinpath("case")
      return get_case(case_path)
  在此文件中,我们定义了get_case_file、get_sheet_names、get_sheet_case、get_case、get_login_case、get_change_pwd_case和get_all_case共7个函数。get_case_file是在指定的目录下查找所有的Excel文件,但不包括子孙目录下的Excel文件;get_sheet_names是读取一个Excel文件中所有的Sheet表格名称;get_sheet_case是读取一个Excel文件中指定Sheet表格下所有的测试用例数据,剔除不符合规则和不执行的数据,且只保留用例编号、用例名称、接口地址、请求方式、请求头、请求参数、预期结果类型、预期值8列数据并返回;get_case是依次读取所有Excel文件下所有Sheet表格中的测试用例数据,其中调用了get_case_file、get_sheet_names和get_sheet_case函数;最后的三个函数get_login_case、get_change_pwd_case和get_all_case分别是指定登录测试用例路径case/login_case并返回测试用例数据、指定修改密码测试用例路径case/change_pwd_case并返回测试用例数据和指定所有测试用例路径case并返回测试用例数据。
  下面对添加的代码进行测试。在core\get_case.py文件中添加打印所有测试用例数据的代码,如下所示:
  if __name__ == '__main__':
      from tabulate import tabulate
      df_list = list(get_all_case())
      df = pd.concat(df_list)  # 合并 df
      print(tabulate(df, headers="keys", tablefmt="psql"))
  pd.concat(df_list)语句可以将多个DataFrame结构数据合并成一个。代码中,使用到了tabulate模块,它是Python的一个第三方库,可以让表格数据更优雅美观地展示。
  执行脚本core\get_case.py,控制台输出的内容如图11-4所示,从图中可以看到,打印出了case\Admin管理员.xlsx文件中所有Sheet的测试用例数据。
图11-4  Admin管理员.xlsx测试用例数据
  11.6.5  封装接口请求函数
  在core\send_request.py文件中添加发送请求函数,此文件主要是借助Requests模块封装两个我们项目中可以用到的接口请求函数,代码如下:
  # chapter11\core\send_request.py
  import requests
  from common.read_config import login as login_conf, base_url
  def headers_format(headers):
      """对请求头进行处理"""
      if headers:
          headers = eval(headers)
      else:
          headers = {}
      return headers
  def send(method, url, headers=None, body=None, session=requests):
      """发送请求"""
      headers = headers_format(headers)
      params = {"q": url}
      return session.request(method=method, url=base_url, params=params, 
  headers=headers, data=body)
  def set_session(data=login_conf["body"]):
      """开启会话,添加认证信息"""
      session = requests.session()
      try:
          params = {"q": login_conf['url']}
  response = session.post(url=base_url, params=params, headers=eval(login_conf["headers"]),
  data=data)
          if response.status_code == 200:
              bearer = response.json().get("access_token")
              session.headers.update({"Authorization": "Bearer " + bearer})
              return session
          else:
              print(f"获取 Bearer Token 失败, 返回状态码是:{response.status_code}")
      except requests.exceptions.RequestException as e:
          print("登录失败:", e)
  core/send_request.py文件下共有headers_format、send、set_session三个函数。headers_format是格式化请求头,从Excel文件中读到的请求头数据格式是字符串,我们需要转换成字典格式;send函数是发送请求,并返回响应结果。session参数可决定是直接发送请求还是带认证信息发送请求,即未登录下请求还是用户登录后请求;set_session函数是设置认证信息,即保持用户登录会话,LeadShop项目用户接口请求是通过Bearer身份验证方法让服务器识别到用户信息。当用户登录后会返回一个access_token字段,即Bearer token,因此使用bearer = response.json().get("access_token")代码获取access_token的值,然后使用session.headers.update({"Authorization": "Bearer " + bearer})代码在请求头中添加Bearer身份验证信息,这样,再使用session发送接口请求时就携带了用户认证。
查看《软件自动化测试入门攻略》全部连载章节
版权声明:51Testing软件测试网获得作者授权连载本书部分章节。
任何个人或单位未获得明确的书面许可,不得对本文内容复制、转载或进行镜像,否则将追究法律责
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号