测试平台系列(18) 项目用例表设计和权限改造

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 项目用例表设计和权限改造

回顾


上一节,我们说到了关于整个用例执行的生命周期。我后面细想了一下,如果一开始就要完全兼容代码生成的话,写起来会很费时间。为了给大家一些好的体验,还是得一口一口地吃,不能一下吃胖。

所以我们就先完成无码模式吧~

粗略地设计几个核心表


我们的用例后续如果要方便管理,肯定是需要做一些分类权限的控制,所以我们先设计几个核心的表:

  • 项目表
    用例分步在各个项目,类似于目录的概念,不同的用例位于不同的项目之中,方便用例进行分类。
  • 项目角色表
    每个项目都是需要有自己的成员,对于成员们来说,他们因为身份的不同,身上担负的职责也不一样,我们给出几个简单的身份如:
    组长和组员,其中组长可以对组员进行相关权限的变化。
  • 测试用例表
    存放了各个用例的信息,是测试平台的一个最小的执行单元。

项目表 models/project.py



from app.models import db
from datetime import datetime
class Project(db.Model):
    id = db.Column(db.INT, primary_key=True)
    name = db.Column(db.String(16), unique=True, index=True)
    owner = db.Column(db.INT)
    created_at = db.Column(db.DATETIME, nullable=False)
    updated_at = db.Column(db.DATETIME, nullable=False)
    deleted_at = db.Column(db.DATETIME)
    create_user = db.Column(db.INT, nullable=True)
    update_user = db.Column(db.INT, nullable=True)
    private = db.Column(db.BOOLEAN, default=False)
    def __init__(self, name, owner, create_user, private=False):
        self.name = name
        self.owner = owner
        self.private = private
        self.created_at = datetime.now()
        self.updated_at = datetime.now()
        self.create_user = create_user
        self.update_user = create_user
        self.deleted_at = None

大概分为以下几个字段,除了创建/更新时间/用户以外,还有以下字段:

owner(组长)

name(项目名)

private(是否私有)

项目角色表 models/project_role.py


from app.models import db
from datetime import datetime
class ProjectRole(db.Model):
    id = db.Column(db.INT, primary_key=True)
    project_id = db.Column(db.INT, index=True)
    project_role = db.Column(db.INT, index=True)
    created_at = db.Column(db.DATETIME, nullable=False)
    updated_at = db.Column(db.DATETIME, nullable=False)
    deleted_at = db.Column(db.DATETIME)
    create_user = db.Column(db.INT, nullable=True)
    update_user = db.Column(db.INT, nullable=True)
    def __init__(self, project_id, project_role, create_user):
        self.project_id = project_id
        self.project_role = project_role
        self.created_at = datetime.now()
        self.updated_at = datetime.now()
        self.create_user = create_user
        self.update_user = create_user
        self.deleted_at = None

与上个表单类似,project_id是项目id,project_role是项目角色。

咱们规定:

1: 组长 2: 组员

测试用例表 models/test_case.py


from app.models import db
from datetime import datetime
class TestCase(db.Model):
    id = db.Column(db.INT, primary_key=True)
    name = db.Column(db.String(32), unique=True, index=True)
    request_type = db.Column(db.INT, default=1, comment="请求类型 1: http 2: grpc 3: dubbo")
    url = db.Column(db.TEXT, nullable=False, comment="请求url")
    request_method = db.Column(db.String(12), nullable=True, comment="请求方式, 如果非http可为空")
    request_header = db.Column(db.TEXT, comment="请求头,可为空")
    project_id = db.Column(db.INT, comment="所属项目")
    tag = db.Column(db.String(64), comment="用例标签")
    status = db.Column(db.INT, comment="用例状态: 1: 待完成 2: 暂时关闭 3: 正常运作")
    expected = db.Column(db.TEXT, comment="预期结果, 支持el表达式", nullable=False)
    created_at = db.Column(db.DATETIME, nullable=False)
    updated_at = db.Column(db.DATETIME, nullable=False)
    deleted_at = db.Column(db.DATETIME)
    create_user = db.Column(db.INT, nullable=False)
    update_user = db.Column(db.INT, nullable=False)
    def __init__(self, name, request_type, url, project_id, tag, status, expected, create_user, request_header=None,
                 request_method=None):
        self.name = name
        self.request_type = request_type
        self.url = url
        self.project_id = project_id
        self.tag = tag
        self.status = status
        self.expected = expected
        self.create_user = create_user
        self.update_user = create_user
        self.request_header = request_header
        self.request_method = request_method
        self.created_at = datetime.now()
        self.updated_at = datetime.now()

基本上内容都在comment注释里面了,大家看着就行,也不多讲解了。肯定现在还有一些特性没有考虑到的,后序可以加字段解决。

编写检查用户权限的装饰器


我们在上面三张表里面定义好了create_userupdate_user,其实这2个字段接受的都是咱们的用户id,而用户id又是可以通过token进行解析的。

4.jpg

之前编写过的解析token的方法

还记得之前编写过的解析token的方法吗?我们现在就来编写一个装饰器: 自动判断用户token是否有效以及获取用户信息。

5.jpg

image

原理很简单,就是通过headers中的token字段获取token,经过解析后拿到用户信息,这里更加复杂一点,对于那种需要有权限控制的地方,我们做了一层判断,如果权限在配置范围以下,那么普通成员就不能调用这个接口。

完整代码:


from functools import wraps
from flask import request, jsonify
from app import pity
from app.middleware.Jwt import UserToken
FORBIDDEN = "对不起, 你没有足够的权限"
class SingletonDecorator:
    def __init__(self, cls):
        self.cls = cls
        self.instance = None
    def __call__(self, *args, **kwargs):
        if self.instance is None:
            self.instance = self.cls(*args, **kwargs)
        return self.instance
def permission(role=pity.config.get("GUEST")):
    def login_required(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                headers = request.headers
                token = headers.get('token')
                if token is None:
                    return jsonify(dict(code=401, msg="用户信息认证失败, 请检查"))
                user_info = UserToken.parse_token(token)
                # 这里把user信息写入kwargs
                kwargs["user_info"] = user_info
            except Exception as e:
                return jsonify(dict(code=401, msg=str(e)))
            # 判断用户权限是否足够, 如果不足够则直接返回,不继续
            if user_info.get("role", 0) < role:
                return jsonify(dict(code=400, msg=FORBIDDEN))
            return func(*args, **kwargs)
        return wrapper
    return login_required

kwargs["user_info"] = user_info

重点注意一下这句话。

为之前咱们编写的http/request接口加入权限


6.jpg

这里插入咱们刚才的permission即可

由于我们这个接口暂时支持登录用户使用,所以权限默认就行了,也就是说用户role为0(普通用户)即可!

7.jpg

改动很简单,导入permission并使用

这里需要注意的是,我们的http_request必须带有user_info参数,否则会报错,因为我们后续可能会用到用户信息。

改造前端代码


因为我们之前前端在请求接口的时候,是不会带上用户token的,所以我们需要改造前端请求方法:

  1. 在发送http请求的时候带上token数据
  2. 校验返回code,如果为401则自动注销用户,提示用户未登录!
  • 创建src/utils/auth.js


import { message } from 'antd';
export default {
  headers: (json = true) => {
    const token = localStorage.getItem('pityToken');
    const headers = { token };
    if (json) {
      headers['Content-Type'] = 'application/json';
    }
    return headers;
  },
  response: (res, info = false) => {
    if (res.code === 0) {
      if (info) {
        message.info(res.msg);
      }
      return true;
    }
    if (res.code === 401) {
      // 说明用户未认证
      message.info(res.msg);
      localStorage.setItem('pityToken', null);
      localStorage.setItem('pityUser', null);
      window.location.href = '/user/login';
    }
    message.error(res.msg);
    return false;
  },
};

这里编写了获取token并组成headers的方法,也编写了针对token过期,权限不够的code码进行不同的处理。


  • 修改src/services/request.js

8.jpg

image

  • 修改请求结果:

9.jpg

请求结束后,只有当返回true状态时才设置response

  • 开始测试
    发现我们的错误信息并没有完全展示,是因为我们需要没有针对请求失败的情况进行校验,所以我们还需要调整后端接口:

10.jpg

image

判断里面的status是否为True,不为True的话返回110状态码

来个动态图测试一下吧:

16.PNG

image

接着测试一下权限

通过开发者工具的application可以看到:

12.jpg

我们的role默认是0

接着我们调整一下权限为: 只有管理员可以请求接口

13.jpg

image

来个动图看看:

17.PNG

image


打完收工,最近清明可以稍微更新多一点😳



相关文章
|
4天前
|
测试技术
软件测试用例设计之微信群抢红包经典用例
作者在浏览招聘网站时遇到为微信群发和抢红包设计测试用例的问题,作为软件测试新手,作者通过实际体验并撰写测试案例来加深对业务的理解,并分享了测试案例表格。需要注意的是,该用例未考虑添加银行卡支付、红包类型选择及红包描述。
16 5
软件测试用例设计之微信群抢红包经典用例
ACE
|
2天前
|
SQL 分布式计算 数据处理
如何创建2024云栖Openlake测试项目和配置环境
2024年云栖大会,MaxCompute 多项重磅产品新功能邀测发布,新特性包括 支持OpenLake的湖仓一体2.0、Object Table支持SQL或MaxFrame处理非结构化数据、Delta Table增量表格式、基于增量物化视图的增量计算、MCQA2.0 SQL引擎查询加速等。其相关特性将在中国区 公共云 北京、上海、杭州、深圳Region 上线开放试用。本文以最佳实践的方式,帮助您创建MaxCompute和周边产品 在Openlake解决方案demo中需要准备的实例、项目和开发环境,并完成配置。欢迎您玩转云栖邀测demo,体验新功能。
ACE
54 6
|
19天前
|
jenkins 测试技术 持续交付
解锁.NET项目高效秘籍:从理论迷雾到实践巅峰,持续集成与自动化测试如何悄然改变游戏规则?
【8月更文挑战第28天】在软件开发领域,持续集成(CI)与自动化测试已成为提升效率和质量的关键工具。尤其在.NET项目中,二者的结合能显著提高开发速度并保证软件稳定性。本文将从理论到实践,详细介绍CI与自动化测试的重要性,并以ASP.NET Core Web API项目为例,演示如何使用Jenkins和NUnit实现自动化构建与测试。每次代码提交后,Jenkins自动触发构建流程,通过编译和运行NUnit测试确保代码质量。这种方式不仅节省了时间,还能快速发现并解决问题,推动.NET项目开发迈向更高水平。
34 8
|
18天前
|
测试技术
基于LangChain手工测试用例转Web自动化测试生成工具
该方案探索了利用大模型自动生成Web自动化测试用例的方法,替代传统的手动编写或录制方式。通过清晰定义功能测试步骤,结合LangChain的Agent和工具包,实现了从功能测试到自动化测试的转换,极大提升了效率。不仅减少了人工干预,还提高了测试用例的可维护性和实用性。
28 4
|
26天前
|
存储 SQL 测试技术
单元测试问题之JCode5插件在项目中的实际应用效果如何解决
单元测试问题之JCode5插件在项目中的实际应用效果如何解决
36 3
|
26天前
|
Java 测试技术 Maven
单元测试问题之在Maven项目中引入JUnit 5和Mockito的依赖如何解决
单元测试问题之在Maven项目中引入JUnit 5和Mockito的依赖如何解决
86 1
|
27天前
|
测试技术 Android开发 iOS开发
Appium 是一个开源的自动化测试框架,它支持多种平台和多种编程语言
Appium是一款开源自动化测试框架,支持iOS和Android多平台及多种编程语言。通过WebDriver协议,开发者可编写自动化测试脚本。在iPhone上实现屏幕点击等操作需安装Appium及其依赖,启动服务器,并设置所需的测试环境参数。利用Python等语言编写测试脚本,模拟用户交互行为,最后运行测试脚本来验证应用功能。对于iPhone测试,需准备真实设备或Xcode模拟器。
59 1
|
1月前
|
人工智能 自然语言处理 测试技术
基于LangChain手工测试用例转接口自动化测试生成工具
本文介绍利用大语言模型自动生成接口自动化测试用例的方法。首先展示传统通过HAR文件生成测试用例的方式及其局限性,随后提出结合自然语言描述的测试需求与HAR文件来生成更全面的测试脚本。通过LangChain框架,设计特定的提示词模板,使模型能够解析测试需求文档和HAR文件中的接口信息,并据此生成Python pytest测试脚本。示例展示了正常请求、非法请求及无效路径三种测试场景的自动化脚本生成过程。最终,整合流程形成完整代码实现,帮助读者理解如何利用大模型提高测试效率和质量。
66 2
|
1月前
|
资源调度 Java 调度
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
|
16天前
|
持续交付 C# 敏捷开发
“敏捷之道:揭秘WPF项目中的快速迭代与持续交付——从需求管理到自动化测试,打造高效开发流程的全方位指南”
【8月更文挑战第31天】敏捷开发是一种注重快速迭代和持续交付的软件开发方法,通过短周期开发提高产品质量并快速响应变化。本文通过问题解答形式,探讨在Windows Presentation Foundation(WPF)项目中应用敏捷开发的最佳实践,涵盖需求管理、版本控制、自动化测试及持续集成等方面,并通过具体示例代码展示其实施过程,帮助团队提升代码质量和开发效率。
29 0