基于 Sonic 的云测平台新增脚本任务模式的设计与实现

Ming
Ming
订阅者
273
文章
0
粉丝
测试交流评论134字数 1391阅读4分38秒阅读模式

前言:

用户社区 https://sonic-cloud.wiki/
官方网站 https://sonic-cloud.gitee.io/

一、 方案概述

云测平台新增脚本模式,可在平台上直接上传脚本;
云测平台新增任务模式,任务可关联脚本、设备、agent 等信息;任务支持立即执行、修改、定期执行、查看报告等基本功能;
白屏监控可作为其中的一项任务执行,关联至白屏监控脚本上;文章源自玩技e族-https://www.playezu.com/189701.html

二、 sonic 脚本管理

2.1 前端 ui 设计

导航栏新增一列脚本管理,页面展示:
操作行:新增脚本
脚本列表,列表后展示操作按钮,包括:删除、调试、下载
权限管理:初期全放开,后期接入权限模块后再做详细拆分文章源自玩技e族-https://www.playezu.com/189701.html

参考:
基于 Sonic 的云测平台新增脚本任务模式的设计与实现插图文章源自玩技e族-https://www.playezu.com/189701.html

2.2 新增脚本

点击按钮,可以选择文件/文件夹(或者压缩包)上传,此处可直接使用现有实现逻辑(压测平台参数化接口),将对应文件上传至 wos 存储
存储成功后,将该脚本相关信息存储至脚本表中文章源自玩技e族-https://www.playezu.com/189701.html

表设计如下:文章源自玩技e族-https://www.playezu.com/189701.html

脚本 id脚本名称关联任务 id资源 url创建时间更新人员创建人员更新时间脚本类型md5 校验文件大小删除位标记脚本状态扩展字段
idscript_nametask_idres_urlcreate_timeupdate_uidcreate_uidupdate_timescript_typemd5_valueres_sizeflag_deletedscript_statusexport

2.2.1 前端交互设计

参考:https://blog.csdn.net/weixin_46038888/article/details/124117369文章源自玩技e族-https://www.playezu.com/189701.html

// 新增上传操作
// HTML 
<el-upload
ref="upload"
class="upload-demo"
action="#"
accept=".xlsx, .xls"
:auto-upload="false"
:on-change="uploadFile"
:show-file-list="false"
>
<el-button type="warning">导入商品</el-button>
        </el-upload>
// JS
uploadFile (item) {
let formData = new FormData()
let file = item.raw
formData.append('file', file)
this.$http({
url: '', //后端提供的接口
method: 'post',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(({data}) => {
this.$alert(data.data)
})
}

2.2.2 后端逻辑

新增接口,包装墨洁的上传接口
当文件上传成功后,
将新增上传文件相关信息落库
参考:
基于 Sonic 的云测平台新增脚本任务模式的设计与实现插图1文章源自玩技e族-https://www.playezu.com/189701.html

创建两个脚本类型: DTO+VO
script.java文章源自玩技e族-https://www.playezu.com/189701.html

package org.cloud.sonic.common.models.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.gitee.sunchenbin.mybatis.actable.annotation.*;
import com.gitee.sunchenbin.mybatis.actable.constants.MySqlCharsetConstant;
import com.gitee.sunchenbin.mybatis.actable.constants.MySqlEngineConstant;
import org.cloud.sonic.common.models.base.TypeConverter;
import org.cloud.sonic.common.models.dto.TestSuitesDTO;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@ApiModel(value = "脚本对象", description = "")
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("script")
@TableComment("脚本对象表")
@TableCharset(MySqlCharsetConstant.DEFAULT)
@TableEngine(MySqlEngineConstant.InnoDB)
public class Script implements Serializable, TypeConverter<Script, ScriptDTO> {
@TableId(value = "id", type = IdType.AUTO)
@IsAutoIncrement
private Integer id;
@TableField
@TableLogic
@Column(isNull = false, comment = "脚本状态")
private boolean deleted;
@TableField
@Column(value = "resource_url", isNull = false, comment = "脚本资源url")
private String resourceUrl;
@TableField
@Column(value = "create_time", isNull = false, comment = "创建时间")
private String createTime;
@TableField
@Column(value = "update_time", comment = "更新时间")
private String updateTime;
@TableField
@Column(value = "create_person", isNull = false, comment = "创建人员")
private String createPerson;
@TableField
@Column(value = "update_person", comment = "更新人员")
private String updatePerson;
@TableField
@Column(isNull = false, comment = "脚本类型")
private String type;
@TableField
@Column(isNull = false, comment = "脚本大小")
private Integer size;
@TableField
@Column(value = "renwu_id", isNull = false, comment = "脚本关联任务ID")
@Index(value = "IDX_PROJECT_ID", columns = {"id"})
private Integer renwuId;
}

scriptDTO.java文章源自玩技e族-https://www.playezu.com/189701.html

package org.cloud.sonic.common.models.dto;
import org.cloud.sonic.common.models.base.TypeConverter;
import org.cloud.sonic.common.models.domain.TestSuites;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Positive;
import java.io.Serializable;
import java.util.List;
@ApiModel("测试套件DTO 模型")
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TestSuitesDTO implements Serializable, TypeConverter<TestSuitesDTO, TestSuites> {
@ApiModelProperty(value = "id", example = "1")
Integer id;
@NotBlank
@ApiModelProperty(value = "测试套件名称", required = true, example = "首页测试套件")
String name;
@Positive
@ApiModelProperty(value = "测试套件平台类型", required = true, example = "1")
Integer platform;
@Positive
@ApiModelProperty(value = "覆盖类型", required = true, example = "1")
Integer cover;
@Positive
@ApiModelProperty(value = "项目id", required = true, example = "1")
Integer projectId;
@ApiModelProperty(value = "包含的测试用例")
List<TestCasesDTO> testCases;
@ApiModelProperty(value = "指定设备列表")
List<DevicesDTO> devices;
}

添加 mappler 文件文章源自玩技e族-https://www.playezu.com/189701.html

package org.cloud.sonic.controller.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.cloud.sonic.common.models.domain.TestSuites;
import org.apache.ibatis.annotations.Mapper;
/**
*  Mapper 接口
* @author JayWenStar
* @since 2021-12-17
*/
@Mapper
public interface TestSuitesMapper extends BaseMapper<TestSuites> {
}

2.3 删除脚本

将该脚本状态置为 DELETE
调用 save 接口

2.4 下载脚本

将该文件资源下载至本地,新增一个下载接口

2.5 脚本调试执行(初步方案,后期优化前端加上执行日志展示框)

2.5.1 整体流程

  1. 发起调试执行接口
  2. 接口调用脚本调试方法
  3. server 端处理一些异常判断,分配执行 agent 与设备,从数据库获取该脚本相关信息,拼接消息类型下发至 agent
  4. agent 端:脚本下载、判断任务类型、环境校验/配置、调用脚本执行
  5. agent 端:等待 Python 脚本回调消息,Python 脚本执行完毕后,给 java 一个回调
  6. agent 端:整体任务执行完毕后,给 server 通信

2.5.2 server 处理流程

基于 Sonic 的云测平台新增脚本任务模式的设计与实现插图2

2.5.3 agent 处理流程

基于 Sonic 的云测平台新增脚本任务模式的设计与实现插图3

三、任务管理

实现逻辑

可直接参考 org.cloud.sonic.simple.controller.TestSuitesController.runSuite 方法

public RespModel<String> runSuite(int suiteId, String strike) {
TestSuitesDTO testSuitesDTO;
if (existsById(suiteId)) {
testSuitesDTO = findById(suiteId);
} else {
return new RespModel<>(3001, "测试套件已删除!");
}
if (testSuitesDTO.getTestCases().size() == 0) {
return new RespModel<>(3002, "该测试套件内无测试用例!");
}
List<Devices> devicesList = BeanTool.transformFromInBatch(testSuitesDTO.getDevices(), Devices.class);
for (int i = devicesList.size() - 1; i >= 0; i--) {
if (devicesList.get(i).getStatus().equals(DeviceStatus.OFFLINE) || devicesList.get(i).getStatus().equals(DeviceStatus.DISCONNECTED)) {
devicesList.remove(devicesList.get(i));
}
}
if (devicesList.size() == 0) {
return new RespModel<>(3003, "所选设备暂无可用!");
}

四、整体设计方案流程

##4.1 server 执行任务流程
基于 Sonic 的云测平台新增脚本任务模式的设计与实现插图4

##4.2 agent 执行任务流程
基于 Sonic 的云测平台新增脚本任务模式的设计与实现插图5

4.3 脚本执行流程

基于 Sonic 的云测平台新增脚本任务模式的设计与实现插图6

软件测试支付功能怎么测试

 
匿名

发表评论

匿名网友
确定

拖动滑块以完成验证