Authored by zhengyouwei

项目发布增加自动测试

  1 +package com.ui.model.req;
  2 +
  3 +import lombok.Data;
  4 +
  5 +/**
  6 + * Created by zhengyouwei on 2016/11/28.
  7 + */
  8 +@Data
  9 +public class AutoTestReq {
  10 +
  11 + private String taskname;
  12 +
  13 + private String env;
  14 +
  15 + private String models;
  16 +
  17 + private String branch;
  18 +
  19 + private int proId;
  20 +
  21 + private int versionId;
  22 +
  23 + private String mailto;
  24 +
  25 +}
@@ -8,6 +8,7 @@ import com.ui.model.domain.BuildMessage; @@ -8,6 +8,7 @@ import com.ui.model.domain.BuildMessage;
8 import com.ui.model.req.*; 8 import com.ui.model.req.*;
9 import com.ui.project.ProjectEnvironment; 9 import com.ui.project.ProjectEnvironment;
10 import com.ui.project.ProjectOnline; 10 import com.ui.project.ProjectOnline;
  11 +import org.apache.commons.lang.RandomStringUtils;
11 import org.slf4j.Logger; 12 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory; 13 import org.slf4j.LoggerFactory;
13 import org.springframework.beans.factory.annotation.Autowired; 14 import org.springframework.beans.factory.annotation.Autowired;
@@ -17,6 +18,7 @@ import org.springframework.web.bind.annotation.*; @@ -17,6 +18,7 @@ import org.springframework.web.bind.annotation.*;
17 import org.springframework.web.servlet.ModelAndView; 18 import org.springframework.web.servlet.ModelAndView;
18 19
19 import javax.servlet.http.HttpSession; 20 import javax.servlet.http.HttpSession;
  21 +import java.text.SimpleDateFormat;
20 import java.util.*; 22 import java.util.*;
21 23
22 /** 24 /**
@@ -142,12 +144,12 @@ public class ProjectBuildCtrl { @@ -142,12 +144,12 @@ public class ProjectBuildCtrl {
142 if ("Deploy".equals(operate_name)) { 144 if ("Deploy".equals(operate_name)) {
143 String[] array = project_name.split(","); 145 String[] array = project_name.split(",");
144 if (array.length > 4) { 146 if (array.length > 4) {
145 - String[] newArray = new String[]{"","","",""}; 147 + String[] newArray = new String[]{"", "", "", ""};
146 for (int i = 0; i < array.length; i++) { 148 for (int i = 0; i < array.length; i++) {
147 - newArray[i%4] = newArray[i%4] + array[i] + ","; 149 + newArray[i % 4] = newArray[i % 4] + array[i] + ",";
148 } 150 }
149 for (String project : newArray) { 151 for (String project : newArray) {
150 - buildRequest.setProject(project.substring(0,project.length() - 1)); 152 + buildRequest.setProject(project.substring(0, project.length() - 1));
151 BuildMessage buildMessage = httpRestClient.post(ProjectEnvironment.getUrl(environment_name) + "build", buildRequest, BuildMessage.class); 153 BuildMessage buildMessage = httpRestClient.post(ProjectEnvironment.getUrl(environment_name) + "build", buildRequest, BuildMessage.class);
152 if (buildMessage != null) { 154 if (buildMessage != null) {
153 list.add(buildMessage); 155 list.add(buildMessage);
@@ -275,4 +277,37 @@ public class ProjectBuildCtrl { @@ -275,4 +277,37 @@ public class ProjectBuildCtrl {
275 return response; 277 return response;
276 } 278 }
277 279
  280 + @RequestMapping("/aototest/autoTestService")
  281 + @ResponseBody
  282 + public BaseResponse autoTestService(String models, String branch, HttpSession session) {
  283 + User user = (User) session.getAttribute("user");
  284 + AutoTestReq autoTestReq = new AutoTestReq();
  285 + String id = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + RandomStringUtils.randomNumeric(6);
  286 + autoTestReq.setTaskname(id);
  287 + autoTestReq.setEnv("5");
  288 + autoTestReq.setModels(models.substring(0, models.length() - 1));
  289 + autoTestReq.setBranch(branch);
  290 + autoTestReq.setProId(0);
  291 + autoTestReq.setVersionId(0);
  292 + autoTestReq.setMailto(user.getEmail());
  293 + BaseResponse baseResponse = httpRestClient.post("http://qmc.yohops.com:9999/autotest/autoTestService", autoTestReq, BaseResponse.class);
  294 + System.out.println(id);
  295 + return baseResponse;
  296 + }
  297 +
  298 + @RequestMapping("/aototest/getAutoTestResult")
  299 + @ResponseBody
  300 + public BaseResponse getAutoTestResult(String id) {
  301 + AutoTestReq autoTestReq = new AutoTestReq();
  302 + autoTestReq.setTaskname(id);
  303 + BaseResponse baseResponse = httpRestClient.post("http://qmc.yohops.com:9999/autotest/getAutoTestResult", autoTestReq, BaseResponse.class);
  304 + return baseResponse;
  305 + }
  306 +
  307 + @RequestMapping("/aototest/toAutoTestResult")
  308 + public ModelAndView toAutoTestResult(String id,Model model) {
  309 + model.addAttribute("id",id);
  310 + return new ModelAndView("project/autotestresult");
  311 + }
  312 +
278 } 313 }
  1 +<%@page language="java" contentType="text/html;charset=utf-8" %>
  2 +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  3 +<%
  4 + String path = request.getContextPath();
  5 + String basePath = request.getScheme() + "://"
  6 + + request.getServerName() + ":" + request.getServerPort()
  7 + + path + "/";
  8 +%>
  9 +
  10 +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  11 +<html>
  12 +<head>
  13 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  14 +
  15 + <link rel="stylesheet" href="<%=basePath %>css/bootstrap.min.css"/>
  16 + <link rel="stylesheet" href="<%=basePath %>css/bootstrap-responsive.min.css"/>
  17 + <link rel="stylesheet" href="<%=basePath %>css/jquery.gritter.css"/>
  18 + <link rel="stylesheet" href="<%=basePath %>css/jquery-ui.css"/>
  19 +
  20 + <script src="<%=basePath %>js/excanvas.min.js" charset="UTF-8" type="text/javascript"></script>
  21 + <script src="<%=basePath %>js/jquery-1.12.0.min.js" charset="UTF-8" type="text/javascript"></script>
  22 + <script src="<%=basePath %>js/jquery-ui.custom.js" charset="UTF-8" type="text/javascript"></script>
  23 + <script src="<%=basePath %>/js/bootstrap.min.js"></script>
  24 + <script src="<%=basePath %>/js/unicorn.js"></script>
  25 + <script src="<%=basePath %>js/bootstrap-plugin/datetimepicker/moment-with-locales.js" charset="UTF-8"
  26 + type="text/javascript"></script>
  27 + <script src="<%=basePath %>js/bootstrap-plugin/datetimepicker/bootstrap-datetimepicker.js" charset="UTF-8"
  28 + type="text/javascript"></script>
  29 + <script src="<%=basePath %>js/global.js" charset="UTF-8" type="text/javascript"></script>
  30 + <script src="<%=basePath %>js/bootstrap-plugin/bootstrap.pagination.js" charset="UTF-8"
  31 + type="text/javascript"></script>
  32 + <script src="<%=basePath %>js/bootstrap-plugin/bootstrap.table.js" charset="UTF-8" type="text/javascript"></script>
  33 + <script src="<%=basePath %>js/bootstrap-plugin/bootstrap.dialog.js" charset="UTF-8" type="text/javascript"></script>
  34 + <script src="<%=basePath %>js/bootstrap-plugin/bootstrap.form.js" charset="UTF-8" type="text/javascript"></script>
  35 + <script src="<%=basePath %>js/bootstrap-plugin/bootstrap.panel.js" charset="UTF-8" type="text/javascript"></script>
  36 + <script src="<%=basePath %>js/bootstrap-plugin/bootstrap.alerts.js" charset="UTF-8" type="text/javascript"></script>
  37 + <script src="<%=basePath %>js/bootstrap-plugin/bootstrap.accordion.js" charset="UTF-8"
  38 + type="text/javascript"></script>
  39 + <script src="<%=basePath %>js/bootstrap-plugin/bootstrap.breadcrumb.js" charset="UTF-8"
  40 + type="text/javascript"></script>
  41 + <script src="<%=basePath %>js/bootstrap-plugin/bootstrap.validate.js" charset="UTF-8"
  42 + type="text/javascript"></script>
  43 + <script src="<%=basePath %>js/bootstrap-plugin/bootstrap.form.js" charset="UTF-8" type="text/javascript"></script>
  44 + <script src="<%=basePath %>js/layer/layer.js" charset="UTF-8" type="text/javascript"></script>
  45 + <script src="<%=basePath %>js/bootstrap-plugin/bootstrap.select.js" charset="UTF-8" type="text/javascript"></script>
  46 + <script src="<%=basePath %>js/jstree/jstree.min.js"></script>
  47 + <script src="<%=basePath %>js/jquery.toaster.js"></script>
  48 + <script src="<%=basePath %>js/jquery.gritter.min.js"></script>
  49 + <script>
  50 + var contextPath = '<%=basePath %>';
  51 + </script>
  52 + <title>YOHO!运维</title>
  53 +</head>
  54 +<body >
  55 +<!-- 右侧具体内容 -->
  56 +
  57 +<input type="hidden" id="hidden_id" value="${id}">
  58 +<div>
  59 + <br/>
  60 + <br/>
  61 + <br/>
  62 + <br/>
  63 + <span>
  64 + tips:测试结果正在获取中,请不要关闭页面。或者您也可以等待邮件,邮件稍后会发送到您的邮箱!
  65 +
  66 + </span>
  67 +</div>
  68 +
  69 +<div id="infoTable">
  70 +</div>
  71 +
  72 +</body>
  73 +<script>
  74 +
  75 + $(function () {
  76 + var jq = $("#infoTable");
  77 + var id = $("#hidden_id").val();
  78 + var tableParam = {
  79 + columnAutoWidth: false,
  80 + url: contextPath + "project/aototest/getAutoTestResult?id=" + id,
  81 + striped: true,
  82 + title: "自动测试结果",
  83 + dataType: "json",
  84 + beforeSend:function(){
  85 + var div = $("<div>").attr("tableSelector", jq.selector).addClass("modal-backdrop fade in").appendTo($("body")).hide();
  86 + var tableOffset = jq.offset();
  87 + var tableWidth = jq.outerWidth(true), tableHeight = jq.outerHeight(true);
  88 + div.append($("<div>").addClass("table-loading").css({
  89 + left : (tableWidth - 124) / 2,
  90 + top : (tableHeight - 124) / 2
  91 + }));
  92 + div.css({
  93 + width : tableWidth,
  94 + height : tableHeight,
  95 + left : tableOffset.left,
  96 + top : tableOffset.top
  97 + });
  98 + div.show();
  99 + },
  100 + loadFilter: function (data) {
  101 + $("body").find("div[tableSelector='"+ jq.selector +"']").remove();
  102 + if (!data || data.code != 200) {
  103 + return [];
  104 + }else{
  105 + clearInterval(interval);
  106 + }
  107 + return data.data.autotestRunCollections;
  108 + },
  109 + onLoadSuccess: function (data) {
  110 + },
  111 + columns: [{
  112 + title: "版本号",
  113 + field: "versionId",
  114 + width: "10%"
  115 + }, {
  116 + title: "执行集名称",
  117 + field: "runCollectionName",
  118 + width: "10%"
  119 + }, {
  120 + title: "总数",
  121 + field: "testcaseTotal",
  122 + width: "10%"
  123 + },{
  124 + title: "运行时间",
  125 + field: "totalTime",
  126 + width: "10%"
  127 + },{
  128 + title: "成功",
  129 + field: "testcaseSuccess",
  130 + width: "10%"
  131 + },{
  132 + title: "失败",
  133 + field: "testcaseFailures",
  134 + width: "10%"
  135 + },{
  136 + title: "错误",
  137 + field: "testcaseErrors",
  138 + width: "10%"
  139 + },{
  140 + title: "跳过 ",
  141 + field: "testcaseSkips",
  142 + width: "10%"
  143 + }
  144 + ]
  145 + };
  146 + $("#infoTable").table(tableParam);
  147 +
  148 + var interval = setInterval(function () {//查后台,展示数据
  149 + $("#infoTable").table(tableParam);
  150 + }, 5000);
  151 +
  152 + });
  153 +
  154 +</script>
  155 +
  156 +<script>
  157 + document.onkeydown = function()
  158 + {
  159 + if(event.keyCode==116 || event.keyCode==8 || (event.ctrlKey && event.keyCode==82) || event.keyCode == 13) {
  160 + event.keyCode=0;
  161 + event.returnValue = false;
  162 + }
  163 + }
  164 + document.oncontextmenu = function() {event.returnValue = false;}
  165 +
  166 +</script>
@@ -39,7 +39,7 @@ @@ -39,7 +39,7 @@
39 <div class="form-group"> 39 <div class="form-group">
40 <label class="col-sm-1 control-label">操作选择</label> 40 <label class="col-sm-1 control-label">操作选择</label>
41 41
42 - <div class="col-sm-8"> 42 + <div class="col-sm-8" style="display: inline">
43 <div class="rdio rdio-default"> 43 <div class="rdio rdio-default">
44 <input type="radio" name="operate" id="operatedeploy" value="Deploy" checked="checked" 44 <input type="radio" name="operate" id="operatedeploy" value="Deploy" checked="checked"
45 onclick="operateChange()"/> 45 onclick="operateChange()"/>
@@ -51,6 +51,9 @@ @@ -51,6 +51,9 @@
51 <label for="operateback">回滚</label> 51 <label for="operateback">回滚</label>
52 </div> 52 </div>
53 </div> 53 </div>
  54 + <div id="autotest-div">
  55 + <input type="button" class="btn btn-primary" id="autotest-button" onclick="autotest()" value="执行自动测试用例" </input>
  56 + </div>
54 </div> 57 </div>
55 58
56 <div class="form-group"> 59 <div class="form-group">
@@ -72,10 +72,8 @@ @@ -72,10 +72,8 @@
72 var removeArray = new Array(); 72 var removeArray = new Array();
73 73
74 $(function () { 74 $(function () {
  75 + var interval;
75 var ip = $("#hidden_ip").val(); 76 var ip = $("#hidden_ip").val();
76 - var cloud = $("#hidden_cloud").val();  
77 - var exe = $("#hidden_exe").val();  
78 - var project = $("#hidden_project").val();  
79 var tableParam = { 77 var tableParam = {
80 columnAutoWidth: false, 78 columnAutoWidth: false,
81 url: contextPath + "/javaRestart/stopOrRestart", 79 url: contextPath + "/javaRestart/stopOrRestart",
@@ -86,10 +84,7 @@ @@ -86,10 +84,7 @@
86 return defaultLoadFilter(data); 84 return defaultLoadFilter(data);
87 }, 85 },
88 onLoadSuccess: function (data) { 86 onLoadSuccess: function (data) {
89 - $.each(data, function (idx, val) {  
90 - myArray[idx] = val.id;  
91 - });  
92 - setStatus(); 87 + clearInterval(interval);
93 }, 88 },
94 columns: [{ 89 columns: [{
95 title: "项目名称", 90 title: "项目名称",
@@ -132,15 +127,9 @@ @@ -132,15 +127,9 @@
132 127
133 //加载表格 128 //加载表格
134 $("#infoTable").table(tableParam); 129 $("#infoTable").table(tableParam);
135 - $("#infoTable").table("load", {  
136 - 'ip': ip,  
137 - 'cloud': cloud,  
138 - 'exe': exe,  
139 - 'project': project  
140 - });  
141 130
142 - var interval = setInterval(function () {//查后台,展示数据  
143 - setStatus(); 131 + interval = setInterval(function () {//查后台,展示数据
  132 + $("#infoTable").table("load");
144 }, 3000); 133 }, 3000);
145 134
146 }); 135 });
@@ -13,12 +13,16 @@ function operateChange() { @@ -13,12 +13,16 @@ function operateChange() {
13 document.getElementById("branch-div").style.display = "none"; 13 document.getElementById("branch-div").style.display = "none";
14 //展示 回滚选择框 14 //展示 回滚选择框
15 document.getElementById("rollback-div").style.display = ""; 15 document.getElementById("rollback-div").style.display = "";
  16 + //隐藏自动执行测试用例
  17 + document.getElementById("autotest-div").style.display = "none";
  18 +
16 } else { 19 } else {
17 //展示Branch输入框 20 //展示Branch输入框
18 document.getElementById("branch-div").style.display = ""; 21 document.getElementById("branch-div").style.display = "";
19 //隐藏 回滚选择框 22 //隐藏 回滚选择框
20 document.getElementById("rollback-div").style.display = "none"; 23 document.getElementById("rollback-div").style.display = "none";
21 - 24 + //展示自动执行测试用例
  25 + document.getElementById("autotest-div").style.display = "";
22 } 26 }
23 } 27 }
24 28
@@ -278,7 +282,54 @@ function branchdefault() { @@ -278,7 +282,54 @@ function branchdefault() {
278 } 282 }
279 } 283 }
280 284
  285 +function autotest(){
  286 + var environment = $("input[name='environments']:checked").val();
  287 + if("qcloud_gray" == environment){
  288 + alert("灰度环境不支持测试用例执行");
  289 + return;
  290 + }
  291 + var projects = new Array();
  292 + $('input[name="project1"]:checked').each(function () {
  293 + projects.push($(this).val());//向数组中添加元素
  294 + });
  295 + $('input[name="project2"]:checked').each(function () {
  296 + projects.push($(this).val());//向数组中添加元素
  297 + });
  298 + $('input[name="project3"]:checked').each(function () {
  299 + projects.push($(this).val());//向数组中添加元素
  300 + });
  301 + if (projects.length == 0) {
  302 + alert("请选择项目");
  303 + return;
  304 + }
  305 + var branch = $("input[name='branch']").val();
  306 + if (branch == "") {
  307 + alert("请填写分支名称");
  308 + return;
  309 + }
281 310
  311 + $.ajax({
  312 + url: 'aototest/autoTestService?models=' + projects + "&branch=" + branch,
  313 + type: 'POST',
  314 + dataType: 'json',
  315 + success: function (data) {
  316 + console.log(data);
  317 + if(data.code != 200){
  318 + alert(data.message);
  319 + }else{
  320 + var iWidth = 900;
  321 + var iHeight = 600;
  322 + var iTop = (window.screen.availHeight - 30 - iHeight) / 2; //获得窗口的垂直位置;
  323 + var iLeft = (window.screen.availWidth - 10 - iWidth) / 2; //获得窗口的水平位置;
  324 + window.open("aototest/toAutoTestResult?id=" + data.data.taskname, "_blank", "height=" + iHeight + ", width=" + iWidth + ", top=" + iTop + ", left=" + iLeft);
  325 + }
  326 + },
  327 + error: function (e) {
  328 + alert("系统错误");
  329 + }
  330 + });
  331 +
  332 +}
282 333
283 334
284 335