通用技术 测试开发 -如何优雅的开发脚本

小巴哥 · 2023年09月08日 · 最后由 小巴哥 回复于 2023年09月12日 · 5287 次阅读

写在前面

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

背景

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

引入脚本

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

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

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

三种常见脚本的编写

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

  • javac + 脚本名称 生成.class 文件
  • java + 脚本名称 + 参数 运行 class 文件
  • 备注:- java 通过 args 去获取 参数
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 获取参数
import sys

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

shell 脚本

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

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

脚本工具的设计

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

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

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 ,都可以 通过 通过脚本名 + 参数的方式执行。

脚本执行类

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、然后可以写一下,脚本上传,脚本编辑、脚本获取,脚本执行,脚本删除的接口

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){

    }

}

这样后端就开发完成了

脚本开发工具前端的开发

<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>

前端页面的展示

添加脚本页面

脚本编辑页面

执行脚本页面

写着最后

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

共收到 8 条回复 时间 点赞

图挂了

下面图没有了

yun 回复

好的,我重新弄下

好的,我重新弄一下

是个不错的思路!

感谢

我们团队前年做了个类似的东西 https://mp.weixin.qq.com/s/qpWe_AveUDQvKJ-zfoZglg 现在是作为测试的基础设施来用的

小狄子 回复

是的,挺实用的

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册