【接口测试】5_项目实战 _iHRM登录接口参数化

文章目录

  • 一、框架
  • 二、参数化步骤
    • [2.1 api包](#2.1 api包)
      • [2.1.1 ihrm_login_api.py](#2.1.1 ihrm_login_api.py)
    • [2.2 common包](#2.2 common包)
      • [2.2.1 read_json_file.py](#2.2.1 read_json_file.py)
        • [2.2.1.1 相对路径写法](#2.2.1.1 相对路径写法)
        • [2.2.1.2 绝对路径写法](#2.2.1.2 绝对路径写法)
      • [2.2.2 assert_tools.py](#2.2.2 assert_tools.py)
      • [2.2.3 logging_use.py](#2.2.3 logging_use.py)
    • [2.3 data文件夹](#2.3 data文件夹)
      • [2.3.1 login_data.json](#2.3.1 login_data.json)
    • [2.4 report文件夹](#2.4 report文件夹)
    • [2.5 scripts包](#2.5 scripts包)
      • [2.5.1 test_ihrm_login_params.py](#2.5.1 test_ihrm_login_params.py)
    • [2.6 config.py](#2.6 config.py)
    • [2.7 pytest.ini](#2.7 pytest.ini)

一、框架

1、api/:接口对象层(代码:python package)

  • ① __ init__.py 无内容
  • ②ihrm_login_api.py

2、common/:通用工具方法、函数(代码:python package)

  • ① __ init__.py 无内容
  • ②read_json_file.py
  • ③assert_tools.py
  • ④logging_use.py

3、data/:测试数据文件(文件:dir)

  • login_data.json

4、report/:测试报告(文件:dir)

5、scripts/:测试脚本层(代码:python package)

  • ① __ init__.py 无内容
  • ② test_ihrm_login_params.py

6、config.py: 项目中的 配置信息。(全局变量)

7、pytest.ini: pytest 配置

二、参数化步骤

  1. 将 测试数据,按 [{},{},{}] 格式 组织到 json文件中。
  2. 读取 json文件,将数据转换为 [(),(),()]
  3. 在通用测试方法上一行,添加 @pytest.mark.parameterize()
  4. 给 parameterize() 传参。参1:字符串类型,内容为 json文件中一组数据的 key。参2:[(),(),()]格式数据。
  5. 给 通用测试方法添加形参,与 parameterize() 参1 字符串的内容一致。
  6. 修改 通用测试方法 内部实现,使用形参。

2.1 api包

2.1.1 ihrm_login_api.py

python 复制代码
"""
ihrm 登录接口 对象层
"""
import requests


# 定义 ihrm 登录接口 类
class IhrmLoginApi(object):
    # 定义方法
    @classmethod
    def login(cls, req_data):
        resp = requests.post(url="http://ihrm-test.itheima.net/api/sys/login", json=req_data)
        return resp


# 测试 接口封装是否成功
if __name__ == '__main__':
    # 准备请求体数据
    data = {"mobile": "13800000002", "password": "123456"}
    resp = IhrmLoginApi.login(data)
    print("登录成功:", resp.json())

2.2 common包

2.2.1 read_json_file.py

2.2.1.1 相对路径写法
  1. 在 common/ 下创建 文件 read_json_file.py
  2. 在 文件内,创建 函数,读取json文件中的数据,转换成 [(),(),()] 格式数据
  3. 测试此函数功能通过
python 复制代码
import json

# 定义工具函数,读取json文件中的数据,转换成 [(),(),()] 格式数据
def read_json_data(filename):
    with open(filename, "r", encoding="utf8") as f:
        json_data = json.load(f)
        login_list = []
        for data in json_data:
            tmp = tuple(data.values())
            login_list.append(tmp)

        return login_list

if __name__ == '__main__':
    res = read_json_data("../data/login_data.json")   # 相对路径写法
    print(res)
  1. 建议读取 json文件时,使用 绝对路径法传入文件名
    1. config.py 中,添加 全局变量,获取 项目目录 BASE_DIR = os.path.dirname(__file__)
    2. 拼接 json文件的绝对路径 filename = BASE_DIR+"/data/login_data.json"
    3. 使用 绝对路径,传入 json文件读取函数。 read_json_data(filename)
2.2.1.2 绝对路径写法

在计算机的存储路径是固定的。

python 复制代码
import json
from config import BASE_DIR


# 定义工具函数,读取json文件中的数据,转换成 [(),(),()] 格式数据
def read_json_data(filename):
    with open(filename, "r", encoding="utf8") as f:
        json_data = json.load(f)
        login_list = []
        for data in json_data:
            tmp = tuple(data.values())
            login_list.append(tmp)

        return login_list


if __name__ == '__main__':
    # res = read_json_data("../data/login_data.json")
    filename = BASE_DIR + "/data/login_data.json"       # 绝对路径写法
    res = read_json_data(filename)
    print(res)

2.2.2 assert_tools.py

python 复制代码
"""
定义 通用的 工具函数,实现断言
"""
def common_assert(resp, status_code, success, code, message):
    assert status_code == resp.status_code
    assert success is resp.json().get("success")
    assert code == resp.json().get("code")
    assert message in resp.json().get("message")

2.2.3 logging_use.py

  1. 将 loggin_use.py 文件部署到项目中。 如:拷贝至 common/ 下。

  2. 在 项目下 创建 log/ 用来存放生成的 xxx.log 日志文件

  3. 在 项目中,使用日志之前,初始化日志信息,指定 日志文件名【必填】、单位、单位间隔、保留文件个数。

  4. 在 需要打印输出的位置,使用 logging.级别("想要输出的信息")

python 复制代码
import logging.handlers
import logging
from config import BASE_DIR


def init_log_config(filename, when='midnight', interval=1, backup_count=7):
    """
    功能:初始化日志配置函数
    :param filename: 日志文件名
    :param when: 设定日志切分的间隔时间单位
    :param interval: 间隔时间单位的个数,指等待多少个 when 后继续进行日志记录
    :param backup_count: 保留日志文件的个数
    :return:
    """
    # 1. 创建日志器对象
    logger = logging.getLogger()

    # 2. 设置日志打印级别
    logger.setLevel(logging.DEBUG)
    # logging.DEBUG 调试级别
    # logging.INFO 信息级别
    # logging.WARNING 警告级别
    # logging.ERROR 错误级别
    # logging.CRITICAL 严重错误级别

    # 3. 创建处理器对象
    # 控制台对象
    st = logging.StreamHandler()
    # 日志文件对象
    fh = logging.handlers.TimedRotatingFileHandler(filename,
                                                   when=when,
                                                   interval=interval,
                                                   backupCount=backup_count,
                                                   encoding='utf-8')

    # 4. 日志信息格式
    fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"
    formatter = logging.Formatter(fmt)

    # 5. 给处理器设置日志信息格式
    st.setFormatter(formatter)
    fh.setFormatter(formatter)

    # 6. 给日志器添加处理器
    logger.addHandler(st)
    logger.addHandler(fh)


if __name__ == '__main__':
    # 初始化日志
    init_log_config(BASE_DIR + '/log/sh27.log', interval=3, backup_count=5)

    # 打印输出日志信息
    logging.debug('我是一个调试级别的日志')
    logging.info("AAA BBB CCC")
    logging.error("xxxx 错误。。")

2.3 data文件夹

2.3.1 login_data.json

总共15条测试案例,但是本案例数据只有7条,仅做演示,后续可以补充全部。

json 复制代码
[
  {
    "desc": "登录成功",
    "req_data": {
      "mobile": "13800000002",
      "password": "123456"
    },
    "status_code": 200,
    "success": true,
    "code": 10000,
    "message": "操作成功"
  },
  {
    "desc": "手机号不存在",
    "req_data": {
      "mobile": "13874893701",
      "password": "123456"
    },
    "status_code": 200,
    "success": false,
    "code": 20001,
    "message": "用户名或密码错误"
  },
  {
    "desc": "密码错误",
    "req_data": {
      "mobile": "13800000002",
      "password": "123456890"
    },
    "status_code": 200,
    "success": false,
    "code": 20001,
    "message": "用户名或密码错误"
  },
  {
    "desc": "手机号为空",
    "req_data": {
      "mobile": null,
      "password": "123456"
    },
    "status_code": 200,
    "success": false,
    "code": 20001,
    "message": "用户名或密码错误"
  },
  {
    "desc": "多参",
    "req_data": {
      "mobile": "13800000002",
      "password": "123456",
      "abc": "123"
    },
    "status_code": 200,
    "success": true,
    "code": 10000,
    "message": "操作成功"
  },
  {
    "desc": "少参",
    "req_data": {
      "mobile": "13800000002"
    },
    "status_code": 200,
    "success": false,
    "code": 20001,
    "message": "用户名或密码错误"
  },
  {
    "desc": "无参",
    "req_data": null,
    "status_code": 200,
    "success": false,
    "code": 99999,
    "message": "抱歉,系统繁忙,请稍后重试!"
  }
]

2.4 report文件夹

2.5 scripts包

2.5.1 test_ihrm_login_params.py

yacas 复制代码
## parameterize参数化
1. 在 通用测试方法上一行,添加 @pytest.mark.parameterize()
2. 给 parameterize()添加参数。参1:一个字符串,内容为json文件中,一组测试数据的键。参2:[(),(),()]格式数据。
3. 给 通用测试方法,添加形参。参数与 parameterize()的 参1 保持一致。
4. 修改 通用测试方法 内部实现,使用 形参。
  • 定义通用测试方法,测试登录接口。
  • 作参数化,一个接口就一个方法。
python 复制代码
import logging

import pytest
from api.ihrm_login_api import IhrmLoginApi
from common.assert_tools import common_assert
from common.logging_use import init_log_config
from common.read_json_file import read_json_data
from config import BASE_DIR


class TestIhrmLoginParams(object):
    init_log_config(BASE_DIR + '/log/sh27.log', interval=3, backup_count=5)
    # 读取json文件,获取[(),(),()]格式数据
    data = read_json_data(BASE_DIR + "/data/login_data.json")

    @pytest.mark.parametrize("desc, req_data, status_code, success, code, message", data)
    # 定义 通用测试方法 - 测试ihrm登录接口
    def test_ihrm_login(self, desc, req_data, status_code, success, code, message):
        # 调用 自己封装的 api, 获取响应结果
        resp = IhrmLoginApi.login(req_data)
        # 打印查看
        # print(desc, ":", resp.json())
        logging.info(f"{desc} : {resp.json()}")
        # 断言
        common_assert(resp, status_code, success, code, message)

2.6 config.py

python 复制代码
import os

# 定义全局变量,获取项目路径(绝对路径)
BASE_DIR = os.path.dirname(__file__)

2.7 pytest.ini

ini 复制代码
[pytest]
addopts = -s
testpaths = ./scripts
python_files = test*.py
python_classes = TestAdd*Params
python_functions = test*
相关推荐
小笔学长20 小时前
Webpack 配置优化:提高打包速度与质量
前端·项目实战·前端开发·webpack优化·打包性能优化
少云清1 天前
【接口测试】2_项目实战 _接口自动化测试框架
接口测试·项目实战·自动化测试框架
程序员杰哥2 天前
Postman设置接口关联,实现参数化
自动化测试·软件测试·python·测试工具·测试用例·接口测试·postman
少云清2 天前
【接口测试】8_代码实现 _全量字段校验
接口测试·代码实现·全量字段校验
测试架构师北凡3 天前
自动化测试框架入门上手,封装自动化框架,一篇通关...
自动化测试·软件测试·软件测试工程师·python自动化测试·接口自动化测试·接口测试·自动化测试框架
小笔学长4 天前
事件委托:优化事件处理性能
javascript·性能优化·项目实战·前端开发·事件委托
玄同7654 天前
Python 项目实战中“高内聚低耦合”的设计方法 —— 基于七大设计原则与拓展技巧
开发语言·人工智能·python·语言模型·pycharm·设计原则·项目实战
小笔学长5 天前
Mixin 模式:灵活组合对象功能
开发语言·javascript·项目实战·前端开发·mixin模式
小笔学长5 天前
观察者模式:实现对象间的消息传递
javascript·观察者模式·项目实战·前端开发