接口自动化框架搭建

目录

 一、场景分析

二、具体分析

1.工具类utils

2.测试数据data

3.脚本scripts

 4.测试报告report 

5.日志log


接口自动化框架:pytest + yaml + pymysql + requests + allure + logging 

接口自动化框架中,对于每个框架/库 概念及使用 简单总结在了另一篇:http://t.csdnimg.cn/TjFLg

 一、场景分析

对于一个自动化框架的搭建,首先我们得清楚该框架要实现什么?

现在有一个场景:请求某系统的登录页面,自动输入账号密码,并点击登录进入首页                   对于这样一个场景,我想要实现的有以下几点:

目录【实现方法】:

  1. 脚本 scripts --- 测试登陆页面 【requests】
  2. 日志 log --- 程序运行日志【logging】
  3. 测试报告 report --- 【pytest 插件/allure】

实现自动化的一个核心思想就是,数据分离。也就是测试数据以参数的形式传递给测试脚本,而不是直接写道测试脚本中。

那么,我们就还需要一个 data目录 --- 【yaml】存放测试数据,于是,问题又来了,怎么读这个数据呢?所以需要封装一个使测试脚本读取数据的类,既然把它作为工具使用,把它称为工具类。所以,现在还需要一个 utils目录 来存放工具类。

二、具体分析

1.工具类utils

仔细分析一下,我们还有哪些需要的工具类:

  • 文件路径:传递参数的时候直接写文件名就好,不用自己找路径

import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

# 定义yaml_file方法
def yaml_file(yaml_name):
    yaml_dir = os.path.join(BASE_DIR, "data")
    yaml_f = os.path.join(yaml_dir, yaml_name)
    return yaml_f

# 封装日志路径
LOGER_DIR = os.path.join(BASE_DIR, "logs")
INFO_FILE = os.path.join(LOGER_DIR, "info_logs")
ERROR_FILE = os.path.join(LOGER_DIR, "error_logs")

# 封装allure路径
REPORT_DIR = os.path.join(BASE_DIR, "report")
REPORT_JSON = os.path.join(REPORT_DIR, "allure_json")
REPORT_HTML = os.path.join(REPORT_DIR, "allure_html")
print(REPORT_JSON)
print(REPORT_HTML)

# 封装case路径
CASE_FILE = os.path.join(BASE_DIR, "testcase")
print(CASE_FILE)

  • 读取yaml文件:从指定的YAML文件中读取数据,并返回给测试脚本指定节点名称下的数据值列表。
import yaml

class YamlUtils:
    @staticmethod
    def read_yaml(yaml_path, node_name):
        with open(yaml_path, 'r', encoding='utf-8') as file:
            datas = yaml.safe_load(file)
            login_dict = datas[node_name]
            print(login_dict)
            return list(login_dict.values())
  •  日志记录器:生成日志需要导入python的标准日志模块实现
# 日志:记录正确/错误的接口信息
import logging

from utils.path_utils import INFO_FILE, ERROR_FILE

def get_logger():
    # 初始化日志记录器,设置日志记录器的级别
    logger = logging.getLogger()
    logger.setLevel("DEBUG")
    # 创建流处理器
    ls = logging.StreamHandler()
    ls.setLevel("INFO")

    # 创建并配置文件处理器,用于记录INFO级别的日志(文件名,追加模式,编码格式)
    lf_info = logging.FileHandler(filename=INFO_FILE, mode='a', encoding="utf-8")
    lf_info.setLevel('INFO')

    # 创建并配置文件处理器,用于记录ERROR级别的日志(文件名,追加模式,编码格式)
    lf_er = logging.FileHandler(filename=ERROR_FILE, mode="a", encoding="utf-8")
    lf_er.setLevel("ERROR")

    # 创建并配置文件处理器,用于记录ERROR级别的日志(文件名,追加模式,编码格式)
    fmat = "%(asctime)s - [%(filename)s - %(lineno)d] - %(levelname)s : %(message)s"
    my_fmat = logging.Formatter(fmat)

    # 给处理器添加格式器
    logger.addHandler(ls)
    logger.addHandler(lf_info)
    logger.addHandler(lf_er)

    # 给日志器添加处理器
    ls.setFormatter(my_fmat)
    lf_er.setFormatter(my_fmat)
    lf_info.setFormatter(my_fmat)

    return logger

logger = get_logger()

2.测试数据data

注意yaml的格式规范就好啦~

case_login:
  case_001: # 测试用户正常登陆场景
    username: "admin"
    password: "123456"
    code: "6"
    exp: "操作成功"
  case_002: # 测试用户不存在的场景
    username: "admin1"
    password: "123456"
    code: "6"
    exp: "登录用户:admin1 不存在"
  case_003: # 测试用户密码错误的场景
    username: "admin"
    password: "1234567"
    code: "6"
    exp: "用户不存在/密码错误"
  case_004: # 测试验证码的场景
    username: "admin"
    password: "123456"
    code: "7"
    exp: "验证码错误"

#这里的验证码统一设置为6

3.脚本scripts

对于大多数的登录都有包含验证码,该场景为图片验证码。但不管是哪种类型的验证码,都需要先请求验证码,获得验证码的唯一标识符,传递给后续的登陆操作。

from utils.path_utils import yaml_file
from utils.yaml_utils import YamlUtils


def get_uuid():
    # 发送 HTTP GET 请求,获取验证码图片标识符
    captchaimage = requests.get(url='http://192.168.9.131/api/captchaImage')
    # 解析http响应的json数据
    res_uuid = captchaimage.json()
    # 从json数据中获取uuid
    uuid = res_uuid['uuid']
    return uuid

class TestUserLogin:
    # 使用 parametrize 装饰器,定义参数化测试用例。
    # 从 YAML 文件中读取登录测试用例数据,以字典的形式传入测试方法中。
    @pytest.mark.parametrize("user_info",
                             YamlUtils.read_yaml(yaml_file("wms_login_data.yaml"),
                                                 "case_login"))
    def test_login(self, user_info):
        info_msg = {"username": user_info["username"],
                    "password": user_info["password"],
                    "code": user_info["code"],
                    "uuid": get_uuid()}
        
        # 请求登陆页面
        response = requests.post(url="http://192.168.9.131/api/login", json=info_msg)
        res = response.json()
        # 打印响应结果
        print(res)

       

 4.测试报告report 

使用allure生成测试报告,其实就是装饰器的使用。在上面脚本的基础上添加装饰器:

#  使用 allure 库的 feature 装饰器,定义测试用例所属的特性
@allure.feature("wms仓管系统-登陆接口")
class TestUserLogin:
    # 使用 allure 库的 description 装饰器,定义测试用例的描述。
    @allure.description("接口测试case")
    # 使用 allure 库的 severity 装饰器,定义测试用例的严重性级别。
    @allure.severity("Critical")

 测试报告:

5.日志log

 可以在判断结果的时候,根据不同结果打印不同日志信息,因为日志本身就是用来记录程序执行信息,帮助我们定位错误来源。

        if res["msg"] == user_info["exp"]:
            logger.info("接口响应符合预期,用例执行成功,请求参数是:%s", info_msg)
        else:
            logger.error("用例执行失败:直接结果是:%s", res)
            raise AssertionError("响应结果不在预期结果内!")

【补充】工具类:数据库连接

当我们的请求需要访问数据库时,可直接调用该类及方法,不需要重复书写冗余代码。【该场景中未使用】

import pymysql


class DB_utils:

    # 初始化方法  封装连接和游标
    def __init__(self):
        try:
            self.conn = pymysql.connect(host="192.168.9.131",
                                        port=80,
                                        user="root",
                                        passwd="root",
                                        db="wms")
            self.cursor = self.conn.cursor()
            print("数据连接成功!")
        except Exception as error:
            print("数据库连接失败!")
            raise error

    # 关闭连接和游标
    def close(self):
        self.cursor.close()
        self.conn.close()

 

 

  • 14
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值