refactor: 测试用例支持拖拽调整顺序代码优化

This commit is contained in:
chenjianxing 2021-09-09 13:46:54 +08:00 committed by jianxing
parent effcece5b1
commit 89684c404c
6 changed files with 169 additions and 100 deletions

View File

@ -81,7 +81,7 @@
left join test_case_review_test_case as T2 on test_case.id=T2.case_id and T2.review_id =#{request.reviewId} left join test_case_review_test_case as T2 on test_case.id=T2.case_id and T2.review_id =#{request.reviewId}
<include refid="notInQueryWhereCondition"/> <include refid="notInQueryWhereCondition"/>
and T2.case_id is null and T2.case_id is null
ORDER BY test_case.update_time DESC <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/>
</select> </select>
<sql id="notInQueryWhereCondition"> <sql id="notInQueryWhereCondition">

View File

@ -5,17 +5,24 @@ import io.metersphere.base.domain.User;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.controller.request.BaseQueryRequest; import io.metersphere.controller.request.BaseQueryRequest;
import io.metersphere.controller.request.OrderRequest; import io.metersphere.controller.request.OrderRequest;
import io.metersphere.controller.request.ResetOrderRequest;
import io.metersphere.service.ProjectService; import io.metersphere.service.ProjectService;
import io.metersphere.service.UserService; import io.metersphere.service.UserService;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class ServiceUtils { public class ServiceUtils {
@ -24,10 +31,18 @@ public class ServiceUtils {
return getDefaultOrder(null, orders); return getDefaultOrder(null, orders);
} }
public static List<OrderRequest> getDefaultSortOrder(List<OrderRequest> orders) {
return getDefaultOrderByField(null, orders, "order");
}
public static List<OrderRequest> getDefaultOrder(String prefix, List<OrderRequest> orders) { public static List<OrderRequest> getDefaultOrder(String prefix, List<OrderRequest> orders) {
return getDefaultOrderByField(prefix, orders, "update_time");
}
private static List<OrderRequest> getDefaultOrderByField(String prefix, List<OrderRequest> orders, String field) {
if (orders == null || orders.size() < 1) { if (orders == null || orders.size() < 1) {
OrderRequest orderRequest = new OrderRequest(); OrderRequest orderRequest = new OrderRequest();
orderRequest.setName("update_time"); orderRequest.setName(field);
orderRequest.setType("desc"); orderRequest.setType("desc");
if (StringUtils.isNotBlank(prefix)) { if (StringUtils.isNotBlank(prefix)) {
orderRequest.setPrefix(prefix); orderRequest.setPrefix(prefix);
@ -100,4 +115,98 @@ public class ServiceUtils {
}); });
return nameMap; return nameMap;
} }
/**
* 初始化 order
* @param clazz
* @param mapClazz
* @param selectProjectIdsFunc
* @param getIdsOrderByCreateTimeFunc
* @param <T>
* @param <M>
*/
public static <T, M> void initOrderField(Class<T> clazz, Class<M> mapClazz,
Supplier<List<String>> selectProjectIdsFunc,
Function<String, List<String>> getIdsOrderByCreateTimeFunc) {
try {
SqlSessionFactory sqlSessionFactory = CommonBeanFactory.getBean(SqlSessionFactory.class);
Method setId = clazz.getMethod("setId", String.class);
Method setOrder = clazz.getMethod("setOrder", Long.class);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
Object mapper = sqlSession.getMapper(mapClazz);
List<String> projectIds = selectProjectIdsFunc.get();
for (String projectId : projectIds) {
Long order = 0L;
List<String> ids = getIdsOrderByCreateTimeFunc.apply(projectId);
for (String id : ids) {
T item = null;
item = (T) clazz.newInstance();
setId.invoke(item, id);
setOrder.invoke(item, order);
order += 5000;
Method updateByPrimaryKeySelectiveFunc = mapper.getClass().getMethod("updateByPrimaryKeySelective", clazz);
updateByPrimaryKeySelectiveFunc.invoke(mapper, item);
}
sqlSession.flushStatements();
}
} catch (Throwable e) {
LogUtil.error(e.getMessage(), e);
}
}
/**
*
* @param request
* @param clazz
* @param selectByPrimaryKeyFunc
* @param getPreOrderFunc
* @param getLastOrderFunc
* @param updateByPrimaryKeySelectiveFuc
* @param <T>
*/
public static <T> void updateOrderField(ResetOrderRequest request, Class<T> clazz,
Function<String, T> selectByPrimaryKeyFunc,
BiFunction<String, Long, Long> getPreOrderFunc,
BiFunction<String, Long, Long> getLastOrderFunc,
Consumer<T> updateByPrimaryKeySelectiveFuc) {
Long order = null;
Long lastOrPreOrder = null;
try {
Method getOrder = clazz.getMethod("getOrder");
Method setId = clazz.getMethod("setId", String.class);
Method setOrder = clazz.getMethod("setOrder", Long.class);
// 获取移动的参考对象
T target = selectByPrimaryKeyFunc.apply(request.getTargetId());
Long targetOrder = (Long) getOrder.invoke(target);
if (request.getMoveMode().equals(ResetOrderRequest.MoveMode.AFTER.name())) {
// 追加到参考对象的之后
order = targetOrder - 5000;
// 因为是降序排则查找比目标 order 小的一个order
lastOrPreOrder = getPreOrderFunc.apply(request.getProjectId(), targetOrder);
} else {
// 追加到前面
order = targetOrder + 5000;
// 因为是降序排则查找比目标 order 更大的一个order
lastOrPreOrder = getLastOrderFunc.apply(request.getProjectId(), targetOrder);
}
if (lastOrPreOrder != null) {
// 如果不是第一个或最后一个则取中间值
order = (targetOrder + lastOrPreOrder) / 2;
}
// 更新order值
T updateObj = (T) clazz.newInstance();
setId.invoke(updateObj, request.getMoveId());
setOrder.invoke(updateObj, order);
updateByPrimaryKeySelectiveFuc.accept(updateObj);
} catch (Throwable e) {
LogUtil.error(e.getMessage(), e);
MSException.throwException("更新 order 字段失败");
}
}
} }

View File

@ -63,22 +63,13 @@ public class AppStartListener implements ApplicationListener<ApplicationReadyEve
initPythonEnv(); initPythonEnv();
try {
//检查状态为开启的TCP-Mock服务端口 //检查状态为开启的TCP-Mock服务端口
projectService.initMockTcpService(); projectService.initMockTcpService();
}catch (Exception e){
e.printStackTrace();
}
initOnceOperate();
initOperate(apiAutomationService::checkApiScenarioUseUrl, "init.scenario.url");
initOperate(apiAutomationService::checkApiScenarioReferenceId, "init.scenario.referenceId");
initOperate(apiAutomationService::initExecuteTimes, "init.scenario.executeTimes");
initOperate(issuesService::syncThirdPartyIssues, "init.issue");
initOperate(issuesService::issuesCount, "init.issueCount");
initOperate(performanceTestService::initScenarioLoadTest, "init.scenario.load.test");
initOperate(testCaseService::initOrderField, "init.sort.test.case");
pluginService.loadPlugins(); pluginService.loadPlugins();
try { try {
Thread.sleep(1 * 60 * 1000); Thread.sleep(1 * 60 * 1000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
@ -96,7 +87,7 @@ public class AppStartListener implements ApplicationListener<ApplicationReadyEve
* @param initFuc * @param initFuc
* @param key * @param key
*/ */
private void initOperate(RunInterface initFuc, final String key) { private void initOnceOperate(RunInterface initFuc, final String key) {
try { try {
String value = systemParameterService.getValue(key); String value = systemParameterService.getValue(key);
if (StringUtils.isBlank(value)) { if (StringUtils.isBlank(value)) {
@ -108,6 +99,16 @@ public class AppStartListener implements ApplicationListener<ApplicationReadyEve
} }
} }
private void initOnceOperate() {
initOnceOperate(apiAutomationService::checkApiScenarioUseUrl, "init.scenario.url");
initOnceOperate(apiAutomationService::checkApiScenarioReferenceId, "init.scenario.referenceId");
initOnceOperate(apiAutomationService::initExecuteTimes, "init.scenario.executeTimes");
initOnceOperate(issuesService::syncThirdPartyIssues, "init.issue");
initOnceOperate(issuesService::issuesCount, "init.issueCount");
initOnceOperate(performanceTestService::initScenarioLoadTest, "init.scenario.load.test");
initOnceOperate(testCaseService::initOrderField, "init.sort.test.case");
}
/** /**
* 解决接口测试-无法导入内置python包 * 解决接口测试-无法导入内置python包
*/ */

View File

@ -635,7 +635,11 @@ public class ProjectService {
} }
} }
/**
* 检查状态为开启的TCP-Mock服务端口
*/
public void initMockTcpService() { public void initMockTcpService() {
try {
ProjectExample example = new ProjectExample(); ProjectExample example = new ProjectExample();
Integer portInteger = new Integer(0); Integer portInteger = new Integer(0);
Boolean statusBoolean = new Boolean(true); Boolean statusBoolean = new Boolean(true);
@ -656,6 +660,9 @@ public class ProjectService {
projectMapper.updateByPrimaryKeySelective(p); projectMapper.updateByPrimaryKeySelective(p);
} }
} }
}catch (Exception e){
e.printStackTrace();
}
} }
public Organization getOrganizationByProjectId(String projectId) { public Organization getOrganizationByProjectId(String projectId) {

View File

@ -190,7 +190,7 @@ public class TestCaseController {
@PostMapping("/edit/order") @PostMapping("/edit/order")
public void orderCase(@RequestBody ResetOrderRequest request) { public void orderCase(@RequestBody ResetOrderRequest request) {
checkPermissionService.checkTestCaseOwner(request.getMoveId()); checkPermissionService.checkTestCaseOwner(request.getMoveId());
testCaseService.orderCase(request); testCaseService.updateOrder(request);
} }
@PostMapping(value = "/edit", consumes = {"multipart/form-data"}) @PostMapping(value = "/edit", consumes = {"multipart/form-data"})

View File

@ -352,14 +352,7 @@ public class TestCaseService {
return returnList; return returnList;
} }
public void setDefaultOrder(QueryTestCaseRequest request) { public void setDefaultOrder(QueryTestCaseRequest request) {
List<OrderRequest> orders = request.getOrders(); List<OrderRequest> orders = ServiceUtils.getDefaultSortOrder(request.getOrders());
if (CollectionUtils.isEmpty(orders)) {
OrderRequest order = new OrderRequest();
order.setName("order");
order.setType("desc");
orders = new ArrayList<>();
orders.add(order);
}
OrderRequest order = new OrderRequest(); OrderRequest order = new OrderRequest();
// 对模板导入的测试用例排序 // 对模板导入的测试用例排序
order.setName("sort"); order.setName("sort");
@ -466,13 +459,10 @@ public class TestCaseService {
} }
public List<TestCase> getReviewCase(QueryTestCaseRequest request) { public List<TestCase> getReviewCase(QueryTestCaseRequest request) {
List<OrderRequest> orderList = ServiceUtils.getDefaultOrder(request.getOrders()); setDefaultOrder(request);
OrderRequest order = new OrderRequest(); request.getOrders().forEach(order -> {
// 对模板导入的测试用例排序 order.setPrefix("test_case");
order.setName("sort"); });
order.setType("desc");
orderList.add(order);
request.setOrders(orderList);
return extTestCaseMapper.getTestCaseByNotInReview(request); return extTestCaseMapper.getTestCaseByNotInReview(request);
} }
@ -484,7 +474,7 @@ public class TestCaseService {
criteria.andMaintainerEqualTo(request.getUserId()); criteria.andMaintainerEqualTo(request.getUserId());
if (StringUtils.isNotBlank(request.getProjectId())) { if (StringUtils.isNotBlank(request.getProjectId())) {
criteria.andProjectIdEqualTo(request.getProjectId()); criteria.andProjectIdEqualTo(request.getProjectId());
testCaseExample.setOrderByClause("update_time desc, sort desc"); testCaseExample.setOrderByClause("order desc, sort desc");
return testCaseMapper.selectByExample(testCaseExample); return testCaseMapper.selectByExample(testCaseExample);
} }
return new ArrayList<>(); return new ArrayList<>();
@ -1004,6 +994,7 @@ public class TestCaseService {
} }
returnDatas.add(list); returnDatas.add(list);
} }
return returnDatas; return returnDatas;
} }
@ -1013,7 +1004,7 @@ public class TestCaseService {
QueryTestCaseRequest condition = request.getCondition(); QueryTestCaseRequest condition = request.getCondition();
List<OrderRequest> orderList = new ArrayList<>(); List<OrderRequest> orderList = new ArrayList<>();
if (condition != null) { if (condition != null) {
orderList = ServiceUtils.getDefaultOrder(condition.getOrders()); orderList = ServiceUtils.getDefaultSortOrder(request.getOrders());
} }
OrderRequest order = new OrderRequest(); OrderRequest order = new OrderRequest();
order.setName("sort"); order.setName("sort");
@ -1408,13 +1399,7 @@ public class TestCaseService {
} }
public List<TestCaseDTO> listTestCaseIds(QueryTestCaseRequest request) { public List<TestCaseDTO> listTestCaseIds(QueryTestCaseRequest request) {
List<OrderRequest> orderList = ServiceUtils.getDefaultOrder(request.getOrders()); setDefaultOrder(request);
OrderRequest order = new OrderRequest();
// 对模板导入的测试用例排序
order.setName("sort");
order.setType("desc");
orderList.add(order);
request.setOrders(orderList);
List<String> selectFields = new ArrayList<>(); List<String> selectFields = new ArrayList<>();
selectFields.add("id"); selectFields.add("id");
selectFields.add("name"); selectFields.add("name");
@ -1494,14 +1479,7 @@ public class TestCaseService {
} }
public List<TestCaseWithBLOBs> listTestCaseForMinder(QueryTestCaseRequest request) { public List<TestCaseWithBLOBs> listTestCaseForMinder(QueryTestCaseRequest request) {
List<OrderRequest> orderList = ServiceUtils.getDefaultOrder(request.getOrders()); setDefaultOrder(request);
OrderRequest order = new OrderRequest();
// 对模板导入的测试用例排序
order.setName("sort");
order.setType("desc");
orderList.add(order);
request.setOrders(orderList);
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
return extTestCaseMapper.listForMinder(request); return extTestCaseMapper.listForMinder(request);
} }
@ -1919,46 +1897,20 @@ public class TestCaseService {
} }
public void initOrderField() { public void initOrderField() {
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); ServiceUtils.initOrderField(TestCaseWithBLOBs.class, TestCaseMapper.class,
TestCaseMapper mapper = sqlSession.getMapper(TestCaseMapper.class); extTestCaseMapper::selectProjectIds,
List<String> projectIds = extTestCaseMapper.selectProjectIds(); extTestCaseMapper::getIdsOrderByCreateTime);
projectIds.forEach((projectId) -> {
Long order = 0L;
List<String> ids = extTestCaseMapper.getIdsOrderByCreateTime(projectId);
for (String id : ids) {
TestCaseWithBLOBs testCase = new TestCaseWithBLOBs();
testCase.setId(id);
testCase.setOrder(order);
order += 5000;
mapper.updateByPrimaryKeySelective(testCase);
}
sqlSession.flushStatements();
});
} }
/** /**
* 用例自定义排序 * 用例自定义排序
* @param request * @param request
*/ */
public void orderCase(ResetOrderRequest request) { public void updateOrder(ResetOrderRequest request) {
Long order = null; ServiceUtils.updateOrderField(request, TestCaseWithBLOBs.class,
Long lastOrPreOrder = null; testCaseMapper::selectByPrimaryKey,
TestCaseWithBLOBs target = testCaseMapper.selectByPrimaryKey(request.getTargetId()); extTestCaseMapper::getPreOrder,
if (request.getMoveMode().equals(ResetOrderRequest.MoveMode.AFTER.name())) { extTestCaseMapper::getLastOrder,
order = target.getOrder() - 5000; testCaseMapper::updateByPrimaryKeySelective);
lastOrPreOrder = extTestCaseMapper.getPreOrder(request.getProjectId(), target.getOrder());
} else {
order = target.getOrder() + 5000;
// 追加到前面因为是降序排则查找比目标 order 更大的一个order
lastOrPreOrder = extTestCaseMapper.getLastOrder(request.getProjectId(), target.getOrder());
}
if (lastOrPreOrder != null) {
// 如果不是第一个或最后一个则取中间值
order = (target.getOrder() + lastOrPreOrder) / 2;
}
TestCaseWithBLOBs testCaseWithBLOBs = new TestCaseWithBLOBs();
testCaseWithBLOBs.setId(request.getMoveId());
testCaseWithBLOBs.setOrder(order);
testCaseMapper.updateByPrimaryKeySelective(testCaseWithBLOBs);
} }
} }