feat(测试用例): 测试用例的Excel模版用例状态字段增加备注、国际化的部分问题
--bug=1005222 --user=宋天阳 【测试用例】excel模版建议添加“用例状态”备注 https://www.tapd.cn/55049933/s/1028465;--bug=1005343 --user=宋天阳 【接口测试】国际化问题 https://www.tapd.cn/55049933/s/1028552
This commit is contained in:
parent
1959fe34f8
commit
12d6b7115b
|
@ -975,11 +975,11 @@ public class ApiDefinitionService {
|
|||
res.setCasePassingRate(compRes.getPassRate());
|
||||
// 状态优先级 未执行,未通过,通过
|
||||
if ((compRes.getError() + compRes.getSuccess()) < compRes.getCaseTotal()) {
|
||||
res.setCaseStatus("未执行");
|
||||
res.setCaseStatus(Translator.get("not_execute"));
|
||||
} else if (compRes.getError() > 0) {
|
||||
res.setCaseStatus("未通过");
|
||||
res.setCaseStatus(Translator.get("execute_not_pass"));
|
||||
} else {
|
||||
res.setCaseStatus("通过");
|
||||
res.setCaseStatus(Translator.get("execute_pass"));
|
||||
}
|
||||
} else {
|
||||
res.setCaseTotal("-");
|
||||
|
|
|
@ -3,7 +3,9 @@ package io.metersphere.excel.handler;
|
|||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
|
||||
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
|
||||
import com.alibaba.excel.write.style.row.AbstractRowHeightStyleStrategy;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.Comment;
|
||||
import org.apache.poi.ss.usermodel.Drawing;
|
||||
|
@ -11,10 +13,8 @@ import org.apache.poi.ss.usermodel.Row;
|
|||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author song.tianyang
|
||||
|
@ -26,9 +26,11 @@ public class FunctionCaseTemplateWriteHandler extends AbstractRowHeightStyleStra
|
|||
private boolean isNeedId;
|
||||
List<List<String>> headList = new ArrayList<>();
|
||||
Map<String,Integer> rowDispseIndexMap;
|
||||
public FunctionCaseTemplateWriteHandler(boolean isNeedId,List<List<String>> headList){
|
||||
Map<String,List<String>> caseLevelAndStatusValueMap;
|
||||
public FunctionCaseTemplateWriteHandler(boolean isNeedId,List<List<String>> headList,Map<String,List<String>> caseLevelAndStatusValueMap){
|
||||
this.isNeedId = isNeedId;
|
||||
rowDispseIndexMap = this.buildFiledMap(headList);
|
||||
this.caseLevelAndStatusValueMap = caseLevelAndStatusValueMap;
|
||||
}
|
||||
|
||||
private Map<String, Integer> buildFiledMap(List<List<String>> headList) {
|
||||
|
@ -47,6 +49,8 @@ public class FunctionCaseTemplateWriteHandler extends AbstractRowHeightStyleStra
|
|||
returnMap.put("Priority",index);
|
||||
}else if(StringUtils.equalsAnyIgnoreCase(head,"标签","標簽","Tag")){
|
||||
returnMap.put("Tag",index);
|
||||
}else if(StringUtils.equalsAnyIgnoreCase(head,"用例状态","用例狀態","Case status")){
|
||||
returnMap.put("Status",index);
|
||||
}
|
||||
index ++;
|
||||
}
|
||||
|
@ -94,12 +98,30 @@ public class FunctionCaseTemplateWriteHandler extends AbstractRowHeightStyleStra
|
|||
sheet.getRow(0).getCell(1).setCellComment(comment);
|
||||
}else if(StringUtils.equalsAnyIgnoreCase(coloum,"Priority")){
|
||||
Comment comment = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, index, 0, (short) 3, 1));
|
||||
comment.setString(new XSSFRichTextString(Translator.get("options") + "(P0、P1、P2、P3)"));
|
||||
List<String> list = new ArrayList<>();
|
||||
if(caseLevelAndStatusValueMap != null && caseLevelAndStatusValueMap.containsKey("caseLevel")){
|
||||
list = caseLevelAndStatusValueMap.get("caseLevel");
|
||||
}
|
||||
if(CollectionUtils.isEmpty(list)){
|
||||
comment.setString(new XSSFRichTextString(Translator.get("options") + "(P0、P1、P2、P3)"));
|
||||
}else {
|
||||
comment.setString(new XSSFRichTextString(Translator.get("options") + JSONArray.toJSONString(list)));
|
||||
}
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment);
|
||||
}else if(StringUtils.equalsAnyIgnoreCase(coloum,"Tag")){
|
||||
Comment comment = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, index, 0, (short) 3, 1));
|
||||
comment.setString(new XSSFRichTextString(Translator.get("tag_tip_pattern")));
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment);
|
||||
}else if(StringUtils.equalsAnyIgnoreCase(coloum,"Status")){
|
||||
List<String> list = new ArrayList<>();
|
||||
if(caseLevelAndStatusValueMap != null && caseLevelAndStatusValueMap.containsKey("caseStatus")){
|
||||
list = caseLevelAndStatusValueMap.get("caseStatus");
|
||||
}
|
||||
if(!CollectionUtils.isEmpty(list)){
|
||||
Comment comment = drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, index, 0, (short) 3, 1));
|
||||
comment.setString(new XSSFRichTextString(Translator.get("options") + JSONArray.toJSONString(list)));
|
||||
sheet.getRow(0).getCell(1).setCellComment(comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,15 +46,15 @@ public class EasyExcelExporter {
|
|||
response.setContentType("application/vnd.ms-excel");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
List<List<String>> list = new ArrayList<>();
|
||||
List<String>aaaList = new ArrayList<>();
|
||||
aaaList.add("aaaaa");
|
||||
List<String>nameList = new ArrayList<>();
|
||||
nameList.add("所属模块");
|
||||
List<String>name2List = new ArrayList<>();
|
||||
name2List.add("用例名称");
|
||||
list.add(aaaList);
|
||||
list.add(nameList);
|
||||
list.add(name2List);
|
||||
// List<String>aaaList = new ArrayList<>();
|
||||
// aaaList.add("aaaaa");
|
||||
// List<String>nameList = new ArrayList<>();
|
||||
// nameList.add("所属模块");
|
||||
// List<String>name2List = new ArrayList<>();
|
||||
// name2List.add("用例名称");
|
||||
// list.add(aaaList);
|
||||
// list.add(nameList);
|
||||
// list.add(name2List);
|
||||
try {
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
|
||||
if(CollectionUtils.isNotEmpty(excludeColumnFiledNames)){
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.TestCaseTemplateMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestCaseTemplateMapper;
|
||||
|
@ -24,8 +26,7 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
|
@ -182,6 +183,51 @@ public class TestCaseTemplateService extends TemplateBaseService {
|
|||
return testCaseTemplates;
|
||||
}
|
||||
|
||||
public Map<String,List<String>> getCaseLevelAndStatusMapByProjectId(String projectId){
|
||||
Project project = projectService.getProjectById(projectId);
|
||||
String caseTemplateId = project.getCaseTemplateId();
|
||||
TestCaseTemplateWithBLOBs caseTemplate = null;
|
||||
TestCaseTemplateDao caseTemplateDao = new TestCaseTemplateDao();
|
||||
if (StringUtils.isNotBlank(caseTemplateId)) {
|
||||
caseTemplate = testCaseTemplateMapper.selectByPrimaryKey(caseTemplateId);
|
||||
if (caseTemplate == null) {
|
||||
caseTemplate = getDefaultTemplate(project.getWorkspaceId());
|
||||
}
|
||||
} else {
|
||||
caseTemplate = getDefaultTemplate(project.getWorkspaceId());
|
||||
}
|
||||
BeanUtils.copyBean(caseTemplateDao, caseTemplate);
|
||||
List<CustomFieldDao> result = customFieldService.getCustomFieldByTemplateId(caseTemplate.getId());
|
||||
|
||||
Map<String, List<String>> returnMap = new HashMap<>();
|
||||
for (CustomFieldDao field:result) {
|
||||
if(StringUtils.equalsAnyIgnoreCase(field.getScene(),"TEST_CASE")){
|
||||
if(StringUtils.equalsAnyIgnoreCase(field.getName(),"用例等级")){
|
||||
try {
|
||||
JSONArray jsonArray = JSONArray.parseArray(field.getOptions());
|
||||
List<String> values = new ArrayList<>();
|
||||
for (int i = 0;i < jsonArray.size();i++) {
|
||||
JSONObject obj = jsonArray.getJSONObject(i);
|
||||
values.add(obj.getString("value"));
|
||||
}
|
||||
returnMap.put("caseLevel",values);
|
||||
}catch (Exception e){}
|
||||
}else if(StringUtils.equalsAnyIgnoreCase(field.getName(),"用例状态")){
|
||||
try {
|
||||
JSONArray jsonArray = JSONArray.parseArray(field.getOptions());
|
||||
List<String> values = new ArrayList<>();
|
||||
for (int i = 0;i < jsonArray.size();i++) {
|
||||
JSONObject obj = jsonArray.getJSONObject(i);
|
||||
values.add(obj.getString("value"));
|
||||
}
|
||||
returnMap.put("caseStatus",values);
|
||||
}catch (Exception e){}
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnMap;
|
||||
}
|
||||
|
||||
public TestCaseTemplateDao getTemplate(String projectId) {
|
||||
Project project = projectService.getProjectById(projectId);
|
||||
String caseTemplateId = project.getCaseTemplateId();
|
||||
|
|
|
@ -29,10 +29,7 @@ import io.metersphere.log.utils.ReflexObjectUtil;
|
|||
import io.metersphere.log.vo.DetailColumn;
|
||||
import io.metersphere.log.vo.OperatingLogDetails;
|
||||
import io.metersphere.log.vo.track.TestCaseReference;
|
||||
import io.metersphere.service.FileService;
|
||||
import io.metersphere.service.ProjectService;
|
||||
import io.metersphere.service.TestCaseTemplateService;
|
||||
import io.metersphere.service.UserService;
|
||||
import io.metersphere.service.*;
|
||||
import io.metersphere.track.dto.TestCaseCommentDTO;
|
||||
import io.metersphere.track.dto.TestCaseDTO;
|
||||
import io.metersphere.track.request.testcase.EditTestCaseRequest;
|
||||
|
@ -120,6 +117,8 @@ public class TestCaseService {
|
|||
private TestCaseIssuesMapper testCaseIssuesMapper;
|
||||
@Resource
|
||||
private IssuesMapper issuesMapper;
|
||||
@Resource
|
||||
private CustomFieldService customFieldService;
|
||||
|
||||
private void setNode(TestCaseWithBLOBs testCase) {
|
||||
if (StringUtils.isEmpty(testCase.getNodeId()) || "default-module".equals(testCase.getNodeId())) {
|
||||
|
@ -731,8 +730,9 @@ public class TestCaseService {
|
|||
|
||||
List<List<String>> headList = testCaseExcelData.getHead(importFileNeedNum, customFields);
|
||||
EasyExcelExporter easyExcelExporter = new EasyExcelExporter(testCaseExcelData.getClass());
|
||||
FunctionCaseTemplateWriteHandler handler = new FunctionCaseTemplateWriteHandler(importFileNeedNum, headList);
|
||||
easyExcelExporter.exportByCustomWriteHandler(response, headList, generateExportDatas(importFileNeedNum),
|
||||
Map<String,List<String>> caseLevelAndStatusValueMap = testCaseTemplateService.getCaseLevelAndStatusMapByProjectId(projectId);
|
||||
FunctionCaseTemplateWriteHandler handler = new FunctionCaseTemplateWriteHandler(importFileNeedNum,headList,caseLevelAndStatusValueMap);
|
||||
easyExcelExporter.exportByCustomWriteHandler(response,headList, generateExportDatas(importFileNeedNum),
|
||||
Translator.get("test_case_import_template_name"), Translator.get("test_case_import_template_sheet"), handler);
|
||||
|
||||
} catch (Exception e) {
|
||||
|
@ -968,7 +968,6 @@ public class TestCaseService {
|
|||
|
||||
/**
|
||||
* 更新自定义字段
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
public void editTestCaseBath(TestCaseBatchRequest request) {
|
||||
|
@ -1283,7 +1282,6 @@ public class TestCaseService {
|
|||
if (editCustomFieldsPriority(dbCase, item.getPriority())) {
|
||||
item.setCustomFields(dbCase.getCustomFields());
|
||||
}
|
||||
;
|
||||
editTestCase(item);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -217,6 +217,9 @@ message_task_already_exists=Task recipient already exists
|
|||
automation_name_already_exists=the scenario already exists in the project
|
||||
automation_exec_info=There are no test steps to execute
|
||||
delete_check_reference_by=be referenced by Scenario
|
||||
not_execute=Not execute
|
||||
execute_not_pass=Not pass
|
||||
execute_pass=Pass
|
||||
#authsource
|
||||
authsource_name_already_exists=Authentication source name already exists
|
||||
authsource_name_is_null=Authentication source name cannot be empty
|
||||
|
|
|
@ -217,6 +217,9 @@ message_task_already_exists=任务接收人已经存在
|
|||
automation_name_already_exists=同一个项目下,场景名称不能重复
|
||||
automation_exec_info=没有测试步骤,无法执行
|
||||
delete_check_reference_by=被场景引用
|
||||
not_execute=未执行
|
||||
execute_not_pass=未通过
|
||||
execute_pass=通过
|
||||
#authsource
|
||||
authsource_name_already_exists=认证源名称已经存在
|
||||
authsource_name_is_null=认证源名称不能为空
|
||||
|
|
|
@ -218,6 +218,9 @@ message_task_already_exists=任務接收人已經存在
|
|||
automation_name_already_exists=同一個項目下,場景名稱不能重複
|
||||
automation_exec_info=沒有測試步驟,無法執行
|
||||
delete_check_reference_by=被場景引用
|
||||
not_execute=未執行
|
||||
execute_not_pass=未通過
|
||||
execute_pass=通過
|
||||
#authsource
|
||||
authsource_name_already_exists=認證源名稱已經存在
|
||||
authsource_name_is_null=認證源名稱不能為空
|
||||
|
|
|
@ -179,7 +179,7 @@ export default {
|
|||
params.forEach(item => {
|
||||
let line = item.split(/,|,/);
|
||||
let required = false;
|
||||
if (line[1] === '必填' || line[1] === 'true') {
|
||||
if (line[1] === '必填' || line[1] === 'Required' || line[1] === 'true') {
|
||||
required = true;
|
||||
}
|
||||
keyValues.push(new KeyValue({
|
||||
|
|
|
@ -135,7 +135,10 @@
|
|||
data() {
|
||||
return {
|
||||
currentItem: null,
|
||||
requireds: REQUIRED,
|
||||
requireds: [
|
||||
{name: this.$t('commons.selector.required'), id: true},
|
||||
{name: this.$t('commons.selector.not_required'), id: false}
|
||||
],
|
||||
isSelectAll: true,
|
||||
isActive: true
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
params.forEach(item => {
|
||||
let line = item.split(/,|,/);
|
||||
let required = false;
|
||||
if (line[1] === '必填' || line[1] === 'true') {
|
||||
if (line[1] === '必填' || line[1] === 'Required' || line[1] === 'true') {
|
||||
required = true;
|
||||
}
|
||||
keyValues.push(new KeyValue({name: line[0], required: required, value: line[2], description: line[3], type: "text", valid: false, file: false, encode: true, enable: true, contentType: "text/plain"}));
|
||||
|
|
|
@ -179,7 +179,7 @@
|
|||
params.forEach(item => {
|
||||
let line = item.split(/,|,/);
|
||||
let required = false;
|
||||
if (line[1] === '必填' || line[1] === 'true') {
|
||||
if (line[1] === '必填' || line[1] === 'Required' || line[1] === 'true') {
|
||||
required = true;
|
||||
}
|
||||
keyValues.push(new KeyValue({name: line[0], required: required, value: line[2], description: line[3], type: "text", valid: false, file: false, encode: true, enable: true, contentType: "text/plain"}));
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
|
||||
<script>
|
||||
import {_getBodyUploadFiles, getCurrentProjectID, getUUID} from "@/common/js/utils";
|
||||
import {PRIORITY, RESULT_MAP} from "../../model/JsonData";
|
||||
import {PRIORITY} from "../../model/JsonData";
|
||||
import MsTag from "../../../../common/components/MsTag";
|
||||
import MsTipButton from "../../../../common/components/MsTipButton";
|
||||
import MsApiRequestForm from "../request/http/ApiHttpRequestForm";
|
||||
|
@ -173,6 +173,11 @@
|
|||
return {
|
||||
result: {},
|
||||
grades: [],
|
||||
resultMap:new Map([
|
||||
['success', this.$t('test_track.plan_view.execute_result')+':'+this.$t('test_track.plan_view.pass')],
|
||||
['error', this.$t('test_track.plan_view.execute_result')+':'+this.$t('api_test.home_page.detail_card.execution_failed')],
|
||||
['default', this.$t('test_track.plan_view.execute_result')+':'+this.$t('api_test.home_page.detail_card.unexecute')]
|
||||
]),
|
||||
showXpackCompnent: false,
|
||||
isReadOnly: false,
|
||||
selectedEvent: Object,
|
||||
|
@ -390,10 +395,10 @@
|
|||
item.active = !item.active;
|
||||
},
|
||||
getResult(data) {
|
||||
if (RESULT_MAP.get(data)) {
|
||||
return RESULT_MAP.get(data);
|
||||
if (this.resultMap.get(data)) {
|
||||
return this.resultMap.get(data);
|
||||
} else {
|
||||
return RESULT_MAP.get("default");
|
||||
return this.resultMap.get("default");
|
||||
}
|
||||
},
|
||||
validate(row) {
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
<ms-api-auth-config :is-read-only="isReadOnly" :request="request"/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="其他设置" name="advancedConfig">
|
||||
<el-tab-pane :label="$t('api_test.definition.request.other_config')" name="advancedConfig">
|
||||
<ms-api-advanced-config :is-read-only="isReadOnly" :request="request"/>
|
||||
</el-tab-pane>
|
||||
|
||||
|
@ -219,7 +219,7 @@
|
|||
params.forEach(item => {
|
||||
let line = item.split(/,|,/);
|
||||
let required = false;
|
||||
if (line[1] === '必填' || line[1] === 'true') {
|
||||
if (line[1] === '必填' || line[1] === 'Required' || line[1] === 'true') {
|
||||
required = true;
|
||||
}
|
||||
keyValues.push(new KeyValue({name: line[0], required: required, value: line[2], description: line[3], type: "text", valid: false, file: false, encode: true, enable: true, contentType: "text/plain"}));
|
||||
|
|
|
@ -198,7 +198,7 @@
|
|||
params.forEach(item => {
|
||||
let line = item.split(/,|,/);
|
||||
let required = false;
|
||||
if (line[1] === '必填' || line[1] === 'true') {
|
||||
if (line[1] === '必填' || line[1] === 'Required' || line[1] === 'true') {
|
||||
required = true;
|
||||
}
|
||||
keyValues.push(new KeyValue({name: line[0], required: required, value: line[2], description: line[3], type: "text", valid: false, file: false, encode: true, enable: true, contentType: "text/plain"}));
|
||||
|
|
|
@ -101,7 +101,7 @@ export default {
|
|||
params.forEach(item => {
|
||||
let line = item.split(/,|,/);
|
||||
let required = false;
|
||||
if (line[1] === '必填' || line[1] === 'true') {
|
||||
if (line[1] === '必填' || line[1] === 'Required' || line[1] === 'true') {
|
||||
required = true;
|
||||
}
|
||||
keyValues.push(new KeyValue({
|
||||
|
|
|
@ -171,6 +171,10 @@ export default {
|
|||
table: {
|
||||
select_tip: "Item {0} data is selected"
|
||||
},
|
||||
selector: {
|
||||
required: "Required",
|
||||
not_required: "Not required",
|
||||
},
|
||||
ssl: {
|
||||
config: "Config",
|
||||
files: "Files",
|
||||
|
@ -750,7 +754,7 @@ export default {
|
|||
definition: {
|
||||
api_title: "Api test",
|
||||
case_title: "Test Case",
|
||||
doc_title: "Document",
|
||||
doc_title: "DOC",
|
||||
api_name: "Api name",
|
||||
api_status: "Api status",
|
||||
api_type: "Api type",
|
||||
|
@ -758,8 +762,8 @@ export default {
|
|||
api_path: "Api path",
|
||||
api_principal: "Api principal",
|
||||
api_last_time: "Last update time",
|
||||
api_case_number: "Number use case",
|
||||
api_case_status: "Ise case status",
|
||||
api_case_number: "Cases",
|
||||
api_case_status: "Case status",
|
||||
api_case_passing_rate: "Use case pass rate",
|
||||
create_tip: "Note: Detailed interface information can be filled out on the edit page",
|
||||
api_import: "Api Import",
|
||||
|
|
|
@ -172,6 +172,10 @@ export default {
|
|||
table: {
|
||||
select_tip: "已选中 {0} 条数据"
|
||||
},
|
||||
selector: {
|
||||
required: "必填",
|
||||
not_required: "非必填",
|
||||
},
|
||||
ssl: {
|
||||
config: "证书配置",
|
||||
files: "证书文件",
|
||||
|
|
|
@ -169,6 +169,10 @@ export default {
|
|||
create_user: "創建人",
|
||||
run_message: "任務執行中,請到任務中心查看詳情",
|
||||
executor: "執行人",
|
||||
selector: {
|
||||
required: "必填",
|
||||
not_required: "非必填",
|
||||
},
|
||||
table: {
|
||||
select_tip: "已選中 {0} 條數據"
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue