api测试,未完待续
This commit is contained in:
parent
8dc3249347
commit
6aa69cee66
|
@ -57,6 +57,11 @@
|
||||||
<artifactId>spring-boot-starter-jetty</artifactId>
|
<artifactId>spring-boot-starter-jetty</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mybatis.spring.boot</groupId>
|
<groupId>org.mybatis.spring.boot</groupId>
|
||||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package io.metersphere.api.controller;
|
||||||
|
|
||||||
|
import com.github.pagehelper.Page;
|
||||||
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import io.metersphere.api.dto.APITestResult;
|
||||||
|
import io.metersphere.api.dto.DeleteAPITestRequest;
|
||||||
|
import io.metersphere.api.dto.QueryAPITestRequest;
|
||||||
|
import io.metersphere.api.dto.SaveAPITestRequest;
|
||||||
|
import io.metersphere.api.service.ApiTestService;
|
||||||
|
import io.metersphere.base.domain.ApiTestWithBLOBs;
|
||||||
|
import io.metersphere.commons.constants.RoleConstants;
|
||||||
|
import io.metersphere.commons.utils.PageUtils;
|
||||||
|
import io.metersphere.commons.utils.Pager;
|
||||||
|
import io.metersphere.service.FileService;
|
||||||
|
import io.metersphere.user.SessionUtils;
|
||||||
|
import org.apache.shiro.authz.annotation.Logical;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(value = "/api")
|
||||||
|
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR)
|
||||||
|
public class APITestController {
|
||||||
|
@Resource
|
||||||
|
private ApiTestService apiTestService;
|
||||||
|
@Resource
|
||||||
|
private FileService fileService;
|
||||||
|
|
||||||
|
@GetMapping("recent/{count}")
|
||||||
|
public List<APITestResult> recentTest(@PathVariable int count) {
|
||||||
|
String currentWorkspaceId = SessionUtils.getCurrentWorkspaceId();
|
||||||
|
QueryAPITestRequest request = new QueryAPITestRequest();
|
||||||
|
request.setWorkspaceId(currentWorkspaceId);
|
||||||
|
PageHelper.startPage(1, count, true);
|
||||||
|
return apiTestService.recentTest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/list/{goPage}/{pageSize}")
|
||||||
|
public Pager<List<APITestResult>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryAPITestRequest request) {
|
||||||
|
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
||||||
|
request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||||
|
return PageUtils.setPageInfo(page, apiTestService.list(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/save")
|
||||||
|
public String save(@RequestBody SaveAPITestRequest request) {
|
||||||
|
return apiTestService.save(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get/{testId}")
|
||||||
|
public ApiTestWithBLOBs get(@PathVariable String testId) {
|
||||||
|
return apiTestService.get(testId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/delete")
|
||||||
|
public void delete(@RequestBody DeleteAPITestRequest request) {
|
||||||
|
apiTestService.delete(request);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// @PostMapping("/run")
|
||||||
|
// public void run(@RequestBody RunTestPlanRequest request) {
|
||||||
|
// apiTestService.run(request);
|
||||||
|
// }
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package io.metersphere.api.dto;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.ApiTestWithBLOBs;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class APITestResult extends ApiTestWithBLOBs {
|
||||||
|
|
||||||
|
private String projectName;
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package io.metersphere.api.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class DeleteAPITestRequest {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package io.metersphere.api.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class QueryAPITestRequest {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String projectId;
|
||||||
|
private String name;
|
||||||
|
private String workspaceId;
|
||||||
|
private boolean recent = false;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package io.metersphere.api.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class SaveAPITestRequest {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String scenarioDefinition;
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
package io.metersphere.api.service;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.APITestResult;
|
||||||
|
import io.metersphere.api.dto.DeleteAPITestRequest;
|
||||||
|
import io.metersphere.api.dto.QueryAPITestRequest;
|
||||||
|
import io.metersphere.api.dto.SaveAPITestRequest;
|
||||||
|
import io.metersphere.base.domain.*;
|
||||||
|
import io.metersphere.base.mapper.*;
|
||||||
|
import io.metersphere.base.mapper.ext.ExtApiTestMapper;
|
||||||
|
import io.metersphere.commons.constants.APITestStatus;
|
||||||
|
import io.metersphere.commons.exception.MSException;
|
||||||
|
import io.metersphere.i18n.Translator;
|
||||||
|
import io.metersphere.service.FileService;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class ApiTestService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ApiTestMapper apiTestMapper;
|
||||||
|
@Resource
|
||||||
|
private ExtApiTestMapper extApiTestMapper;
|
||||||
|
@Resource
|
||||||
|
private ProjectMapper projectMapper;
|
||||||
|
@Resource
|
||||||
|
private FileMetadataMapper fileMetadataMapper;
|
||||||
|
@Resource
|
||||||
|
private FileContentMapper fileContentMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiTestFileMapper apiTestFileMapper;
|
||||||
|
@Resource
|
||||||
|
private FileService fileService;
|
||||||
|
|
||||||
|
public List<APITestResult> list(QueryAPITestRequest request) {
|
||||||
|
return extApiTestMapper.list(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<APITestResult> recentTest(QueryAPITestRequest request) {
|
||||||
|
request.setRecent(true);
|
||||||
|
return extApiTestMapper.list(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String save(SaveAPITestRequest request) {
|
||||||
|
final ApiTestWithBLOBs test;
|
||||||
|
if (StringUtils.isNotBlank(request.getId())) {
|
||||||
|
test = updateTest(request);
|
||||||
|
} else {
|
||||||
|
test = createTest(request);
|
||||||
|
}
|
||||||
|
return test.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiTestWithBLOBs get(String id) {
|
||||||
|
return apiTestMapper.selectByPrimaryKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(DeleteAPITestRequest request) {
|
||||||
|
apiTestMapper.deleteByPrimaryKey(request.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApiTestWithBLOBs updateTest(SaveAPITestRequest request) {
|
||||||
|
final ApiTestWithBLOBs test = new ApiTestWithBLOBs();
|
||||||
|
test.setId(request.getId());
|
||||||
|
test.setName(request.getName());
|
||||||
|
test.setProjectId(request.getProjectId());
|
||||||
|
test.setScenarioDefinition(request.getScenarioDefinition());
|
||||||
|
test.setUpdateTime(System.currentTimeMillis());
|
||||||
|
test.setStatus(APITestStatus.Saved.name());
|
||||||
|
apiTestMapper.updateByPrimaryKeySelective(test);
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApiTestWithBLOBs createTest(SaveAPITestRequest request) {
|
||||||
|
ApiTestExample example = new ApiTestExample();
|
||||||
|
example.createCriteria().andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId());
|
||||||
|
if (apiTestMapper.countByExample(example) > 0) {
|
||||||
|
MSException.throwException(Translator.get("load_test_already_exists"));
|
||||||
|
}
|
||||||
|
|
||||||
|
final ApiTestWithBLOBs test = new ApiTestWithBLOBs();
|
||||||
|
test.setId(UUID.randomUUID().toString());
|
||||||
|
test.setName(request.getName());
|
||||||
|
test.setProjectId(request.getProjectId());
|
||||||
|
test.setScenarioDefinition(request.getScenarioDefinition());
|
||||||
|
test.setCreateTime(System.currentTimeMillis());
|
||||||
|
test.setUpdateTime(System.currentTimeMillis());
|
||||||
|
test.setStatus(APITestStatus.Saved.name());
|
||||||
|
apiTestMapper.insert(test);
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,6 +11,8 @@ public class ApiTest implements Serializable {
|
||||||
|
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
private String status;
|
||||||
|
|
||||||
private Long createTime;
|
private Long createTime;
|
||||||
|
|
||||||
private Long updateTime;
|
private Long updateTime;
|
||||||
|
@ -49,6 +51,14 @@ public class ApiTest implements Serializable {
|
||||||
this.description = description == null ? null : description.trim();
|
this.description = description == null ? null : description.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status == null ? null : status.trim();
|
||||||
|
}
|
||||||
|
|
||||||
public Long getCreateTime() {
|
public Long getCreateTime() {
|
||||||
return createTime;
|
return createTime;
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,6 +384,76 @@ public class ApiTestExample {
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusIsNull() {
|
||||||
|
addCriterion("status is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusIsNotNull() {
|
||||||
|
addCriterion("status is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusEqualTo(String value) {
|
||||||
|
addCriterion("status =", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusNotEqualTo(String value) {
|
||||||
|
addCriterion("status <>", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusGreaterThan(String value) {
|
||||||
|
addCriterion("status >", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("status >=", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusLessThan(String value) {
|
||||||
|
addCriterion("status <", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("status <=", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusLike(String value) {
|
||||||
|
addCriterion("status like", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusNotLike(String value) {
|
||||||
|
addCriterion("status not like", value, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusIn(List<String> values) {
|
||||||
|
addCriterion("status in", values, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusNotIn(List<String> values) {
|
||||||
|
addCriterion("status not in", values, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusBetween(String value1, String value2) {
|
||||||
|
addCriterion("status between", value1, value2, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andStatusNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("status not between", value1, value2, "status");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
public Criteria andCreateTimeIsNull() {
|
public Criteria andCreateTimeIsNull() {
|
||||||
addCriterion("create_time is null");
|
addCriterion("create_time is null");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
|
|
|
@ -3,18 +3,18 @@ package io.metersphere.base.domain;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
public class ApiTestWithBLOBs extends ApiTest implements Serializable {
|
public class ApiTestWithBLOBs extends ApiTest implements Serializable {
|
||||||
private String runtimeConfiguration;
|
private String scenarioDefinition;
|
||||||
|
|
||||||
private String schedule;
|
private String schedule;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public String getRuntimeConfiguration() {
|
public String getScenarioDefinition() {
|
||||||
return runtimeConfiguration;
|
return scenarioDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRuntimeConfiguration(String runtimeConfiguration) {
|
public void setScenarioDefinition(String scenarioDefinition) {
|
||||||
this.runtimeConfiguration = runtimeConfiguration == null ? null : runtimeConfiguration.trim();
|
this.scenarioDefinition = scenarioDefinition == null ? null : scenarioDefinition.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSchedule() {
|
public String getSchedule() {
|
||||||
|
|
|
@ -6,11 +6,12 @@
|
||||||
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
|
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
|
||||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||||
<result column="description" jdbcType="VARCHAR" property="description" />
|
<result column="description" jdbcType="VARCHAR" property="description" />
|
||||||
|
<result column="status" jdbcType="VARCHAR" property="status" />
|
||||||
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||||
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.ApiTestWithBLOBs">
|
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.ApiTestWithBLOBs">
|
||||||
<result column="runtime_configuration" jdbcType="LONGVARCHAR" property="runtimeConfiguration" />
|
<result column="scenario_definition" jdbcType="LONGVARCHAR" property="scenarioDefinition" />
|
||||||
<result column="schedule" jdbcType="LONGVARCHAR" property="schedule" />
|
<result column="schedule" jdbcType="LONGVARCHAR" property="schedule" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
<sql id="Example_Where_Clause">
|
<sql id="Example_Where_Clause">
|
||||||
|
@ -72,10 +73,10 @@
|
||||||
</where>
|
</where>
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, project_id, name, description, create_time, update_time
|
id, project_id, name, description, status, create_time, update_time
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Blob_Column_List">
|
<sql id="Blob_Column_List">
|
||||||
runtime_configuration, schedule
|
scenario_definition, schedule
|
||||||
</sql>
|
</sql>
|
||||||
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.ApiTestExample" resultMap="ResultMapWithBLOBs">
|
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.ApiTestExample" resultMap="ResultMapWithBLOBs">
|
||||||
select
|
select
|
||||||
|
@ -127,11 +128,13 @@
|
||||||
</delete>
|
</delete>
|
||||||
<insert id="insert" parameterType="io.metersphere.base.domain.ApiTestWithBLOBs">
|
<insert id="insert" parameterType="io.metersphere.base.domain.ApiTestWithBLOBs">
|
||||||
insert into api_test (id, project_id, name,
|
insert into api_test (id, project_id, name,
|
||||||
description, create_time, update_time,
|
description, status, create_time,
|
||||||
runtime_configuration, schedule)
|
update_time, scenario_definition, schedule
|
||||||
|
)
|
||||||
values (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
|
values (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
|
||||||
#{description,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
#{description,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT},
|
||||||
#{runtimeConfiguration,jdbcType=LONGVARCHAR}, #{schedule,jdbcType=LONGVARCHAR})
|
#{updateTime,jdbcType=BIGINT}, #{scenarioDefinition,jdbcType=LONGVARCHAR}, #{schedule,jdbcType=LONGVARCHAR}
|
||||||
|
)
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiTestWithBLOBs">
|
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiTestWithBLOBs">
|
||||||
insert into api_test
|
insert into api_test
|
||||||
|
@ -148,14 +151,17 @@
|
||||||
<if test="description != null">
|
<if test="description != null">
|
||||||
description,
|
description,
|
||||||
</if>
|
</if>
|
||||||
|
<if test="status != null">
|
||||||
|
status,
|
||||||
|
</if>
|
||||||
<if test="createTime != null">
|
<if test="createTime != null">
|
||||||
create_time,
|
create_time,
|
||||||
</if>
|
</if>
|
||||||
<if test="updateTime != null">
|
<if test="updateTime != null">
|
||||||
update_time,
|
update_time,
|
||||||
</if>
|
</if>
|
||||||
<if test="runtimeConfiguration != null">
|
<if test="scenarioDefinition != null">
|
||||||
runtime_configuration,
|
scenario_definition,
|
||||||
</if>
|
</if>
|
||||||
<if test="schedule != null">
|
<if test="schedule != null">
|
||||||
schedule,
|
schedule,
|
||||||
|
@ -174,14 +180,17 @@
|
||||||
<if test="description != null">
|
<if test="description != null">
|
||||||
#{description,jdbcType=VARCHAR},
|
#{description,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="status != null">
|
||||||
|
#{status,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="createTime != null">
|
<if test="createTime != null">
|
||||||
#{createTime,jdbcType=BIGINT},
|
#{createTime,jdbcType=BIGINT},
|
||||||
</if>
|
</if>
|
||||||
<if test="updateTime != null">
|
<if test="updateTime != null">
|
||||||
#{updateTime,jdbcType=BIGINT},
|
#{updateTime,jdbcType=BIGINT},
|
||||||
</if>
|
</if>
|
||||||
<if test="runtimeConfiguration != null">
|
<if test="scenarioDefinition != null">
|
||||||
#{runtimeConfiguration,jdbcType=LONGVARCHAR},
|
#{scenarioDefinition,jdbcType=LONGVARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="schedule != null">
|
<if test="schedule != null">
|
||||||
#{schedule,jdbcType=LONGVARCHAR},
|
#{schedule,jdbcType=LONGVARCHAR},
|
||||||
|
@ -209,14 +218,17 @@
|
||||||
<if test="record.description != null">
|
<if test="record.description != null">
|
||||||
description = #{record.description,jdbcType=VARCHAR},
|
description = #{record.description,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="record.status != null">
|
||||||
|
status = #{record.status,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="record.createTime != null">
|
<if test="record.createTime != null">
|
||||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||||
</if>
|
</if>
|
||||||
<if test="record.updateTime != null">
|
<if test="record.updateTime != null">
|
||||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||||
</if>
|
</if>
|
||||||
<if test="record.runtimeConfiguration != null">
|
<if test="record.scenarioDefinition != null">
|
||||||
runtime_configuration = #{record.runtimeConfiguration,jdbcType=LONGVARCHAR},
|
scenario_definition = #{record.scenarioDefinition,jdbcType=LONGVARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="record.schedule != null">
|
<if test="record.schedule != null">
|
||||||
schedule = #{record.schedule,jdbcType=LONGVARCHAR},
|
schedule = #{record.schedule,jdbcType=LONGVARCHAR},
|
||||||
|
@ -232,9 +244,10 @@
|
||||||
project_id = #{record.projectId,jdbcType=VARCHAR},
|
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||||
name = #{record.name,jdbcType=VARCHAR},
|
name = #{record.name,jdbcType=VARCHAR},
|
||||||
description = #{record.description,jdbcType=VARCHAR},
|
description = #{record.description,jdbcType=VARCHAR},
|
||||||
|
status = #{record.status,jdbcType=VARCHAR},
|
||||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||||
runtime_configuration = #{record.runtimeConfiguration,jdbcType=LONGVARCHAR},
|
scenario_definition = #{record.scenarioDefinition,jdbcType=LONGVARCHAR},
|
||||||
schedule = #{record.schedule,jdbcType=LONGVARCHAR}
|
schedule = #{record.schedule,jdbcType=LONGVARCHAR}
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
@ -246,6 +259,7 @@
|
||||||
project_id = #{record.projectId,jdbcType=VARCHAR},
|
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||||
name = #{record.name,jdbcType=VARCHAR},
|
name = #{record.name,jdbcType=VARCHAR},
|
||||||
description = #{record.description,jdbcType=VARCHAR},
|
description = #{record.description,jdbcType=VARCHAR},
|
||||||
|
status = #{record.status,jdbcType=VARCHAR},
|
||||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||||
update_time = #{record.updateTime,jdbcType=BIGINT}
|
update_time = #{record.updateTime,jdbcType=BIGINT}
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
|
@ -264,14 +278,17 @@
|
||||||
<if test="description != null">
|
<if test="description != null">
|
||||||
description = #{description,jdbcType=VARCHAR},
|
description = #{description,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="status != null">
|
||||||
|
status = #{status,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="createTime != null">
|
<if test="createTime != null">
|
||||||
create_time = #{createTime,jdbcType=BIGINT},
|
create_time = #{createTime,jdbcType=BIGINT},
|
||||||
</if>
|
</if>
|
||||||
<if test="updateTime != null">
|
<if test="updateTime != null">
|
||||||
update_time = #{updateTime,jdbcType=BIGINT},
|
update_time = #{updateTime,jdbcType=BIGINT},
|
||||||
</if>
|
</if>
|
||||||
<if test="runtimeConfiguration != null">
|
<if test="scenarioDefinition != null">
|
||||||
runtime_configuration = #{runtimeConfiguration,jdbcType=LONGVARCHAR},
|
scenario_definition = #{scenarioDefinition,jdbcType=LONGVARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="schedule != null">
|
<if test="schedule != null">
|
||||||
schedule = #{schedule,jdbcType=LONGVARCHAR},
|
schedule = #{schedule,jdbcType=LONGVARCHAR},
|
||||||
|
@ -284,9 +301,10 @@
|
||||||
set project_id = #{projectId,jdbcType=VARCHAR},
|
set project_id = #{projectId,jdbcType=VARCHAR},
|
||||||
name = #{name,jdbcType=VARCHAR},
|
name = #{name,jdbcType=VARCHAR},
|
||||||
description = #{description,jdbcType=VARCHAR},
|
description = #{description,jdbcType=VARCHAR},
|
||||||
|
status = #{status,jdbcType=VARCHAR},
|
||||||
create_time = #{createTime,jdbcType=BIGINT},
|
create_time = #{createTime,jdbcType=BIGINT},
|
||||||
update_time = #{updateTime,jdbcType=BIGINT},
|
update_time = #{updateTime,jdbcType=BIGINT},
|
||||||
runtime_configuration = #{runtimeConfiguration,jdbcType=LONGVARCHAR},
|
scenario_definition = #{scenarioDefinition,jdbcType=LONGVARCHAR},
|
||||||
schedule = #{schedule,jdbcType=LONGVARCHAR}
|
schedule = #{schedule,jdbcType=LONGVARCHAR}
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
</update>
|
</update>
|
||||||
|
@ -295,6 +313,7 @@
|
||||||
set project_id = #{projectId,jdbcType=VARCHAR},
|
set project_id = #{projectId,jdbcType=VARCHAR},
|
||||||
name = #{name,jdbcType=VARCHAR},
|
name = #{name,jdbcType=VARCHAR},
|
||||||
description = #{description,jdbcType=VARCHAR},
|
description = #{description,jdbcType=VARCHAR},
|
||||||
|
status = #{status,jdbcType=VARCHAR},
|
||||||
create_time = #{createTime,jdbcType=BIGINT},
|
create_time = #{createTime,jdbcType=BIGINT},
|
||||||
update_time = #{updateTime,jdbcType=BIGINT}
|
update_time = #{updateTime,jdbcType=BIGINT}
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package io.metersphere.base.mapper.ext;
|
package io.metersphere.base.mapper.ext;
|
||||||
|
|
||||||
import io.metersphere.controller.request.testplan.QueryTestPlanRequest;
|
import io.metersphere.api.dto.APITestResult;
|
||||||
import io.metersphere.dto.ApiTestDTO;
|
import io.metersphere.api.dto.QueryAPITestRequest;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface ExtApiTestMapper {
|
public interface ExtApiTestMapper {
|
||||||
List<ApiTestDTO> list(@Param("request") QueryTestPlanRequest params);
|
List<APITestResult> list(@Param("request") QueryAPITestRequest request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||||
<mapper namespace="io.metersphere.base.mapper.ext.ExtApiTestMapper">
|
<mapper namespace="io.metersphere.base.mapper.ext.ExtApiTestMapper">
|
||||||
|
|
||||||
<resultMap id="BaseResultMap" type="io.metersphere.dto.ApiTestDTO"
|
<resultMap id="BaseResultMap" type="io.metersphere.api.dto.APITestResult"
|
||||||
extends="io.metersphere.base.mapper.ApiTestMapper.BaseResultMap">
|
extends="io.metersphere.base.mapper.ApiTestMapper.BaseResultMap">
|
||||||
<result column="project_name" property="projectName"/>
|
<result column="project_name" property="projectName"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<select id="list" resultMap="BaseResultMap" parameterType="io.metersphere.controller.request.testplan.QueryTestPlanRequest">
|
<select id="list" resultMap="BaseResultMap" parameterType="io.metersphere.api.dto.APITestResult">
|
||||||
select api_test.*, project.name as project_name
|
select api_test.*, project.name as project_name
|
||||||
from api_test
|
from api_test
|
||||||
left join project on api_test.project_id = project.id
|
left join project on api_test.project_id = project.id
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package io.metersphere.commons.constants;
|
||||||
|
|
||||||
|
public enum APITestStatus {
|
||||||
|
Saved, Starting, Running, Completed, Error
|
||||||
|
}
|
|
@ -1,99 +0,0 @@
|
||||||
package io.metersphere.controller;
|
|
||||||
|
|
||||||
import com.github.pagehelper.Page;
|
|
||||||
import com.github.pagehelper.PageHelper;
|
|
||||||
import io.metersphere.base.domain.FileMetadata;
|
|
||||||
import io.metersphere.commons.constants.RoleConstants;
|
|
||||||
import io.metersphere.commons.utils.PageUtils;
|
|
||||||
import io.metersphere.commons.utils.Pager;
|
|
||||||
import io.metersphere.controller.request.testplan.*;
|
|
||||||
import io.metersphere.dto.ApiTestDTO;
|
|
||||||
import io.metersphere.service.FileService;
|
|
||||||
import io.metersphere.service.ApiTestService;
|
|
||||||
import io.metersphere.user.SessionUtils;
|
|
||||||
import org.apache.shiro.authz.annotation.Logical;
|
|
||||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping(value = "/api")
|
|
||||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR)
|
|
||||||
public class ApiTestController {
|
|
||||||
@Resource
|
|
||||||
private ApiTestService apiTestService;
|
|
||||||
@Resource
|
|
||||||
private FileService fileService;
|
|
||||||
|
|
||||||
@GetMapping("recent/{count}")
|
|
||||||
public List<ApiTestDTO> recentTestPlans(@PathVariable int count) {
|
|
||||||
String currentWorkspaceId = SessionUtils.getCurrentWorkspaceId();
|
|
||||||
QueryTestPlanRequest request = new QueryTestPlanRequest();
|
|
||||||
request.setWorkspaceId(currentWorkspaceId);
|
|
||||||
PageHelper.startPage(1, count, true);
|
|
||||||
return apiTestService.recentTestPlans(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/list/{goPage}/{pageSize}")
|
|
||||||
public Pager<List<ApiTestDTO>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryTestPlanRequest request) {
|
|
||||||
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
|
||||||
request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
|
||||||
return PageUtils.setPageInfo(page, apiTestService.list(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = "/save", consumes = {"multipart/form-data"})
|
|
||||||
public String save(
|
|
||||||
@RequestPart("request") SaveTestPlanRequest request,
|
|
||||||
@RequestPart(value = "file") MultipartFile file
|
|
||||||
) {
|
|
||||||
return apiTestService.save(request, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = "/edit", consumes = {"multipart/form-data"})
|
|
||||||
public String edit(
|
|
||||||
@RequestPart("request") EditTestPlanRequest request,
|
|
||||||
@RequestPart(value = "file", required = false) MultipartFile file
|
|
||||||
) {
|
|
||||||
return apiTestService.edit(request, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/get/{testId}")
|
|
||||||
public ApiTestDTO get(@PathVariable String testId) {
|
|
||||||
return apiTestService.get(testId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/get-runtime-config/{testId}")
|
|
||||||
public String getAdvancedConfiguration(@PathVariable String testId) {
|
|
||||||
return apiTestService.getRuntimeConfiguration(testId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/delete")
|
|
||||||
public void delete(@RequestBody DeleteTestPlanRequest request) {
|
|
||||||
apiTestService.delete(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/run")
|
|
||||||
public void run(@RequestBody RunTestPlanRequest request) {
|
|
||||||
apiTestService.run(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/file/metadata/{testId}")
|
|
||||||
public FileMetadata getFileMetadata(@PathVariable String testId) {
|
|
||||||
return fileService.getApiFileMetadataByTestId(testId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/file/download")
|
|
||||||
public ResponseEntity<byte[]> downloadJmx(@RequestBody FileOperationRequest fileOperationRequest) {
|
|
||||||
byte[] bytes = fileService.loadFileAsBytes(fileOperationRequest.getId());
|
|
||||||
return ResponseEntity.ok()
|
|
||||||
.contentType(MediaType.parseMediaType("application/octet-stream"))
|
|
||||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileOperationRequest.getName() + "\"")
|
|
||||||
.body(bytes);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,7 +15,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
||||||
/**
|
/**
|
||||||
* 统一处理返回结果集
|
* 统一处理返回结果集
|
||||||
*/
|
*/
|
||||||
@RestControllerAdvice(value = {"io.metersphere.controller"})
|
@RestControllerAdvice(value = {"io.metersphere.controller", "io.metersphere.api.controller"})
|
||||||
public class ResultResponseBodyAdvice implements ResponseBodyAdvice<Object> {
|
public class ResultResponseBodyAdvice implements ResponseBodyAdvice<Object> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
package io.metersphere.dto;
|
|
||||||
|
|
||||||
import io.metersphere.base.domain.LoadTest;
|
|
||||||
|
|
||||||
public class ApiTestDTO extends LoadTest {
|
|
||||||
private String projectName;
|
|
||||||
|
|
||||||
public String getProjectName() {
|
|
||||||
return projectName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProjectName(String projectName) {
|
|
||||||
this.projectName = projectName;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,194 +0,0 @@
|
||||||
package io.metersphere.service;
|
|
||||||
|
|
||||||
import io.metersphere.base.domain.*;
|
|
||||||
import io.metersphere.base.mapper.*;
|
|
||||||
import io.metersphere.base.mapper.ext.ExtApiTestMapper;
|
|
||||||
import io.metersphere.commons.exception.MSException;
|
|
||||||
import io.metersphere.controller.request.testplan.*;
|
|
||||||
import io.metersphere.dto.ApiTestDTO;
|
|
||||||
import io.metersphere.i18n.Translator;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public class ApiTestService {
|
|
||||||
@Resource
|
|
||||||
private ApiTestMapper ApiTestMapper;
|
|
||||||
@Resource
|
|
||||||
private ExtApiTestMapper extApiTestMapper;
|
|
||||||
@Resource
|
|
||||||
private ProjectMapper projectMapper;
|
|
||||||
@Resource
|
|
||||||
private FileMetadataMapper fileMetadataMapper;
|
|
||||||
@Resource
|
|
||||||
private FileContentMapper fileContentMapper;
|
|
||||||
@Resource
|
|
||||||
private ApiTestFileMapper ApiTestFileMapper;
|
|
||||||
@Resource
|
|
||||||
private FileService fileService;
|
|
||||||
|
|
||||||
public List<ApiTestDTO> list(QueryTestPlanRequest request) {
|
|
||||||
return extApiTestMapper.list(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete(DeleteTestPlanRequest request) {
|
|
||||||
ApiTestMapper.deleteByPrimaryKey(request.getId());
|
|
||||||
|
|
||||||
fileService.deleteFileByTestId(request.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String save(SaveTestPlanRequest request, MultipartFile file) {
|
|
||||||
if (file == null) {
|
|
||||||
throw new IllegalArgumentException("文件不能为空!");
|
|
||||||
}
|
|
||||||
|
|
||||||
final FileMetadata fileMetadata = saveFile(file);
|
|
||||||
|
|
||||||
final ApiTestWithBLOBs ApiTest = saveApiTest(request);
|
|
||||||
|
|
||||||
ApiTestFile ApiTestFile = new ApiTestFile();
|
|
||||||
ApiTestFile.setTestId(ApiTest.getId());
|
|
||||||
ApiTestFile.setFileId(fileMetadata.getId());
|
|
||||||
ApiTestFileMapper.insert(ApiTestFile);
|
|
||||||
|
|
||||||
return ApiTest.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ApiTestWithBLOBs saveApiTest(SaveTestPlanRequest request) {
|
|
||||||
|
|
||||||
ApiTestExample example = new ApiTestExample();
|
|
||||||
example.createCriteria().andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId());
|
|
||||||
if (ApiTestMapper.countByExample(example) > 0) {
|
|
||||||
MSException.throwException(Translator.get("function_test_already_exists"));
|
|
||||||
}
|
|
||||||
|
|
||||||
final ApiTestWithBLOBs ApiTes = new ApiTestWithBLOBs();
|
|
||||||
ApiTes.setId(UUID.randomUUID().toString());
|
|
||||||
ApiTes.setName(request.getName());
|
|
||||||
ApiTes.setProjectId(request.getProjectId());
|
|
||||||
ApiTes.setCreateTime(System.currentTimeMillis());
|
|
||||||
ApiTes.setUpdateTime(System.currentTimeMillis());
|
|
||||||
ApiTes.setDescription("todo");
|
|
||||||
ApiTes.setRuntimeConfiguration(request.getRuntimeConfiguration());
|
|
||||||
ApiTestMapper.insert(ApiTes);
|
|
||||||
return ApiTes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private FileMetadata saveFile(MultipartFile file) {
|
|
||||||
final FileMetadata fileMetadata = new FileMetadata();
|
|
||||||
fileMetadata.setId(UUID.randomUUID().toString());
|
|
||||||
fileMetadata.setName(file.getOriginalFilename());
|
|
||||||
fileMetadata.setSize(file.getSize());
|
|
||||||
fileMetadata.setCreateTime(System.currentTimeMillis());
|
|
||||||
fileMetadata.setUpdateTime(System.currentTimeMillis());
|
|
||||||
fileMetadata.setType("jmx");
|
|
||||||
fileMetadataMapper.insert(fileMetadata);
|
|
||||||
|
|
||||||
FileContent fileContent = new FileContent();
|
|
||||||
fileContent.setFileId(fileMetadata.getId());
|
|
||||||
try {
|
|
||||||
fileContent.setFile(file.getBytes());
|
|
||||||
} catch (IOException e) {
|
|
||||||
MSException.throwException(e);
|
|
||||||
}
|
|
||||||
fileContentMapper.insert(fileContent);
|
|
||||||
|
|
||||||
return fileMetadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String edit(EditTestPlanRequest request, MultipartFile file) {
|
|
||||||
// 新选择了一个文件,删除原来的文件
|
|
||||||
if (file != null) {
|
|
||||||
fileService.deleteFileByTestId(request.getId());
|
|
||||||
final FileMetadata fileMetadata = saveFile(file);
|
|
||||||
ApiTestFile ApiTestFile = new ApiTestFile();
|
|
||||||
ApiTestFile.setTestId(request.getId());
|
|
||||||
ApiTestFile.setFileId(fileMetadata.getId());
|
|
||||||
ApiTestFileMapper.insert(ApiTestFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
final ApiTestWithBLOBs ApiTest = ApiTestMapper.selectByPrimaryKey(request.getId());
|
|
||||||
if (ApiTest == null) {
|
|
||||||
MSException.throwException("无法编辑测试,未找到测试:" + request.getId());
|
|
||||||
} else {
|
|
||||||
ApiTest.setName(request.getName());
|
|
||||||
ApiTest.setProjectId(request.getProjectId());
|
|
||||||
ApiTest.setUpdateTime(System.currentTimeMillis());
|
|
||||||
ApiTest.setDescription("todo");
|
|
||||||
ApiTest.setRuntimeConfiguration(request.getRuntimeConfiguration());
|
|
||||||
ApiTestMapper.updateByPrimaryKeySelective(ApiTest);
|
|
||||||
}
|
|
||||||
|
|
||||||
return request.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run(RunTestPlanRequest request) {
|
|
||||||
final ApiTestWithBLOBs ApiTest = ApiTestMapper.selectByPrimaryKey(request.getId());
|
|
||||||
// if (ApiTest == null) {
|
|
||||||
// MSException.throwException("无法运行测试,未找到测试:" + request.getId());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// final List<FileMetadata> fileMetadataList = fileService.getFileMetadataByTestId(request.getId());
|
|
||||||
// if (fileMetadataList == null) {
|
|
||||||
// MSException.throwException("无法运行测试,无法获取测试文件元信息,测试ID:" + request.getId());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// final FileContent fileContent = fileService.getFileContent(fileMetadata.getId());
|
|
||||||
// if (fileContent == null) {
|
|
||||||
// MSException.throwException("无法运行测试,无法获取测试文件内容,测试ID:" + request.getId());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// System.out.println("开始运行:" + ApiTest.getName());
|
|
||||||
// final Engine engine = EngineFactory.createEngine(fileMetadata.getType());
|
|
||||||
// if (engine == null) {
|
|
||||||
// MSException.throwException(String.format("无法运行测试,未识别测试文件类型,测试ID:%s,文件类型:%s",
|
|
||||||
// request.getId(),
|
|
||||||
// fileMetadata.getType()));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// boolean init = true;
|
|
||||||
// try {
|
|
||||||
//// init = engine.init(EngineFactory.createContext(ApiTest, fileMetadata, fileContent));
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// MSException.throwException(e);
|
|
||||||
// }
|
|
||||||
// if (!init) {
|
|
||||||
// MSException.throwException(String.format("无法运行测试,初始化运行环境失败,测试ID:%s", request.getId()));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//// engine.start();
|
|
||||||
|
|
||||||
/// todo:通过调用stop方法能够停止正在运行的engine,但是如果部署了多个backend实例,页面发送的停止请求如何定位到具体的engine
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ApiTestDTO> recentTestPlans(QueryTestPlanRequest request) {
|
|
||||||
// 查询最近的测试计划
|
|
||||||
request.setRecent(true);
|
|
||||||
return extApiTestMapper.list(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApiTestDTO get(String testId) {
|
|
||||||
QueryTestPlanRequest request = new QueryTestPlanRequest();
|
|
||||||
request.setId(testId);
|
|
||||||
List<ApiTestDTO> testDTOS = extApiTestMapper.list(request);
|
|
||||||
if (!CollectionUtils.isEmpty(testDTOS)) {
|
|
||||||
return testDTOS.get(0);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRuntimeConfiguration(String testId) {
|
|
||||||
ApiTestWithBLOBs ApiTestWithBLOBs = ApiTestMapper.selectByPrimaryKey(testId);
|
|
||||||
return Optional.ofNullable(ApiTestWithBLOBs).orElse(new ApiTestWithBLOBs()).getRuntimeConfiguration();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -194,19 +194,17 @@ CREATE TABLE IF NOT EXISTS `workspace` (
|
||||||
-- api start
|
-- api start
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `api_test` (
|
CREATE TABLE IF NOT EXISTS `api_test` (
|
||||||
`id` varchar(50) NOT NULL COMMENT 'Test ID',
|
`id` varchar(50) COLLATE utf8mb4_bin NOT NULL COMMENT 'Test ID',
|
||||||
`project_id` varchar(50) NOT NULL COMMENT 'Project ID this test belongs to',
|
`project_id` varchar(50) COLLATE utf8mb4_bin NOT NULL COMMENT 'Project ID this test belongs to',
|
||||||
`name` varchar(64) NOT NULL COMMENT 'Test name',
|
`name` varchar(64) COLLATE utf8mb4_bin NOT NULL COMMENT 'Test name',
|
||||||
`description` varchar(255) DEFAULT NULL COMMENT 'Test description',
|
`description` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'Test description',
|
||||||
`runtime_configuration` longtext COMMENT 'Load configuration (JSON format)',
|
`scenario_definition` longtext COLLATE utf8mb4_bin COMMENT 'Scenario definition (JSON format)',
|
||||||
`schedule` longtext COMMENT 'Test schedule (cron list)',
|
`schedule` longtext COLLATE utf8mb4_bin COMMENT 'Test schedule (cron list)',
|
||||||
`create_time` bigint(13) NOT NULL COMMENT 'Create timestamp',
|
`status` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL,
|
||||||
`update_time` bigint(13) NOT NULL COMMENT 'Update timestamp',
|
`create_time` bigint(13) NOT NULL COMMENT 'Create timestamp',
|
||||||
|
`update_time` bigint(13) NOT NULL COMMENT 'Update timestamp',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||||
ENGINE = InnoDB
|
|
||||||
DEFAULT CHARSET = utf8mb4
|
|
||||||
COLLATE = utf8mb4_bin;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `api_test_file` (
|
CREATE TABLE IF NOT EXISTS `api_test_file` (
|
||||||
`test_id` varchar(64) DEFAULT NULL,
|
`test_id` varchar(64) DEFAULT NULL,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
|
<div id="menu-bar">
|
||||||
<div id="menu-bar" v-if="isRouterAlive">
|
|
||||||
<el-row type="flex">
|
<el-row type="flex">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-menu class="header-menu" :unique-opened="true" mode="horizontal" router :default-active='$route.path'>
|
<el-menu class="header-menu" :unique-opened="true" mode="horizontal" router :default-active='$route.path'>
|
||||||
|
@ -22,10 +21,10 @@
|
||||||
<template v-slot:title>{{$t('commons.test')}}</template>
|
<template v-slot:title>{{$t('commons.test')}}</template>
|
||||||
<ms-recent-list :options="testRecent"/>
|
<ms-recent-list :options="testRecent"/>
|
||||||
<el-divider/>
|
<el-divider/>
|
||||||
<ms-show-all :index="'/api/test/all'"/>
|
<ms-show-all :index="'/api/test/list/all'"/>
|
||||||
<ms-create-button :index="'/api/test/create'" :title="$t('load_test.create')"/>
|
<ms-create-button :index="'/api/test/create'" :title="$t('load_test.create')"/>
|
||||||
<el-menu-item :index="testCaseProjectPath" class="blank_item"></el-menu-item>
|
<!-- <el-menu-item :index="testCaseProjectPath" class="blank_item"></el-menu-item>-->
|
||||||
<el-menu-item :index="testEditPath" class="blank_item"></el-menu-item>
|
<!-- <el-menu-item :index="testEditPath" class="blank_item"></el-menu-item>-->
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
|
|
||||||
<el-submenu v-if="isCurrentWorkspaceUser"
|
<el-submenu v-if="isCurrentWorkspaceUser"
|
||||||
|
@ -34,7 +33,7 @@
|
||||||
<ms-recent-list :options="reportRecent"/>
|
<ms-recent-list :options="reportRecent"/>
|
||||||
<el-divider/>
|
<el-divider/>
|
||||||
<ms-show-all :index="'/api/report/all'"/>
|
<ms-show-all :index="'/api/report/all'"/>
|
||||||
<el-menu-item :index="reportViewPath" class="blank_item"></el-menu-item>
|
<!-- <el-menu-item :index="reportViewPath" class="blank_item"></el-menu-item>-->
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
@ -63,10 +62,10 @@
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isCurrentWorkspaceUser: false,
|
isCurrentWorkspaceUser: false,
|
||||||
testCaseProjectPath: '',
|
// testCaseProjectPath: '',
|
||||||
testEditPath: '',
|
// testEditPath: '',
|
||||||
reportViewPath: '',
|
// reportViewPath: '',
|
||||||
isRouterAlive: true,
|
// isRouterAlive: true,
|
||||||
projectRecent: {
|
projectRecent: {
|
||||||
title: this.$t('project.recent'),
|
title: this.$t('project.recent'),
|
||||||
url: "/project/recent/5",
|
url: "/project/recent/5",
|
||||||
|
@ -82,6 +81,9 @@
|
||||||
url: "/api/recent/5",
|
url: "/api/recent/5",
|
||||||
index: function (item) {
|
index: function (item) {
|
||||||
return '/api/test/edit/' + item.id;
|
return '/api/test/edit/' + item.id;
|
||||||
|
},
|
||||||
|
router: function (item) {
|
||||||
|
return {path: '/api/test/edit', query: {id: item.id}}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
reportRecent: {
|
reportRecent: {
|
||||||
|
@ -93,35 +95,35 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
// watch: {
|
||||||
'$route'(to, from) {
|
// '$route'(to, from) {
|
||||||
let path = to.path;
|
// let path = to.path;
|
||||||
//激活菜单栏
|
// //激活菜单栏
|
||||||
if (path.indexOf("/api/test/") >= 0) {
|
// if (path.indexOf("/api/test/") >= 0) {
|
||||||
this.testCaseProjectPath = '/api/test/' + this.$route.params.projectId;
|
// this.testCaseProjectPath = '/api/test/' + this.$route.params.projectId;
|
||||||
this.reload();
|
// this.reload();
|
||||||
}
|
// }
|
||||||
if (path.indexOf("/api/test/edit/") >= 0) {
|
// if (path.indexOf("/api/test/edit/") >= 0) {
|
||||||
this.testEditPath = '/api/test/edit/' + this.$route.params.testId;
|
// this.testEditPath = '/api/test/edit/' + this.$route.params.testId;
|
||||||
this.reload();
|
// this.reload();
|
||||||
}
|
// }
|
||||||
if (path.indexOf("/api/report/view/") >= 0) {
|
// if (path.indexOf("/api/report/view/") >= 0) {
|
||||||
this.reportViewPath = '/api/report/view/' + this.$route.params.reportId;
|
// this.reportViewPath = '/api/report/view/' + this.$route.params.reportId;
|
||||||
this.reload();
|
// this.reload();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
mounted() {
|
mounted() {
|
||||||
this.isCurrentWorkspaceUser = checkoutCurrentWorkspace();
|
this.isCurrentWorkspaceUser = checkoutCurrentWorkspace();
|
||||||
},
|
},
|
||||||
methods: {
|
// methods: {
|
||||||
reload() {
|
// reload() {
|
||||||
this.isRouterAlive = false;
|
// this.isRouterAlive = false;
|
||||||
this.$nextTick(function () {
|
// this.$nextTick(function () {
|
||||||
this.isRouterAlive = true;
|
// this.isRouterAlive = true;
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<el-button type="primary" plain :disabled="isDisabled" @click="saveTest">保存</el-button>
|
<el-button type="primary" plain :disabled="isDisabled" @click="saveTest">保存</el-button>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-header>
|
</el-header>
|
||||||
<ms-api-scenario-config :scenarios="test.scenarioDefinition"/>
|
<ms-api-scenario-config :scenarios="test.scenarioDefinition" ref="config"/>
|
||||||
</el-container>
|
</el-container>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
|
@ -23,26 +23,34 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MsApiScenarioConfig from "./components/ApiScenarioConfig";
|
import MsApiScenarioConfig from "./components/ApiScenarioConfig";
|
||||||
|
import {Test} from "./model/ScenarioModel"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsApiTestConfig",
|
name: "MsApiTestConfig",
|
||||||
|
|
||||||
components: {MsApiScenarioConfig},
|
components: {MsApiScenarioConfig},
|
||||||
|
|
||||||
|
props: ["id"],
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
result: {},
|
result: {},
|
||||||
projects: [],
|
projects: [],
|
||||||
change: false,
|
change: false,
|
||||||
test: {
|
test: new Test()
|
||||||
id: null,
|
|
||||||
projectId: null,
|
|
||||||
name: null,
|
|
||||||
scenarioDefinition: []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
beforeRouteUpdate(to, from, next) {
|
||||||
|
if (to.params.type === "edit") {
|
||||||
|
this.getTest(to.query.id);
|
||||||
|
} else {
|
||||||
|
this.test = new Test();
|
||||||
|
this.$refs.config.reset();
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
test: {
|
test: {
|
||||||
handler: function () {
|
handler: function () {
|
||||||
|
@ -53,6 +61,19 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
getTest: function (id) {
|
||||||
|
this.result = this.$get("/api/get/" + id, response => {
|
||||||
|
let item = response.data;
|
||||||
|
|
||||||
|
this.test.reset({
|
||||||
|
id: item.id,
|
||||||
|
projectId: item.projectId,
|
||||||
|
name: item.name,
|
||||||
|
scenarioDefinition: JSON.parse(item.scenarioDefinition),
|
||||||
|
});
|
||||||
|
this.$refs.config.reset();
|
||||||
|
});
|
||||||
|
},
|
||||||
saveTest: function () {
|
saveTest: function () {
|
||||||
this.change = false;
|
this.change = false;
|
||||||
|
|
||||||
|
@ -83,6 +104,9 @@
|
||||||
this.result = this.$get("/project/listAll", response => {
|
this.result = this.$get("/project/listAll", response => {
|
||||||
this.projects = response.data;
|
this.projects = response.data;
|
||||||
})
|
})
|
||||||
|
if (this.id) {
|
||||||
|
this.getTest(this.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -71,7 +71,6 @@
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
result: {},
|
result: {},
|
||||||
deletePath: "/api/delete",
|
|
||||||
condition: "",
|
condition: "",
|
||||||
projectId: null,
|
projectId: null,
|
||||||
tableData: [],
|
tableData: [],
|
||||||
|
@ -83,16 +82,18 @@
|
||||||
testId: null,
|
testId: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
'$route'(to) {
|
beforeRouteUpdate(to, from, next) {
|
||||||
this.projectId = to.params.projectId;
|
this.projectId = to.params.projectId;
|
||||||
this.search();
|
this.search();
|
||||||
}
|
next();
|
||||||
},
|
},
|
||||||
|
|
||||||
created: function () {
|
created: function () {
|
||||||
this.projectId = this.$route.params.projectId;
|
this.projectId = this.$route.params.projectId;
|
||||||
this.search();
|
this.search();
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
search() {
|
search() {
|
||||||
let param = {
|
let param = {
|
||||||
|
@ -113,34 +114,27 @@
|
||||||
handleSelectionChange(val) {
|
handleSelectionChange(val) {
|
||||||
this.multipleSelection = val;
|
this.multipleSelection = val;
|
||||||
},
|
},
|
||||||
handleEdit(testPlan) {
|
handleEdit(test) {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: '/api/test/edit/' + testPlan.id,
|
path: '/api/test/edit?id=' + test.id,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleDelete(testPlan) {
|
handleDelete(test) {
|
||||||
this.$alert(this.$t('load_test.delete_confirm') + testPlan.name + "?", '', {
|
this.$alert(this.$t('load_test.delete_confirm') + test.name + "?", '', {
|
||||||
confirmButtonText: this.$t('commons.confirm'),
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
callback: (action) => {
|
callback: (action) => {
|
||||||
if (action === 'confirm') {
|
if (action === 'confirm') {
|
||||||
this._handleDelete(testPlan);
|
this.result = this.$post("/api/delete", {id: test.id}, () => {
|
||||||
|
this.$message({
|
||||||
|
message: this.$t('commons.delete_success'),
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
this.initTableData();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
_handleDelete(testPlan) {
|
|
||||||
let data = {
|
|
||||||
id: testPlan.id
|
|
||||||
};
|
|
||||||
|
|
||||||
this.result = this.$post(this.deletePath, data, () => {
|
|
||||||
this.$message({
|
|
||||||
message: this.$t('commons.delete_success'),
|
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
this.initTableData();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -149,6 +143,4 @@
|
||||||
.test-content {
|
.test-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -41,14 +41,7 @@
|
||||||
options: ASSERTION_TYPE,
|
options: ASSERTION_TYPE,
|
||||||
type: "",
|
type: "",
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
createRegex: function () {
|
|
||||||
return new Regex();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="assertion-item-editing response-time" v-if="assertions.responseTime.isValid()">
|
<div class="assertion-item-editing response-time" v-if="isShow">
|
||||||
<div>
|
<div>
|
||||||
{{$t("api_test.request.assertions.response_time")}}
|
{{$t("api_test.request.assertions.response_time")}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,6 +31,13 @@
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
assertions: Assertions
|
assertions: Assertions
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
isShow() {
|
||||||
|
let rt = this.assertions.responseTime;
|
||||||
|
return rt.responseInTime !== null && rt.responseInTime > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -80,10 +80,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
if (this.requests.length === 0) {
|
this.select(this.requests[0]);
|
||||||
this.createRequest();
|
|
||||||
this.select(this.requests[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -43,12 +43,13 @@
|
||||||
import MsApiKeyValue from "./ApiKeyValue";
|
import MsApiKeyValue from "./ApiKeyValue";
|
||||||
import MsApiBody from "./ApiBody";
|
import MsApiBody from "./ApiBody";
|
||||||
import MsApiAssertions from "./ApiAssertions";
|
import MsApiAssertions from "./ApiAssertions";
|
||||||
|
import {Request} from "../model/ScenarioModel";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsApiRequestForm",
|
name: "MsApiRequestForm",
|
||||||
components: {MsApiAssertions, MsApiBody, MsApiKeyValue},
|
components: {MsApiAssertions, MsApiBody, MsApiKeyValue},
|
||||||
props: {
|
props: {
|
||||||
request: Object
|
request: Request
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -6,7 +6,12 @@
|
||||||
<ms-api-collapse-item v-for="(scenario, index) in scenarios" :key="index"
|
<ms-api-collapse-item v-for="(scenario, index) in scenarios" :key="index"
|
||||||
:title="scenario.name" :name="index">
|
:title="scenario.name" :name="index">
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<div class="scenario-name">{{scenario.name}}</div>
|
<div class="scenario-name">
|
||||||
|
{{scenario.name}}
|
||||||
|
<span id="hint" v-if="!scenario.name">
|
||||||
|
{{$t('api_test.scenario.config')}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<el-dropdown trigger="click" @command="handleCommand">
|
<el-dropdown trigger="click" @command="handleCommand">
|
||||||
<span class="el-dropdown-link el-icon-more scenario-btn"/>
|
<span class="el-dropdown-link el-icon-more scenario-btn"/>
|
||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
@ -57,14 +62,13 @@
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
activeName: 0,
|
activeName: 0,
|
||||||
selected: Object
|
selected: [Scenario, Request]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
createScenario: function () {
|
createScenario: function () {
|
||||||
let scenario = new Scenario({name: "Scenario"});
|
this.scenarios.push(new Scenario());
|
||||||
this.scenarios.push(scenario);
|
|
||||||
},
|
},
|
||||||
deleteScenario: function (index) {
|
deleteScenario: function (index) {
|
||||||
this.scenarios.splice(index, 1);
|
this.scenarios.splice(index, 1);
|
||||||
|
@ -85,6 +89,12 @@
|
||||||
},
|
},
|
||||||
select: function (obj) {
|
select: function (obj) {
|
||||||
this.selected = obj;
|
this.selected = obj;
|
||||||
|
},
|
||||||
|
reset: function () {
|
||||||
|
this.$nextTick(function () {
|
||||||
|
this.activeName = 0;
|
||||||
|
this.select(this.scenarios[0]);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -98,10 +108,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
if (this.scenarios.length === 0) {
|
this.select(this.scenarios[0]);
|
||||||
this.createScenario();
|
|
||||||
this.select(this.scenarios[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -131,6 +138,10 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.scenario-name > #hint {
|
||||||
|
color: #8a8b8d;
|
||||||
|
}
|
||||||
|
|
||||||
.scenario-btn {
|
.scenario-btn {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 13px;
|
padding: 13px;
|
||||||
|
|
|
@ -21,12 +21,13 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MsApiKeyValue from "./ApiKeyValue";
|
import MsApiKeyValue from "./ApiKeyValue";
|
||||||
|
import {Scenario} from "../model/ScenarioModel";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsApiScenarioForm",
|
name: "MsApiScenarioForm",
|
||||||
components: {MsApiKeyValue},
|
components: {MsApiKeyValue},
|
||||||
props: {
|
props: {
|
||||||
scenario: Object
|
scenario: Scenario
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -1,9 +1,23 @@
|
||||||
import {generateId} from "element-ui/src/utils/util";
|
import {generateId} from "element-ui/src/utils/util";
|
||||||
|
|
||||||
const assign = function (obj, options) {
|
const assign = function (obj, options) {
|
||||||
for (let name in options) {
|
if (options) {
|
||||||
if (options.hasOwnProperty(name)) {
|
for (let name in options) {
|
||||||
obj[name] = options[name];
|
if (options.hasOwnProperty(name)) {
|
||||||
|
if (!(obj[name] instanceof Array)) {
|
||||||
|
obj[name] = options[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const assigns = function (target, source, type) {
|
||||||
|
if (target instanceof Array && source instanceof Array) {
|
||||||
|
if (source && source.length > 0) {
|
||||||
|
source.forEach((options) => {
|
||||||
|
target.push(new type(options));
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +33,32 @@ export const ASSERTION_TYPE = {
|
||||||
RESPONSE_TIME: "RESPONSE_TIME"
|
RESPONSE_TIME: "RESPONSE_TIME"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class Test {
|
||||||
|
constructor(options) {
|
||||||
|
this.reset(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
reset(options) {
|
||||||
|
options = this.getDefaultOptions(options);
|
||||||
|
this.id = null;
|
||||||
|
this.name = null;
|
||||||
|
this.projectId = null;
|
||||||
|
this.scenarioDefinition = [];
|
||||||
|
|
||||||
|
assign(this, options);
|
||||||
|
assigns(this.scenarioDefinition, options.scenarioDefinition, Scenario);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefaultOptions(options) {
|
||||||
|
options = options || {};
|
||||||
|
options.scenarioDefinition = options.scenarioDefinition || [new Scenario()];
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class Scenario {
|
export class Scenario {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
options = this.getDefaultOptions(options);
|
||||||
this.name = null;
|
this.name = null;
|
||||||
this.url = null;
|
this.url = null;
|
||||||
this.variables = [];
|
this.variables = [];
|
||||||
|
@ -28,32 +66,55 @@ export class Scenario {
|
||||||
this.requests = [];
|
this.requests = [];
|
||||||
|
|
||||||
assign(this, options);
|
assign(this, options);
|
||||||
|
assigns(this.variables, options.variables, KeyValue);
|
||||||
|
assigns(this.headers, options.headers, KeyValue);
|
||||||
|
assigns(this.requests, options.requests, Request);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefaultOptions(options) {
|
||||||
|
options = options || {};
|
||||||
|
options.requests = options.requests || [new Request()];
|
||||||
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Request {
|
export class Request {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
options = this.getDefaultOptions(options);
|
||||||
this.randomId = generateId();
|
this.randomId = generateId();
|
||||||
this.name = null;
|
this.name = null;
|
||||||
this.url = null;
|
this.url = null;
|
||||||
this.method = null;
|
this.method = null;
|
||||||
this.parameters = [];
|
this.parameters = [];
|
||||||
this.headers = [];
|
this.headers = [];
|
||||||
this.body = new Body();
|
this.body = null;
|
||||||
this.assertions = new Assertions();
|
this.assertions = null;
|
||||||
this.extract = [];
|
this.extract = [];
|
||||||
|
|
||||||
assign(this, options);
|
assign(this, options);
|
||||||
|
assigns(this.parameters, options.parameters, KeyValue);
|
||||||
|
assigns(this.headers, options.headers, KeyValue);
|
||||||
|
// TODO assigns extract
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefaultOptions(options) {
|
||||||
|
options = options || {};
|
||||||
|
options.method = "GET";
|
||||||
|
options.body = new Body(options.body);
|
||||||
|
options.assertions = new Assertions(options.assertions);
|
||||||
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Body {
|
export class Body {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
options = options || {};
|
||||||
this.type = null;
|
this.type = null;
|
||||||
this.text = null;
|
this.text = null;
|
||||||
this.kvs = [];
|
this.kvs = [];
|
||||||
|
|
||||||
assign(this, options);
|
assign(this, options);
|
||||||
|
assigns(this.kvs, options.kvs, KeyValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
isKV() {
|
isKV() {
|
||||||
|
@ -63,6 +124,7 @@ export class Body {
|
||||||
|
|
||||||
export class KeyValue {
|
export class KeyValue {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
options = options || {};
|
||||||
this.key = null;
|
this.key = null;
|
||||||
this.value = null;
|
this.value = null;
|
||||||
|
|
||||||
|
@ -72,11 +134,20 @@ export class KeyValue {
|
||||||
|
|
||||||
export class Assertions {
|
export class Assertions {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
options = this.getDefaultOptions(options);
|
||||||
this.text = [];
|
this.text = [];
|
||||||
this.regex = [];
|
this.regex = [];
|
||||||
this.responseTime = new ResponseTime();
|
this.responseTime = null;
|
||||||
|
|
||||||
assign(this, options);
|
assign(this, options);
|
||||||
|
assigns(this.text, options.text, KeyValue);
|
||||||
|
assigns(this.regex, options.regex, KeyValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefaultOptions(options) {
|
||||||
|
options = options || {};
|
||||||
|
options.responseTime = new ResponseTime(options.responseTime);
|
||||||
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +159,7 @@ class AssertionType {
|
||||||
|
|
||||||
export class Text extends AssertionType {
|
export class Text extends AssertionType {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
options = options || {};
|
||||||
super(ASSERTION_TYPE.TEXT);
|
super(ASSERTION_TYPE.TEXT);
|
||||||
this.subject = null;
|
this.subject = null;
|
||||||
this.condition = null;
|
this.condition = null;
|
||||||
|
@ -99,6 +171,7 @@ export class Text extends AssertionType {
|
||||||
|
|
||||||
export class Regex extends AssertionType {
|
export class Regex extends AssertionType {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
options = options || {};
|
||||||
super(ASSERTION_TYPE.REGEX);
|
super(ASSERTION_TYPE.REGEX);
|
||||||
this.subject = null;
|
this.subject = null;
|
||||||
this.expression = null;
|
this.expression = null;
|
||||||
|
@ -110,14 +183,11 @@ export class Regex extends AssertionType {
|
||||||
|
|
||||||
export class ResponseTime extends AssertionType {
|
export class ResponseTime extends AssertionType {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
options = options || {};
|
||||||
super(ASSERTION_TYPE.RESPONSE_TIME);
|
super(ASSERTION_TYPE.RESPONSE_TIME);
|
||||||
this.responseInTime = null;
|
this.responseInTime = null;
|
||||||
|
|
||||||
assign(this, options);
|
assign(this, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
isValid() {
|
|
||||||
return this.responseInTime !== null && this.responseInTime > 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
name: "MsCreateTest",
|
name: "MsCreateTest",
|
||||||
props: {
|
props: {
|
||||||
show: Boolean,
|
show: Boolean,
|
||||||
to: String,
|
to: [String, Object],
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: function () {
|
default: function () {
|
||||||
|
|
|
@ -95,25 +95,14 @@ const router = new VueRouter({
|
||||||
component: ApiTestHome,
|
component: ApiTestHome,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'test/create',
|
path: "test/:type",
|
||||||
name: "createAPITest",
|
name: "ApiTestConfig",
|
||||||
component: ApiTestConfig,
|
component: ApiTestConfig,
|
||||||
|
props: (route) => ({id: route.query.id})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "test/edit/:testId",
|
path: "test/list/:projectId",
|
||||||
name: "editAPITest",
|
name: "ApiTestList",
|
||||||
component: ApiTestConfig,
|
|
||||||
props: {
|
|
||||||
content: (route) => {
|
|
||||||
return {
|
|
||||||
...route.params
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "test/:projectId",
|
|
||||||
name: "fucPlan",
|
|
||||||
component: ApiTestList
|
component: ApiTestList
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -173,6 +173,7 @@ export default {
|
||||||
input_name: "请输入测试名称",
|
input_name: "请输入测试名称",
|
||||||
select_project: "请选择项目",
|
select_project: "请选择项目",
|
||||||
scenario: {
|
scenario: {
|
||||||
|
config: "场景配置",
|
||||||
input_name: "请输入场景名称",
|
input_name: "请输入场景名称",
|
||||||
name: "场景名称",
|
name: "场景名称",
|
||||||
base_url: "基础URL",
|
base_url: "基础URL",
|
||||||
|
|
Loading…
Reference in New Issue