测试开发-脚本开发工具

写在前面

今天给大家介绍一个我自己开发的脚本开发工具,可能大多数人会叫这种东西为数据工厂,但是我认为还没达到 自动生成测试数据的地步,所以先叫他脚本开发工具,顾名思义,是用来开发脚本的一个工具,那么为什么测试要做一个这么样的工具呢。

背景

原因有几个, 第一,在测试平台开发的过程中,会开发一些小工具,为了方便测试同学构造数据,这些工具会有一个共同的特点,就是输入一些参数,输出一些返回值,如果每一个工具都开发一个页面,1、成本会很高,2、平台会显得比较臃肿,所以根据抽象的编程思想,才想到做一个这样的工具,第二, 在实际测试过程,大多会遇到这么两个场景,1.是有些数据构造起来比较复杂 例如:发布职位,发布一个职位需要填写相关的职位信息等,填完之后还需要进行职位审核,经过这系列操作后,职位才算是发布成功。2、第二个是同一条数据我需要 多个,例如:测试分页。这些场景都会是影响实际的测试工作中影响测试效率的点。为了解决测试效率问题和开发工具的效率问题,我们引入了脚本的概念。

引入脚本

  1. 脚本的优势 脚本具有灵活性,不需要类似服务的复杂配置过程,也无需部署,而且各种语言都可以进行脚本的编写,编写起来也不复杂。
  2. 脚本的分类 脚本可以根据语言进行分类,主流的有python 、java、php、shell 脚本

不会代码怎么学习脚本的编写

其实所有工具的开发都不只是代码作为基础,这么说,如果你会代码,也不一定能开发出好的测试工具,编写脚本的前提是你需要了解自己所负责的业务,同时还需要了解业务的接口、数据库、数据表,然后了解在测试过程中影响测试效率的问题,最后才是需要学习一门编程语言,但是编程语言也不需要学习那么多,只学习数据库的增删改查和接口怎么请求调用即可。

三种常见脚本的编写

java 脚本比较特殊,需要编译一下

  • javac +脚本名称 生成.class 文件
  • java + 脚本名称 + 参数 运行class 文件
  • 备注:- java 通过args 去获取 参数
csharp 复制代码
public class HelloJava{
        public static void main(String[] args){
                System.out.println("第一个参数是"+args[0]);
                System.out.println("第二个参数是"+args[1]);
                System.out.println("第三个参数是"+args[2]);
        }
}

python 脚本

  • 执行方式:python + 脚本名称 + 参数
  • 备注:python 通过 sys.argv 获取参数
go 复制代码
import sys

if __name__ == '__main__':
    print("第一个参数是:"+sys.argv[0])
    print("第一个参数是:"+sys.argv[1])
    print("第二个参数是:"+sys.argv[2])

shell 脚本

  • sh + 脚本名称 + 参数 或者./+ 脚本名称 + 参数
  • 备注:shell 通过$ 获取参数
bash 复制代码
#!/bin/bash

echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
~

脚本工具的设计

1、那么开始,环境准备,既然需要执行这么多种脚本,所以需要弄一个服务器,然后搭建python、java等环境。

2、了解了脚本工具的设计之后,我们需要设计一个脚本上传记录的表,在设计一张根据业务分组展示的表

sql 复制代码
CREATE TABLE `tools_script` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `project_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '脚本项目组ID',
  `script_name` varchar(1024) NOT NULL DEFAULT '' COMMENT '脚本名称',
  `script_function` varchar(1024) NOT NULL DEFAULT '' COMMENT '脚本功能描述',
  `run_desc` varchar(1024) NOT NULL DEFAULT '' COMMENT '执行描述',
  `address` varchar(1024) NOT NULL DEFAULT '' COMMENT '脚本路径',
  `rely_path` varchar(1024) NOT NULL DEFAULT '' COMMENT '脚本依赖的路径',
  `config` varchar(1024) NOT NULL DEFAULT '' COMMENT '脚本配置',
  `author` varchar(1024) NOT NULL DEFAULT '' COMMENT '脚本作者',
  `status` bigint(20) NOT NULL DEFAULT '0' COMMENT '脚本状态',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `run_time` int(20) NOT NULL DEFAULT '0' COMMENT '执行次数',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=78 DEFAULT CHARSET=utf8mb4 COMMENT='脚本配置信息表';


CREATE TABLE `tools_script_group` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `project` varchar(1024) NOT NULL DEFAULT '' COMMENT '项目名称',
  `status` bigint(20) NOT NULL DEFAULT '0' COMMENT '脚本状态',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `alias` varchar(1024) NOT NULL DEFAULT '' COMMENT '分组别名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COMMENT='脚本配置信息表';

3、我们了解了脚本的编写和脚本的调用方式,根据他们的共同特点,我们可以写一个公共的调用方法去处理不同类型的脚本,无论是java 、shell、python ,都可以 通过 通过脚本名+ 参数的方式执行。

脚本执行类

ini 复制代码
package cn.boss.platform.common.utils;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class RunScriptUtil {

    public String runScript(String scriptName ,String scriptPath, String scriptParam){
        //脚本输出后 文本
        String content = "";
        // 截取文件的后缀名
        String endName = "";

        String line = "";
        //截取_之后字符串
        if (scriptName.contains(".")){
            String str1 = scriptName.substring(0, scriptName.indexOf("."));
            endName = scriptName.substring(str1.length()+1);
        }
        else {
            content = "请检查文件名格式";

            return content;
        }

        Runtime r = Runtime.getRuntime();
        if (endName.equals("java")){
            try{
                // 切换目录
                String[] cmd = {"/bin/sh", "-c", "cd " + scriptPath  +";/javac"+" "+scriptName +";/java"+" "+ scriptName.substring(0, scriptName.indexOf(".")) +" "+ scriptParam};
                Process proc =  r.exec(cmd);

                int exitVal = proc.waitFor();

                if (exitVal == 0){
                    BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream(), "utf-8"));

                    while ((line = reader.readLine()) != null){
                        content  +=  line + " ";
                    }
                }else {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getErrorStream(), "utf-8"));

                    while ((line = reader.readLine()) != null){
                        content  +=  line + " ";
                    }
                }
            }
            catch(Exception e){
                e.printStackTrace();
            }
        }
        else if(endName.equals("py")){
            try{
                String cmd = "/usr/bin/python3"+" "+ scriptPath+"/"+scriptName +" " +scriptParam;
                // 假设该操作为造成大量内容输出

                Process proc = r.exec(cmd);


                int exitVal = proc.waitFor();

                if (exitVal == 0){
                    BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream(), "utf-8"));

                    while ((line = reader.readLine()) != null){
                        content  +=  line + " ";
                    }
                }else {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getErrorStream(), "utf-8"));

                    while ((line = reader.readLine()) != null){
                        content  +=  line + " ";
                    }
                }

            }
            catch(Exception e){
                e.printStackTrace();
            }
        }
        else if(endName.equals("sh")){
            content = "";
            try{
                String cmd = "sh"+" "+ scriptPath+"/"+scriptName +" " +scriptParam;
                Process proc = r.exec(cmd);

                int exitVal = proc.waitFor();
                if (exitVal == 0){
                    BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream(), "utf-8"));

                    while ((line = reader.readLine()) != null){
                        content  +=  line + " ";
                    }
                }else {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getErrorStream(), "utf-8"));

                    while ((line = reader.readLine()) != null){
                        content  +=  line + " ";
                    }
                }
            }
            catch(Exception e){
                e.printStackTrace();
            }
        }
        else if(endName.equals("ipynb")){
            try{
                String[] cmd = {"/bin/sh", "-c", "cd " + scriptPath  +";jupyter nbconvert --to script"+" "+scriptName +";python3"+" "+ scriptPath+"/"+scriptName.substring(0, scriptName.indexOf("."))+".py" +" " +scriptParam};
                // 假设该操作为造成大量内容输出
                Process proc = r.exec(cmd);



                int exitVal = proc.waitFor();

                if (exitVal == 0){


                    BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream(), "utf-8"));

                    while ((line = reader.readLine()) != null){
                        System.out.println(line);

                        content  +=  line + " ";
                    }
                }else {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getErrorStream(), "utf-8"));

                    while ((line = reader.readLine()) != null){
                        System.out.println(content);

                        content  +=  line + " ";
                    }
                }

            }
            catch(Exception e){
                e.printStackTrace();
            }
        }
        else {
            content = "暂不支持该脚本执行,请联系管理员";
        }
        return content;
    }


    public static void main(String[] args) {
        RunScriptUtil runScript = new RunScriptUtil();
        String i = runScript.runScript("脚本名","脚本所在路径","参数");
        System.out.println(i);
    }
}

4、然后可以写一下,脚本上传,脚本编辑、脚本获取,脚本执行,脚本删除的接口

less 复制代码
package cn.boss.platform.web.tools;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;


import java.io.UnsupportedEncodingException;
import java.util.*;

@Controller
@RequestMapping("/tools/script")
public class BossToolsScriptController {



    @RequestMapping(value = "/get_all_project", method = RequestMethod.GET)
    @ResponseBody
    public ResultBean<Object> getAllProject(){


    }

    @GetMapping("/get_group_by_project")
    @ResponseBody
    public ResultBean<Object> getGroupByProject(@RequestParam(value = "project",required = true) String project){

    }

    @CrossOrigin
    @GetMapping("/get_script_by_name")
    @ResponseBody
    public ResultBean<Object> getScriptByName(@RequestParam(value = "script_name",required = true) String scriptName){

    }


    @RequestMapping(value = "/add_group", method = RequestMethod.POST)
    @ResponseBody
    public ResultBean<Object> addBossToolsScriptGroupBean(@RequestBody BossToolsScriptGroupBean groupInfo){

    }

    @GetMapping("/del_group")
    @ResponseBody
    public ResultBean<Object> delBossToolsScriptGroup(@RequestParam(value = "id",required = true) Integer id){

    }

    @GetMapping("/get_script_by_id")
    @ResponseBody
    public ResultBean<Object> selectScriptById(@RequestParam("project_id") Integer projectId){

    }

  
    @RequestMapping(value = "/add_script", method = RequestMethod.POST)
    @ResponseBody
    public ResultBean<Object> addScript(@RequestParam Map<String,Object> scriptInfo){

    }

 
    @GetMapping("/del_script")
    @ResponseBody
    public  ResultBean<Object> delScript(@RequestParam("script_name") String scriptName){



 }
    @GetMapping("/get_all_script")
    @ResponseBody
    public ResultBean<Object> selectAllScript(){

    }

    @GetMapping("/get_script_by_author")
    @ResponseBody
    public ResultBean<Object> selectScriptByAuthor(@RequestParam("author") String author){
  
    }

}

这样后端就开发完成了

脚本开发工具前端的开发

xml 复制代码
<template>

  <el-container>
    <el-header style="height: 35px">


          <div class="one" v-if="isRouterAlive" >
            <vue-custom-scrollbar class="scroll-area"  :settings="settings" >
                  <el-menu mode="horizontal" >
                    <el-submenu v-for="(item) in menu" :key="item.index" :index="item.id+ ''" style="padding-left: 1%">
                      <template slot="title">{{item.label}}<svg-icon  icon-class="dropdown"></svg-icon></template>
                      <el-menu-item  v-for="(item) in item.children" :key="item.index" :index="'sub' +item.id" @click="getScript(item.label)">{{item.func}}</el-menu-item>
                    </el-submenu>
                  </el-menu>
            </vue-custom-scrollbar>
          </div>


      <div class="two" style="padding-top: 10px; padding-left: 30%">
        <el-tooltip class="item" effect="dark" content="首页:脚本开发工具的首页" placement="top-start">
          <el-button type="primary" icon="el-icon-s-home" circle @click="onEdit"></el-button>
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="添加脚本:编写完脚本记得在此处添加" placement="top-start">
          <el-button type="info" icon="el-icon-circle-plus-outline" circle @click="onAdd"></el-button>
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="编写脚本:可以在此处上传或者编写脚本" placement="top-start">
          <el-button type="warning" icon="el-icon-edit-outline" circle @click="onWrite"></el-button>
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="说明文档" placement="top-start">
          <el-button type="warning" icon="el-icon-question" circle @click="ondoc"></el-button>
        </el-tooltip>
      </div>

    </el-header>
    <div style= "background-color: #d7dee5; height: 3px; margin-top: 25px"> </div>
    <el-main>
      <div id="script" v-if="isShow ==1">
        <div class="body-content" style=";float:left;">
          <h3 style=" text-align: left; padding-bottom: 15px">执行脚本</h3>
          <el-form ref="runScriptForm" label-width="85px" :label-position="labelPosition">
            <el-form-item label="脚本名称:"  style="margin-bottom: 10px; text-align: left">
              {{runScriptForm.scriptName}}
            </el-form-item>
            <el-form-item label="作者:" style=" margin-bottom: 10px; text-align: left">
              {{runScriptForm.author}}
            </el-form-item>
            <el-form-item label="功能介绍:"  style="margin-bottom: 10px; text-align: left">
              {{runScriptForm.scriptFunction}}
            </el-form-item>
            <el-form-item label="参数说明:"  style="margin-bottom: 10px; text-align: left">
              {{runScriptForm.runDesc}}
            </el-form-item>
            <el-form-item v-for="(item,i) in config" :key="i" :label="item.label">
              <el-input style="width: 500px" v-model="item.key"></el-input>
              <addUserId v-if="item.label === 'uid' || item.label === 'userId'" @updateUserId="updateUserId"></addUserId>
            </el-form-item>

            <el-form-item label-width="0px" style="text-align: left">
              <el-button type="success" size="medium" @click="run" :loading="loading">立即执行</el-button>
            </el-form-item>
          </el-form>

          <div style="padding-left: 5px">
            <span style=" font-size: 15px;font-weight: 400;color: #9fa3b0;">执行结果:<span :style="{color: color}">{{message}}</span></span>
            <div>
              <!--  text-align: left; word-wrap:break-word; word-break: break-all; overflow:auto;white-space: pre-wrap;-->
              <pre style="border:1px solid  #9fa3b0;width:100%;height: 500px;font-size:15px;" placeholder="返回结果" v-html="syntaxHighlightTools(response)"></pre>
            </div>
          </div>
        </div>
        <div id="top">
          <div id="personal">
            <h3 style="font-size: 18px;line-height: 22px;"><svg-icon class="icon" icon-class="personal"></svg-icon>我开发的脚本</h3>
            <li class="tr">
              <div class="td1">序号</div>
              <div class="td1">名称</div>
              <div class="td1">功能</div>
              <div class="td1">操作</div>
            </li>
            <div v-if="showPersonalData ==false">
              <vue-custom-scrollbar class="presonal-scroll-area"  :settings="personSettings" >
              <li class="ti" v-for="(item,i) in personal" :key="i">
                <div class="t2">{{item['id']}}</div>
                <div class="t2" @click="getScript(item['scriptName'])"><a>{{item['scriptName']  | ellipsis1}}</a></div>
                <div class="t2">{{item['scriptFunction'] | ellipsis}}</div>
                <div class="t2">

                  <el-button type="text" class="el-icon-edit" @click="getEditScriptInfo(item['scriptName'])"></el-button>
                  <el-button type="text" icon="el-icon-delete"  @click="onDelete(item['scriptName'])" style="margin-left:0px;"></el-button>

                </div>

                <el-dialog title="编辑脚本配置" :visible.sync="dialogFormVisible" :modal-append-to-body=false>
                  <el-form :model="editScriptForm">
                    <el-form-item label="脚本名称:">
                      {{editScriptForm.scriptName}}
                    </el-form-item>
                    <el-form-item label="功能介绍:">
                      <el-input v-model="editScriptForm.scriptFunction" placeholder="可以添加一些脚本具体的用途和一些描述信息" autocomplete="off"></el-input>
                    </el-form-item>
                    <el-form-item label="参数说明:">
                      <el-input v-model="editScriptForm.runDesc" placeholder="可以添加一些执行参数的描述信息" autocomplete="off"></el-input>
                    </el-form-item>
                    <el-form-item label="参数:" label-width="70px">
                      <el-input v-model="editScriptForm.config" placeholder="脚本参数名称列表,例如env,uid,中间用,分割如果没有请输入 无" autocomplete="off"></el-input>
                    </el-form-item>
                  </el-form>
                  <div slot="footer" class="dialog-footer">
                    <el-button @click="dialogFormVisible = false">取 消</el-button>
                    <el-button type="primary" @click="editScript">确 定</el-button>
                  </div>
                </el-dialog>
              </li>
              </vue-custom-scrollbar>
            </div>
            <div class="data" v-else-if="showPersonalData == true">
              <svg-icon class="icon1" icon-class="dataNull"></svg-icon>
              <p class="null">暂无数据</p>
            </div>
          </div>

          <div id="ranking">
              <h3 style="font-size: 18px;line-height: 22px;"><svg-icon class="icon" icon-class="top"></svg-icon>排行榜</h3>
              <li class="tr">
                <div class="td">名次</div>
                <div class="td">名称</div>
                <div class="td">执行次数</div>
                <div class="td">功能</div>
              </li>
              <div  v-if="showData ==false">
              <vue-custom-scrollbar class="ranking-scroll-area"  :settings="personSettings" >
              <li class="ti" v-for="(item,i) in topOne" :key="i">
                <div class="t1">{{item['ranking']}}</div>
                <div class="t1" @click="getScript(item['scriptName'])"><a>{{item['scriptName']  | ellipsis1}}</a></div>
                <div class="t1">{{item['runTime']}}</div>
                <div class="t1">{{item['scriptFunction'] | ellipsis}}</div>
              </li>
              </vue-custom-scrollbar>
              </div>
              <div class="data" v-else-if="showData == true">
                <svg-icon class="icon" icon-class="dataNull"></svg-icon>
                <p class="null">暂无数据</p>
              </div>
          </div>
        </div>
      </div>
      <div id="edit" v-if="isShow == 2" >
        <div class="body-content" >
        <h3 style=" text-align: left; padding-bottom: 15px">添加脚本</h3>
        <el-form ref="form" :model="addScriptForm" label-width="80px" :label-position="labelPosition">
          <el-form-item label="脚本名称">
            <el-input v-model="addScriptForm.scriptName" placeholder="脚本名称,注:加后缀名"></el-input>
          </el-form-item>
          <el-form-item label="脚本目录">
            <el-select v-model="addScriptForm.project" placeholder="请选择项目" style="width: 500px">
              <el-option  v-for="(item,index) in projectOptions" :key="index" :label="item" :value="item"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="脚本功能">
            <el-input v-model="addScriptForm.scriptFunction" placeholder="可以添加一些脚本具体的用途和一些描述信息"></el-input>
          </el-form-item>
          <el-form-item label="执行描述">
            <el-input v-model="addScriptForm.runDesc" placeholder="可以添加一些执行参数的描述信息"></el-input>
          </el-form-item>
          <el-form-item label="依赖路径">
            <el-input v-model="addScriptForm.relyPath" placeholder="脚本所依赖文件的目录,没有填 无"></el-input>
          </el-form-item>
          <el-form-item label="参数列表">
            <el-input type="textarea" v-model="addScriptForm.config" placeholder="脚本参数名称列表,例如env,uid,中间用,分割如果没有请输入 无"  style="width: 500px"></el-input>
          </el-form-item>
          <el-form-item label-width="0px" style="text-align: left">
            <el-button type="primary" @click="addScript">立即添加</el-button>
          </el-form-item>
        </el-form>
        </div>
      </div>
      <div id="frame" v-if="isShow ==4">
        <iframe
                :style="autoHeight"
                src="http://192.168.18.220:7777/lab" >
        </iframe>
      </div>
      <div id="frame" v-if="isShow ==5">
        <iframe
          :style="autoHeight"
          src="http://192.168.18.220:3000" >
        </iframe>
      </div>
    </el-main>
  </el-container>
</template>
<script>
import {
  addScript,
  getScriptGroup,
  runScript,
  getProject,
  getScriptByName,
  delScript,
  getAllScript,
  getScriptByAuthor, editScript
} from '@/api/zpTools/tools'
import { syntaxHighlight } from '@/utils/apiUtil'
import addUserId from '@/views/zpTools/other/captureAndMock/addUserId'
import vueCustomScrollbar from 'vue-custom-scrollbar'
import "vue-custom-scrollbar/dist/vueScrollbar.css"
export default {
  name: "scriptManger",
  components: {
    addUserId,
    vueCustomScrollbar
  },
  data() {
    return {
      labelPosition:'left',
      dialogFormVisible:false,
      isShow: 1,
      form:[],
      settings: {
        suppressScrollY: true,
        suppressScrollX: false,
        wheelPropagation: false
      },
      personSettings: {
        suppressScrollY: false,
        suppressScrollX: true,
        wheelPropagation: false
      },
      showData: false,
      showPersonalData:false,
      icon:'top',
      color:'green',
      isRouterAlive: true,
      iframeLoading: false,
      topOne:[],
      personal:[],
      scriptTime:{},
      editScriptForm:{
        scriptName:'',
        runDesc:'',
        scriptFunction:'',
        config:'',
      },
      runScriptForm:{
        scriptName:'',
        author:'',
        runDesc:'',
        scriptFunction:'',
        config:'',
      },
      response:'',
      message:'',
      loading: false,
      addScriptForm: {
        scriptName: '',
        project:'',
        scriptFunction: '',
        runDesc: '',
        address: '',
        relyPath: '',
        config: '',
        author: this.$store.state.user.name,
        status:1,
        runTime:0
      },
      config:[],
      projectOptions:[],
      menu:[],
      userId:'',
      clientHeight: '',
      autoHeight:{
        width:'100%',
        overflow: 'auto',
        height:'400px',
      }
    };
  },
  watch: {
    // 如果 clientHeight 发生改变,这个函数就会运行
    clientHeight() {
      this.changeFixed(this.clientHeight);
    }
  },
  mounted() {
    //获取脚本信息
    this.getMenu()
    this.getProject()
    this.getAllScript()
    this.getScriptPersonal()
    this.config = this.$store.state.tools.paramConfig

    // 获取浏览器可视区域高度
    this.clientHeight = document.documentElement.clientHeight; // document.body.clientWidth;
    window.onresize = function temp() { // 在窗口或框架被调整大小时触发
      this.clientHeight = document.documentElement.clientHeight;
    };

  },
  methods: {
    // 根据屏幕高度动态修改iframe 样式
    changeFixed(clientHeight) { // 动态修改样式
      this.autoHeight.height = clientHeight + 'px';
    },
    updateUserId (userId) {
      this.userId = userId
      this.getScript(this.runScriptForm.scriptName)
      this.$store.commit('tools/setRappPackageUserId', this.userId);
    },
    handleSelect(key, keyPath) {
    },
    async getScriptPersonal(){

      const result = await getScriptByAuthor(this.$store.state.user.name)
      if (result['data'].length == 0){
        this.showPersonalData = true
      }else {
        for(let i in result['data']){
          let top = {
            id:'',
            scriptName:'',
            scriptFunction:'',
          }
          top.id = +i +1
          top.scriptFunction = result["data"][i]["scriptFunction"]
          top.scriptName = result["data"][i]["scriptName"]
          this.personal.push(top)
        }
      }


    },
    async getAllScript(){
      const result = await getAllScript();
      if (result['data'].length == 0){
        this.showData = true
      }
      else {
        for(let i in result['data']){
          let top = {
            ranking:'',
            scriptName:'',
            scriptFunction:'',
            runTime:''
          }


          top.ranking = +i +1
          top.scriptFunction = result["data"][i]["scriptFunction"]
          top.scriptName = result["data"][i]["scriptName"]
          top.runTime = result["data"][i]["runTime"]
          this.topOne.push(top)

          this.scriptTime[result["data"][i]["scriptName"]] = result["data"][i]["runTime"]
        }
        await this.getScript(result['data'][0]['scriptName'])
      }

    },

    //获取编辑脚本
    async getEditScriptInfo(name){
      this.dialogFormVisible = true
      const result = await getScriptByName(name);
      this.editScriptForm.scriptName = result["data"][0]["scriptName"]
      this.editScriptForm.config = result["data"][0]["config"]
      this.editScriptForm.scriptFunction = result["data"][0]["scriptFunction"]
      this.editScriptForm.runDesc = result["data"][0]["runDesc"]
    },
    //编辑脚本
    async editScript(name){
      this.dialogFormVisible = false
      const result = await editScript(this.editScriptForm);
      if(result['status'] === 'success'){
        this.$message({
          message: '编辑成功',
          type: 'success'
        });
      }
    },
    //获取默认脚本信息

    async getScript(name){
      const result = await getScriptByName(name);
      this.runScriptForm.scriptName = result["data"][0]["scriptName"]
      this.runScriptForm.author = result["data"][0]["author"]
      this.runScriptForm.scriptFunction = result["data"][0]["scriptFunction"]
      this.runScriptForm.runDesc = result["data"][0]["runDesc"]
      if( result["data"][0]["config"] === "无" ){
        this.config = []
      }
      else {
        this.config = []
        let str = result["data"][0]["config"]

        let str1 = str.split(',')
        let dict = {}
        for(let i in str1){
          dict['label'] = str1[i]
          if (str1[i] === 'uid' ||str1[i] === 'userId'){
            dict['key'] = this.userId
          }else {
            dict['key'] = ''
          }
          // dict['key'] = ''
          this.config.push(dict)
          dict = {}
        }
        // this.config = this.$store.state.tools.paramConfig
      }
      this.isShow = 1
    },

    async getProject(){
      const result = await getProject()
      this.projectOptions = result.data
    },
    async getMenu(){
      const  result = await getScriptGroup()
      this.menu = result.data
    },
    async run(){

      // this.$store.commit("tools/setParamConfig", this.config)
      this.loading = true;
      for (let i in this.config){
        this.runScriptForm.scriptPram +=this.config[i]["key"]+" "

      }
      if(this.runScriptForm.scriptPram){
        console.log(this.runScriptForm.scriptPram.replace(/undefined/,''))
        this.runScriptForm.scriptPram  = this.runScriptForm.scriptPram.replace(/undefined/,'')
      }
      this.runScriptForm.runTime = +this.scriptTime[this.runScriptForm.scriptName] +1
      const result = await runScript(this.runScriptForm);
      this.response = JSON.stringify(result)
      this.message = result['message']
      this.runScriptForm.scriptPram = ''
      this.loading = false;
      this.reload()
    },
    async addScript(){
      this.addScriptForm.address =  this.addScriptForm.project
      const result = await addScript(this.addScriptForm);
      await this.getMenu();
      if (result["message"] === "success"){
        await this.$alert('脚本添加成功', 'message', {
          confirmButtonText: '确定'
        });
    }else {
        await this.$alert('脚本添加失败', 'message', {
          confirmButtonText: '确定'
        });
      }
      this.reload()
      this.isShow = 1
    },
    onEdit(){
      this.isShow = 1
    },
    onAdd(){
      this.isShow = 2
    },
    onDelete(scriptName){
      this.isShow = 1
      this.$confirm('确定要删除%s脚本吗?'.replace('%s',this.runScriptForm.scriptName), '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        delScript(scriptName)
        this.$message("%s删除成功".replace('%s',this.runScriptForm.scriptName))
        this.getMenu()
        this.reload()
        this.getScript("crm_push_msg.py")
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    onWrite(){
      this.isShow = 4
    },
    ondoc(){
      this.isShow = 5
    },
    syntaxHighlightTools (jsonString) {
      try {
        console.log(typeof jsonString)
        let obj = JSON.parse(jsonString);
        if(typeof obj == 'object' && jsonString ) {
          return syntaxHighlight(JSON.stringify(obj, undefined, 2));
        }else {

        }
      } catch (ex) {
        return jsonString;
      }
    },

    //无感知刷新
    reload() {
      this.isRouterAlive = false;
      this.$nextTick(function () {
        this.isRouterAlive = true;
      });
    },
  },
  filters:{
    ellipsis(value){
      if (!value) return '';
      if (value.length > 9) {
        return value.slice(0,9) + '...'
      }
      return value
    },

    ellipsis1(value){
      if (!value) return '';
      if (value.length > 15) {
        return value.slice(0,15) + '...'
      }
      return value
    }
  }
}
</script>

<style scoped>
/*省略*/
</style>

前端页面的展示

添加脚本页面

脚本编辑页面

执行脚本页面

写着最后

整个的脚本开发工具就设计好了,这样不仅能提高测试人员的工作效率,而且可以通过脚本的编写提高测试团队的技术氛围,大家可以尝试下,我是小巴哥,一个陪你成长,实实在在分享 测试干货职场经验的人,欢迎关注!!!

相关推荐
何贤3 分钟前
2025 年终回顾:25 岁,从“混吃等死”到别人眼中的“技术专家”
前端·程序员·年终总结
冴羽5 分钟前
CSS 新特性!瀑布流布局的终极解决方案
前端·javascript·css
满天星辰11 分钟前
Vue 响应式原理深度解析
前端·vue.js
YDS82915 分钟前
SpringCloud —— MQ的可靠性保障和延迟消息
后端·spring·spring cloud·rabbitmq
怪可爱的地球人19 分钟前
em,rem,px,rpx单位换算,你弄懂了吗?
前端
无限大637 分钟前
为什么"区块链"不只是比特币?——从加密货币到分布式应用
后端
码途潇潇40 分钟前
JavaScript有哪些数据类型?如何判断一个变量的数据类型?
前端·javascript
洛神么么哒42 分钟前
freeswitch-初级-01-日志分割
后端
满天星辰42 分钟前
Vue真的是单向数据流?
前端·vue.js
细心细心再细心44 分钟前
Nice-modal-react的使用
前端