测试平台系列(127) 改造请求参数提取方式(1).md

2022/6/7 测试平台接口测试FastApiPythonReact

大家好~我是米洛
我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的教程,希望大家多多支持。
欢迎关注我的公众号米洛的测开日记,一起交流学习!

# 回顾

上一节我们在测试报告页面增加了重试功能,使得用例调试变得更为方便。

最近因为自己闲的蛋疼在看一些性能测试平台,也感受到了一些不同,虽然人家只是压测工具,但对于接口测试中的一些参数处理,做的还是挺出色的,所以我打算小小地"借鉴"一下。

(由于整体设计不太一致,所以暂时只剥离他用到的那块内容。)

上图就是重点部分啦,图中这个系统(pts即阿里云的性能测试工具)相比较pity而言,他对于上一接口的返回值有着很明确的规划。

它并不提供完整的数据(pity目前会提供response,header,cookie,status_code等一大堆数据,放到一个字典供用户去取值),这点的话,对于每个要用到的数据,他可以剥离出来,用例结构更透明,用到什么数据一目了然,有了类型的区别,也很容易分别出这个变量来自哪里,是response,还是response_header。

当然它定义的变量也是可以给后面的任意接口用的哦,这样就组成了一个出参列表,在必要的输入框还可以选择,提高用户的输入效率,避免用户输入以下这种不可控的取值"函数"(这里先姑且这么称呼):

${response.data.0.field}

所以,有时候不断借鉴,完善自己,也不失为一件坏事嘛。

# 理清楚思路

我们捋一捋pts的思路,当来源为JSON或者header这种K/V(键值对的缩写,即key/value)数据的时候,它采用JSONPath取值。

而当来源为TEXT(文本)的时候,它又支持正则取值,这样就基本能满足我们大部分需求了,因为它还支持索引,比如我正则一下子取出很多值,可以选出其中一个,更是支持random(随机取值)。

总结来说,其实也就分为JSONpath和正则2种,正则还需要多一个索引取值。并不难,熟悉完了以后我们就可以定义参数表了。

# 定义参数表

新建app/models/out_parameters.py

from sqlalchemy import Column, String, INT, UniqueConstraint

from app.models.basic import PityBase


class PityTestCaseOutParameters(PityBase):
    """
    pity用例出参数据,与用例绑定
    """
    __tablename__ = 'pity_out_parameters'
    __table_args__ = (
        UniqueConstraint('case_id', 'name', 'deleted_at'),
    )
    # 用例id
    case_id = Column(INT, nullable=False)
    # 参数名
    name = Column(String(24), nullable=False)
    # 来源类型
    source = Column(INT, nullable=False, default=0,
                    comment="0: Body(TEXT) 1: Body(JSON) 2: Header 3: Cookie 4: HTTP状态码")
    # 表达式
    expression = Column(String(128))
    # 获取结果索引, 可以是random,也可以是all,还可以是数字
    match_index = Column(String(16))

    def __init__(self, name, source, expression, match_index, case_id, user_id):
        super().__init__(user_id)
        self.name = name
        self.case_id = case_id
        self.expression = expression
        self.match_index = match_index
        self.source = source


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

由于需要与case_id绑定,其他的就不需要多说了,都是上图中应该具备的字段:名称,用例id,来源,表达式,索引。

# 编写dao层

这里由于我们封装了一下,所以不需要很复杂即可完成。添加app/crud/test_case/TestCaseOutParametersDao.py,其实我一直觉得这个处理不是很优雅,但现状是可以放一放,毕竟能用,代码量也不多。

from app.crud import Mapper
from app.models.out_parameters import PityTestCaseOutParameters
from app.utils.decorator import dao
from app.utils.logger import Log


@dao(PityTestCaseOutParameters, Log("PityTestCaseOutParametersDao"))
class PityTestCaseOutParametersDao(Mapper):
    pass

1
2
3
4
5
6
7
8
9
10

如果没有特殊的方法,直接继承即可。

# 定义form表单

添加文件app/schema/testcase_out_parameters.py

from pydantic import BaseModel, validator

from app.schema.base import PityModel


class PityTestCaseOutParametersForm(BaseModel):
    id: int = None
    case_id: int = None
    name: str
    expression: str
    match_index: str = None
    source: int

    @validator("expression", "name", "source")
    def name_not_empty(cls, v):
        return PityModel.not_empty(v)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 编写router层

修改app/routers/testcase/testcase.py

由于做了全局异常捕获,所以这把的try/except就省略了,不抛异常即可视为正常了。

注意这儿没有查询接口,那是因为参数都是和用例绑定的,我们到查询用例信息的时候查询数据即可。

# 修改查询用例的接口

# 这里顺便把out_parameters查询出来即可。

这节内容主要给大家展示一个其他优秀平台的设计,下一节我们讲讲怎么编写前端部分,使得我们可以正常录入数据,先来看个预告:

(写前端实在很花时间=。=)

我是米洛,一直陪伴各位学习!免费的小黄心,帮我点一个吧!

项目地址: https://github.com/wuranxu/pity (opens new window)