测试开发-脚本开发工具

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

背景

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

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

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

三种常见脚本的编写

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

  • javac +脚本名称 生成.class 文件
  • java + 脚本名称 + 参数 运行class 文件
  • 备注:- java 通过args 去获取 参数
 
  1. public class HelloJava{

  2. public static void main(String[] args){

  3. System.out.println("第一个参数是"+args[0]);

  4. System.out.println("第二个参数是"+args[1]);

  5. System.out.println("第三个参数是"+args[2]);

  6. }

  7. }

python 脚本

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

  2. if __name__ == '__main__':

  3. print("第一个参数是:"+sys.argv[0])

  4. print("第一个参数是:"+sys.argv[1])

  5. print("第二个参数是:"+sys.argv[2])

shell 脚本

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

  2. echo "执行的文件名:$0";

  3. echo "第一个参数为:$1";

  4. echo "第二个参数为:$2";

  5. echo "第三个参数为:$3";

  6. ~

脚本工具的设计

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

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

 
  1. CREATE TABLE `tools_script` (

  2. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',

  3. `project_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '脚本项目组ID',

  4. `script_name` varchar(1024) NOT NULL DEFAULT '' COMMENT '脚本名称',

  5. `script_function` varchar(1024) NOT NULL DEFAULT '' COMMENT '脚本功能描述',

  6. `run_desc` varchar(1024) NOT NULL DEFAULT '' COMMENT '执行描述',

  7. `address` varchar(1024) NOT NULL DEFAULT '' COMMENT '脚本路径',

  8. `rely_path` varchar(1024) NOT NULL DEFAULT '' COMMENT '脚本依赖的路径',

  9. `config` varchar(1024) NOT NULL DEFAULT '' COMMENT '脚本配置',

  10. `author` varchar(1024) NOT NULL DEFAULT '' COMMENT '脚本作者',

  11. `status` bigint(20) NOT NULL DEFAULT '0' COMMENT '脚本状态',

  12. `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  13. `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  14. `run_time` int(20) NOT NULL DEFAULT '0' COMMENT '执行次数',

  15. PRIMARY KEY (`id`)

  16. ) ENGINE=InnoDB AUTO_INCREMENT=78 DEFAULT CHARSET=utf8mb4 COMMENT='脚本配置信息表';

  17. CREATE TABLE `tools_script_group` (

  18. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',

  19. `project` varchar(1024) NOT NULL DEFAULT '' COMMENT '项目名称',

  20. `status` bigint(20) NOT NULL DEFAULT '0' COMMENT '脚本状态',

  21. `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  22. `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  23. `alias` varchar(1024) NOT NULL DEFAULT '' COMMENT '分组别名',

  24. PRIMARY KEY (`id`)

  25. ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COMMENT='脚本配置信息表';

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

脚本执行类

 
  1. package cn.boss.platform.common.utils;

  2. import java.io.BufferedReader;

  3. import java.io.InputStreamReader;

  4. public class RunScriptUtil {

  5. public String runScript(String scriptName ,String scriptPath, String scriptParam){

  6. //脚本输出后 文本

  7. String content = "";

  8. // 截取文件的后缀名

  9. String endName = "";

  10. String line = "";

  11. //截取_之后字符串

  12. if (scriptName.contains(".")){

  13. String str1 = scriptName.substring(0, scriptName.indexOf("."));

  14. endName = scriptName.substring(str1.length()+1);

  15. }

  16. else {

  17. content = "请检查文件名格式";

  18. return content;

  19. }

  20. Runtime r = Runtime.getRuntime();

  21. if (endName.equals("java")){

  22. try{

  23. // 切换目录

  24. String[] cmd = {"/bin/sh", "-c", "cd " + scriptPath +";/javac"+" "+scriptName +";/java"+" "+ scriptName.substring(0, scriptName.indexOf(".")) +" "+ scriptParam};

  25. Process proc = r.exec(cmd);

  26. int exitVal = proc.waitFor();

  27. if (exitVal == 0){

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

  29. while ((line = reader.readLine()) != null){

  30. content += line + " ";

  31. }

  32. }else {

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

  34. while ((line = reader.readLine()) != null){

  35. content += line + " ";

  36. }

  37. }

  38. }

  39. catch(Exception e){

  40. e.printStackTrace();

  41. }

  42. }

  43. else if(endName.equals("py")){

  44. try{

  45. String cmd = "/usr/bin/python3"+" "+ scriptPath+"/"+scriptName +" " +scriptParam;

  46. // 假设该操作为造成大量内容输出

  47. Process proc = r.exec(cmd);

  48. int exitVal = proc.waitFor();

  49. if (exitVal == 0){

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

  51. while ((line = reader.readLine()) != null){

  52. content += line + " ";

  53. }

  54. }else {

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

  56. while ((line = reader.readLine()) != null){

  57. content += line + " ";

  58. }

  59. }

  60. }

  61. catch(Exception e){

  62. e.printStackTrace();

  63. }

  64. }

  65. else if(endName.equals("sh")){

  66. content = "";

  67. try{

  68. String cmd = "sh"+" "+ scriptPath+"/"+scriptName +" " +scriptParam;

  69. Process proc = r.exec(cmd);

  70. int exitVal = proc.waitFor();

  71. if (exitVal == 0){

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

  73. while ((line = reader.readLine()) != null){

  74. content += line + " ";

  75. }

  76. }else {

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

  78. while ((line = reader.readLine()) != null){

  79. content += line + " ";

  80. }

  81. }

  82. }

  83. catch(Exception e){

  84. e.printStackTrace();

  85. }

  86. }

  87. else if(endName.equals("ipynb")){

  88. try{

  89. String[] cmd = {"/bin/sh", "-c", "cd " + scriptPath +";jupyter nbconvert --to script"+" "+scriptName +";python3"+" "+ scriptPath+"/"+scriptName.substring(0, scriptName.indexOf("."))+".py" +" " +scriptParam};

  90. // 假设该操作为造成大量内容输出

  91. Process proc = r.exec(cmd);

  92. int exitVal = proc.waitFor();

  93. if (exitVal == 0){

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

  95. while ((line = reader.readLine()) != null){

  96. System.out.println(line);

  97. content += line + " ";

  98. }

  99. }else {

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

  101. while ((line = reader.readLine()) != null){

  102. System.out.println(content);

  103. content += line + " ";

  104. }

  105. }

  106. }

  107. catch(Exception e){

  108. e.printStackTrace();

  109. }

  110. }

  111. else {

  112. content = "暂不支持该脚本执行,请联系管理员";

  113. }

  114. return content;

  115. }

  116. public static void main(String[] args) {

  117. RunScriptUtil runScript = new RunScriptUtil();

  118. String i = runScript.runScript("脚本名","脚本所在路径","参数");

  119. System.out.println(i);

  120. }

  121. }

4、然后可以写一下,脚本上传,脚本编辑、脚本获取,脚本执行,脚本删除的接口
 
  1. package cn.boss.platform.web.tools;

  2. import org.springframework.beans.factory.annotation.Autowired;

  3. import org.springframework.stereotype.Controller;

  4. import org.springframework.web.bind.annotation.*;

  5. import java.io.UnsupportedEncodingException;

  6. import java.util.*;

  7. @Controller

  8. @RequestMapping("/tools/script")

  9. public class BossToolsScriptController {

  10. @RequestMapping(value = "/get_all_project", method = RequestMethod.GET)

  11. @ResponseBody

  12. public ResultBean<Object> getAllProject(){

  13. }

  14. @GetMapping("/get_group_by_project")

  15. @ResponseBody

  16. public ResultBean<Object> getGroupByProject(@RequestParam(value = "project",required = true) String project){

  17. }

  18. @CrossOrigin

  19. @GetMapping("/get_script_by_name")

  20. @ResponseBody

  21. public ResultBean<Object> getScriptByName(@RequestParam(value = "script_name",required = true) String scriptName){

  22. }

  23. @RequestMapping(value = "/add_group", method = RequestMethod.POST)

  24. @ResponseBody

  25. public ResultBean<Object> addBossToolsScriptGroupBean(@RequestBody BossToolsScriptGroupBean groupInfo){

  26. }

  27. @GetMapping("/del_group")

  28. @ResponseBody

  29. public ResultBean<Object> delBossToolsScriptGroup(@RequestParam(value = "id",required = true) Integer id){

  30. }

  31. @GetMapping("/get_script_by_id")

  32. @ResponseBody

  33. public ResultBean<Object> selectScriptById(@RequestParam("project_id") Integer projectId){

  34. }

  35. @RequestMapping(value = "/add_script", method = RequestMethod.POST)

  36. @ResponseBody

  37. public ResultBean<Object> addScript(@RequestParam Map<String,Object> scriptInfo){

  38. }

  39. @GetMapping("/del_script")

  40. @ResponseBody

  41. public ResultBean<Object> delScript(@RequestParam("script_name") String scriptName){

  42. }

  43. @GetMapping("/get_all_script")

  44. @ResponseBody

  45. public ResultBean<Object> selectAllScript(){

  46. }

  47. @GetMapping("/get_script_by_author")

  48. @ResponseBody

  49. public ResultBean<Object> selectScriptByAuthor(@RequestParam("author") String author){

  50. }

  51. }

这样后端就开发完成了

脚本开发工具前端的开发
 
  1. <template>

  2. <el-container>

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

  4. <div class="one" v-if="isRouterAlive" >

  5. <vue-custom-scrollbar class="scroll-area" :settings="settings" >

  6. <el-menu mode="horizontal" >

  7. <el-submenu v-for="(item) in menu" :key="item.index" :index="item.id+ ''" style="padding-left: 1%">

  8. <template slot="title">{{item.label}}<svg-icon icon-class="dropdown"></svg-icon></template>

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

  10. </el-submenu>

  11. </el-menu>

  12. </vue-custom-scrollbar>

  13. </div>

  14. <div class="two" style="padding-top: 10px; padding-left: 30%">

  15. <el-tooltip class="item" effect="dark" content="首页:脚本开发工具的首页" placement="top-start">

  16. <el-button type="primary" icon="el-icon-s-home" circle @click="onEdit"></el-button>

  17. </el-tooltip>

  18. <el-tooltip class="item" effect="dark" content="添加脚本:编写完脚本记得在此处添加" placement="top-start">

  19. <el-button type="info" icon="el-icon-circle-plus-outline" circle @click="onAdd"></el-button>

  20. </el-tooltip>

  21. <el-tooltip class="item" effect="dark" content="编写脚本:可以在此处上传或者编写脚本" placement="top-start">

  22. <el-button type="warning" icon="el-icon-edit-outline" circle @click="onWrite"></el-button>

  23. </el-tooltip>

  24. <el-tooltip class="item" effect="dark" content="说明文档" placement="top-start">

  25. <el-button type="warning" icon="el-icon-question" circle @click="ondoc"></el-button>

  26. </el-tooltip>

  27. </div>

  28. </el-header>

  29. <div style= "background-color: #d7dee5; height: 3px; margin-top: 25px"> </div>

  30. <el-main>

  31. <div id="script" v-if="isShow ==1">

  32. <div class="body-content" style=";float:left;">

  33. <h3 style=" text-align: left; padding-bottom: 15px">执行脚本</h3>

  34. <el-form ref="runScriptForm" label-width="85px" :label-position="labelPosition">

  35. <el-form-item label="脚本名称:" style="margin-bottom: 10px; text-align: left">

  36. {{runScriptForm.scriptName}}

  37. </el-form-item>

  38. <el-form-item label="作者:" style=" margin-bottom: 10px; text-align: left">

  39. {{runScriptForm.author}}

  40. </el-form-item>

  41. <el-form-item label="功能介绍:" style="margin-bottom: 10px; text-align: left">

  42. {{runScriptForm.scriptFunction}}

  43. </el-form-item>

  44. <el-form-item label="参数说明:" style="margin-bottom: 10px; text-align: left">

  45. {{runScriptForm.runDesc}}

  46. </el-form-item>

  47. <el-form-item v-for="(item,i) in config" :key="i" :label="item.label">

  48. <el-input style="width: 500px" v-model="item.key"></el-input>

  49. <addUserId v-if="item.label === 'uid' || item.label === 'userId'" @updateUserId="updateUserId"></addUserId>

  50. </el-form-item>

  51. <el-form-item label-width="0px" style="text-align: left">

  52. <el-button type="success" size="medium" @click="run" :loading="loading">立即执行</el-button>

  53. </el-form-item>

  54. </el-form>

  55. <div style="padding-left: 5px">

  56. <span style=" font-size: 15px;font-weight: 400;color: #9fa3b0;">执行结果:<span :style="{color: color}">{{message}}</span></span>

  57. <div>

  58. <!-- text-align: left; word-wrap:break-word; word-break: break-all; overflow:auto;white-space: pre-wrap;-->

  59. <pre style="border:1px solid #9fa3b0;width:100%;height: 500px;font-size:15px;" placeholder="返回结果" v-html="syntaxHighlightTools(response)"></pre>

  60. </div>

  61. </div>

  62. </div>

  63. <div id="top">

  64. <div id="personal">

  65. <h3 style="font-size: 18px;line-height: 22px;"><svg-icon class="icon" icon-class="personal"></svg-icon>我开发的脚本</h3>

  66. <li class="tr">

  67. <div class="td1">序号</div>

  68. <div class="td1">名称</div>

  69. <div class="td1">功能</div>

  70. <div class="td1">操作</div>

  71. </li>

  72. <div v-if="showPersonalData ==false">

  73. <vue-custom-scrollbar class="presonal-scroll-area" :settings="personSettings" >

  74. <li class="ti" v-for="(item,i) in personal" :key="i">

  75. <div class="t2">{{item['id']}}</div>

  76. <div class="t2" @click="getScript(item['scriptName'])"><a>{{item['scriptName'] | ellipsis1}}</a></div>

  77. <div class="t2">{{item['scriptFunction'] | ellipsis}}</div>

  78. <div class="t2">

  79. <el-button type="text" class="el-icon-edit" @click="getEditScriptInfo(item['scriptName'])"></el-button>

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

  81. </div>

  82. <el-dialog title="编辑脚本配置" :visible.sync="dialogFormVisible" :modal-append-to-body=false>

  83. <el-form :model="editScriptForm">

  84. <el-form-item label="脚本名称:">

  85. {{editScriptForm.scriptName}}

  86. </el-form-item>

  87. <el-form-item label="功能介绍:">

  88. <el-input v-model="editScriptForm.scriptFunction" placeholder="可以添加一些脚本具体的用途和一些描述信息" autocomplete="off"></el-input>

  89. </el-form-item>

  90. <el-form-item label="参数说明:">

  91. <el-input v-model="editScriptForm.runDesc" placeholder="可以添加一些执行参数的描述信息" autocomplete="off"></el-input>

  92. </el-form-item>

  93. <el-form-item label="参数:" label-width="70px">

  94. <el-input v-model="editScriptForm.config" placeholder="脚本参数名称列表,例如env,uid,中间用,分割如果没有请输入 无" autocomplete="off"></el-input>

  95. </el-form-item>

  96. </el-form>

  97. <div slot="footer" class="dialog-footer">

  98. <el-button @click="dialogFormVisible = false">取 消</el-button>

  99. <el-button type="primary" @click="editScript">确 定</el-button>

  100. </div>

  101. </el-dialog>

  102. </li>

  103. </vue-custom-scrollbar>

  104. </div>

  105. <div class="data" v-else-if="showPersonalData == true">

  106. <svg-icon class="icon1" icon-class="dataNull"></svg-icon>

  107. <p class="null">暂无数据</p>

  108. </div>

  109. </div>

  110. <div id="ranking">

  111. <h3 style="font-size: 18px;line-height: 22px;"><svg-icon class="icon" icon-class="top"></svg-icon>排行榜</h3>

  112. <li class="tr">

  113. <div class="td">名次</div>

  114. <div class="td">名称</div>

  115. <div class="td">执行次数</div>

  116. <div class="td">功能</div>

  117. </li>

  118. <div v-if="showData ==false">

  119. <vue-custom-scrollbar class="ranking-scroll-area" :settings="personSettings" >

  120. <li class="ti" v-for="(item,i) in topOne" :key="i">

  121. <div class="t1">{{item['ranking']}}</div>

  122. <div class="t1" @click="getScript(item['scriptName'])"><a>{{item['scriptName'] | ellipsis1}}</a></div>

  123. <div class="t1">{{item['runTime']}}</div>

  124. <div class="t1">{{item['scriptFunction'] | ellipsis}}</div>

  125. </li>

  126. </vue-custom-scrollbar>

  127. </div>

  128. <div class="data" v-else-if="showData == true">

  129. <svg-icon class="icon" icon-class="dataNull"></svg-icon>

  130. <p class="null">暂无数据</p>

  131. </div>

  132. </div>

  133. </div>

  134. </div>

  135. <div id="edit" v-if="isShow == 2" >

  136. <div class="body-content" >

  137. <h3 style=" text-align: left; padding-bottom: 15px">添加脚本</h3>

  138. <el-form ref="form" :model="addScriptForm" label-width="80px" :label-position="labelPosition">

  139. <el-form-item label="脚本名称">

  140. <el-input v-model="addScriptForm.scriptName" placeholder="脚本名称,注:加后缀名"></el-input>

  141. </el-form-item>

  142. <el-form-item label="脚本目录">

  143. <el-select v-model="addScriptForm.project" placeholder="请选择项目" style="width: 500px">

  144. <el-option v-for="(item,index) in projectOptions" :key="index" :label="item" :value="item"></el-option>

  145. </el-select>

  146. </el-form-item>

  147. <el-form-item label="脚本功能">

  148. <el-input v-model="addScriptForm.scriptFunction" placeholder="可以添加一些脚本具体的用途和一些描述信息"></el-input>

  149. </el-form-item>

  150. <el-form-item label="执行描述">

  151. <el-input v-model="addScriptForm.runDesc" placeholder="可以添加一些执行参数的描述信息"></el-input>

  152. </el-form-item>

  153. <el-form-item label="依赖路径">

  154. <el-input v-model="addScriptForm.relyPath" placeholder="脚本所依赖文件的目录,没有填 无"></el-input>

  155. </el-form-item>

  156. <el-form-item label="参数列表">

  157. <el-input type="textarea" v-model="addScriptForm.config" placeholder="脚本参数名称列表,例如env,uid,中间用,分割如果没有请输入 无" style="width: 500px"></el-input>

  158. </el-form-item>

  159. <el-form-item label-width="0px" style="text-align: left">

  160. <el-button type="primary" @click="addScript">立即添加</el-button>

  161. </el-form-item>

  162. </el-form>

  163. </div>

  164. </div>

  165. <div id="frame" v-if="isShow ==4">

  166. <iframe

  167. :style="autoHeight"

  168. src="http://192.168.18.220:7777/lab" >

  169. </iframe>

  170. </div>

  171. <div id="frame" v-if="isShow ==5">

  172. <iframe

  173. :style="autoHeight"

  174. src="http://192.168.18.220:3000" >

  175. </iframe>

  176. </div>

  177. </el-main>

  178. </el-container>

  179. </template>

  180. <script>

  181. import {

  182. addScript,

  183. getScriptGroup,

  184. runScript,

  185. getProject,

  186. getScriptByName,

  187. delScript,

  188. getAllScript,

  189. getScriptByAuthor, editScript

  190. } from '@/api/zpTools/tools'

  191. import { syntaxHighlight } from '@/utils/apiUtil'

  192. import addUserId from '@/views/zpTools/other/captureAndMock/addUserId'

  193. import vueCustomScrollbar from 'vue-custom-scrollbar'

  194. import "vue-custom-scrollbar/dist/vueScrollbar.css"

  195. export default {

  196. name: "scriptManger",

  197. components: {

  198. addUserId,

  199. vueCustomScrollbar

  200. },

  201. data() {

  202. return {

  203. labelPosition:'left',

  204. dialogFormVisible:false,

  205. isShow: 1,

  206. form:[],

  207. settings: {

  208. suppressScrollY: true,

  209. suppressScrollX: false,

  210. wheelPropagation: false

  211. },

  212. personSettings: {

  213. suppressScrollY: false,

  214. suppressScrollX: true,

  215. wheelPropagation: false

  216. },

  217. showData: false,

  218. showPersonalData:false,

  219. icon:'top',

  220. color:'green',

  221. isRouterAlive: true,

  222. iframeLoading: false,

  223. topOne:[],

  224. personal:[],

  225. scriptTime:{},

  226. editScriptForm:{

  227. scriptName:'',

  228. runDesc:'',

  229. scriptFunction:'',

  230. config:'',

  231. },

  232. runScriptForm:{

  233. scriptName:'',

  234. author:'',

  235. runDesc:'',

  236. scriptFunction:'',

  237. config:'',

  238. },

  239. response:'',

  240. message:'',

  241. loading: false,

  242. addScriptForm: {

  243. scriptName: '',

  244. project:'',

  245. scriptFunction: '',

  246. runDesc: '',

  247. address: '',

  248. relyPath: '',

  249. config: '',

  250. author: this.$store.state.user.name,

  251. status:1,

  252. runTime:0

  253. },

  254. config:[],

  255. projectOptions:[],

  256. menu:[],

  257. userId:'',

  258. clientHeight: '',

  259. autoHeight:{

  260. width:'100%',

  261. overflow: 'auto',

  262. height:'400px',

  263. }

  264. };

  265. },

  266. watch: {

  267. // 如果 clientHeight 发生改变,这个函数就会运行

  268. clientHeight() {

  269. this.changeFixed(this.clientHeight);

  270. }

  271. },

  272. mounted() {

  273. //获取脚本信息

  274. this.getMenu()

  275. this.getProject()

  276. this.getAllScript()

  277. this.getScriptPersonal()

  278. this.config = this.$store.state.tools.paramConfig

  279. // 获取浏览器可视区域高度

  280. this.clientHeight = document.documentElement.clientHeight; // document.body.clientWidth;

  281. window.onresize = function temp() { // 在窗口或框架被调整大小时触发

  282. this.clientHeight = document.documentElement.clientHeight;

  283. };

  284. },

  285. methods: {

  286. // 根据屏幕高度动态修改iframe 样式

  287. changeFixed(clientHeight) { // 动态修改样式

  288. this.autoHeight.height = clientHeight + 'px';

  289. },

  290. updateUserId (userId) {

  291. this.userId = userId

  292. this.getScript(this.runScriptForm.scriptName)

  293. this.$store.commit('tools/setRappPackageUserId', this.userId);

  294. },

  295. handleSelect(key, keyPath) {

  296. },

  297. async getScriptPersonal(){

  298. const result = await getScriptByAuthor(this.$store.state.user.name)

  299. if (result['data'].length == 0){

  300. this.showPersonalData = true

  301. }else {

  302. for(let i in result['data']){

  303. let top = {

  304. id:'',

  305. scriptName:'',

  306. scriptFunction:'',

  307. }

  308. top.id = +i +1

  309. top.scriptFunction = result["data"][i]["scriptFunction"]

  310. top.scriptName = result["data"][i]["scriptName"]

  311. this.personal.push(top)

  312. }

  313. }

  314. },

  315. async getAllScript(){

  316. const result = await getAllScript();

  317. if (result['data'].length == 0){

  318. this.showData = true

  319. }

  320. else {

  321. for(let i in result['data']){

  322. let top = {

  323. ranking:'',

  324. scriptName:'',

  325. scriptFunction:'',

  326. runTime:''

  327. }

  328. top.ranking = +i +1

  329. top.scriptFunction = result["data"][i]["scriptFunction"]

  330. top.scriptName = result["data"][i]["scriptName"]

  331. top.runTime = result["data"][i]["runTime"]

  332. this.topOne.push(top)

  333. this.scriptTime[result["data"][i]["scriptName"]] = result["data"][i]["runTime"]

  334. }

  335. await this.getScript(result['data'][0]['scriptName'])

  336. }

  337. },

  338. //获取编辑脚本

  339. async getEditScriptInfo(name){

  340. this.dialogFormVisible = true

  341. const result = await getScriptByName(name);

  342. this.editScriptForm.scriptName = result["data"][0]["scriptName"]

  343. this.editScriptForm.config = result["data"][0]["config"]

  344. this.editScriptForm.scriptFunction = result["data"][0]["scriptFunction"]

  345. this.editScriptForm.runDesc = result["data"][0]["runDesc"]

  346. },

  347. //编辑脚本

  348. async editScript(name){

  349. this.dialogFormVisible = false

  350. const result = await editScript(this.editScriptForm);

  351. if(result['status'] === 'success'){

  352. this.$message({

  353. message: '编辑成功',

  354. type: 'success'

  355. });

  356. }

  357. },

  358. //获取默认脚本信息

  359. async getScript(name){

  360. const result = await getScriptByName(name);

  361. this.runScriptForm.scriptName = result["data"][0]["scriptName"]

  362. this.runScriptForm.author = result["data"][0]["author"]

  363. this.runScriptForm.scriptFunction = result["data"][0]["scriptFunction"]

  364. this.runScriptForm.runDesc = result["data"][0]["runDesc"]

  365. if( result["data"][0]["config"] === "无" ){

  366. this.config = []

  367. }

  368. else {

  369. this.config = []

  370. let str = result["data"][0]["config"]

  371. let str1 = str.split(',')

  372. let dict = {}

  373. for(let i in str1){

  374. dict['label'] = str1[i]

  375. if (str1[i] === 'uid' ||str1[i] === 'userId'){

  376. dict['key'] = this.userId

  377. }else {

  378. dict['key'] = ''

  379. }

  380. // dict['key'] = ''

  381. this.config.push(dict)

  382. dict = {}

  383. }

  384. // this.config = this.$store.state.tools.paramConfig

  385. }

  386. this.isShow = 1

  387. },

  388. async getProject(){

  389. const result = await getProject()

  390. this.projectOptions = result.data

  391. },

  392. async getMenu(){

  393. const result = await getScriptGroup()

  394. this.menu = result.data

  395. },

  396. async run(){

  397. // this.$store.commit("tools/setParamConfig", this.config)

  398. this.loading = true;

  399. for (let i in this.config){

  400. this.runScriptForm.scriptPram +=this.config[i]["key"]+" "

  401. }

  402. if(this.runScriptForm.scriptPram){

  403. console.log(this.runScriptForm.scriptPram.replace(/undefined/,''))

  404. this.runScriptForm.scriptPram = this.runScriptForm.scriptPram.replace(/undefined/,'')

  405. }

  406. this.runScriptForm.runTime = +this.scriptTime[this.runScriptForm.scriptName] +1

  407. const result = await runScript(this.runScriptForm);

  408. this.response = JSON.stringify(result)

  409. this.message = result['message']

  410. this.runScriptForm.scriptPram = ''

  411. this.loading = false;

  412. this.reload()

  413. },

  414. async addScript(){

  415. this.addScriptForm.address = this.addScriptForm.project

  416. const result = await addScript(this.addScriptForm);

  417. await this.getMenu();

  418. if (result["message"] === "success"){

  419. await this.$alert('脚本添加成功', 'message', {

  420. confirmButtonText: '确定'

  421. });

  422. }else {

  423. await this.$alert('脚本添加失败', 'message', {

  424. confirmButtonText: '确定'

  425. });

  426. }

  427. this.reload()

  428. this.isShow = 1

  429. },

  430. onEdit(){

  431. this.isShow = 1

  432. },

  433. onAdd(){

  434. this.isShow = 2

  435. },

  436. onDelete(scriptName){

  437. this.isShow = 1

  438. this.$confirm('确定要删除%s脚本吗?'.replace('%s',this.runScriptForm.scriptName), '提示', {

  439. confirmButtonText: '确定',

  440. cancelButtonText: '取消',

  441. type: 'warning'

  442. }).then(() => {

  443. delScript(scriptName)

  444. this.$message("%s删除成功".replace('%s',this.runScriptForm.scriptName))

  445. this.getMenu()

  446. this.reload()

  447. this.getScript("crm_push_msg.py")

  448. }).catch(() => {

  449. this.$message({

  450. type: 'info',

  451. message: '已取消删除'

  452. });

  453. });

  454. },

  455. onWrite(){

  456. this.isShow = 4

  457. },

  458. ondoc(){

  459. this.isShow = 5

  460. },

  461. syntaxHighlightTools (jsonString) {

  462. try {

  463. console.log(typeof jsonString)

  464. let obj = JSON.parse(jsonString);

  465. if(typeof obj == 'object' && jsonString ) {

  466. return syntaxHighlight(JSON.stringify(obj, undefined, 2));

  467. }else {

  468. }

  469. } catch (ex) {

  470. return jsonString;

  471. }

  472. },

  473. //无感知刷新

  474. reload() {

  475. this.isRouterAlive = false;

  476. this.$nextTick(function () {

  477. this.isRouterAlive = true;

  478. });

  479. },

  480. },

  481. filters:{

  482. ellipsis(value){

  483. if (!value) return '';

  484. if (value.length > 9) {

  485. return value.slice(0,9) + '...'

  486. }

  487. return value

  488. },

  489. ellipsis1(value){

  490. if (!value) return '';

  491. if (value.length > 15) {

  492. return value.slice(0,15) + '...'

  493. }

  494. return value

  495. }

  496. }

  497. }

  498. </script>

  499. <style scoped>

  500. /*省略*/

  501. </style>

前端页面的展示

添加脚本页面

脚本编辑页面

执行脚本页面

写着最后

整个的脚本开发工具就设计好了,这样不仅能提高测试人员的工作效率,而且可以通过脚本的编写提高测试团队的技术氛围,大家可以尝试下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值