测试开发系列之——添加用例到测试集合(二)

apiRun.js的代码修改

jQuery的each函数:$.each(ret.data,function(ind,ele)

  • ret.data 是一个数组
  • ind 是数组的索引
  • ele 是数组中的每一个元素
  • ele.name 是套件名
$(function(){
	//共选择的集合
	var url = lemon.config.global.adminUrl+"/suite/listAll";
	$.ajax({url:url,
		headers:{"Authorization":$.cookie("sessionId")},
		data:{"projectId":sessionStorage.getItem("projectId")},
		success:function(ret){
		if(ret!=null){
			var suites = "";
			$.each(ret.data,function(ind,ele){
				if(ind==0){
					suites += ("<li class='active' value='"+ele.id+"'><i class='icon-file'></i>"+ele.name+"</li>");
				}else{
					suites += ("<li class='' value='"+ele.id+"'><i class='icon-file'></i>"+ele.name+"</li>");
				}
			})
			$(".sellist-addass ul").append(suites);
		}
	}});
	//单击保存,添加到集合
	$('#btnSaveInter').on('click',function(){
		var _this = this;
		var dialog = jqueryAlert({
		    'style'   : 'pc',
		    'title'   : '添加到集合',
		    'content' :  $('#addAssemble'),
		    'modal'   : true,
		    'contentTextAlign' : 'left',
		    'width'   : '520px',
		    'animateType' : 'linear',
		    'buttons' :{
		    	'取消' : function(){
		            dialog.close(); 
		        },
		        '确定':function(){
		        	var $form = $('.pcAlert').last().find("[name='addSuiteForm']");
		        	ifViladate = $form.validate('submitValidate');
		        	console.info("ifViladate="+ifViladate);
		        	if(!ifViladate)return false;
		        	var suiteId = $('.pcAlert').last().find(".sellist-addass").find("li.active").val();
		        	var name = $('.pcAlert').last().find("[name='name']").val();
		        	var url=lemon.config.global.adminUrl+"/cases/add?name="+name+"&suiteId="+suiteId;
		        	$.ajax({
						url:url,
						headers:{"Authorization":$.cookie("sessionId")},
		        		data:$("[name='apiRunForm']").serialize(),
		        		type:'post',
		        		dataType:'json',
		        		async:false,
		        		success:function(ret){
		        			alert(ret.message);
		        			dialog.close(); 
		        		}
		        	});
		        	
		        }
		    }
		})
	});

apiRun.html的代码修改

删除apiRun.html内ul的代码:
在这里插入图片描述
如下红框部分需要修改从name="caseName"修改成name=“name”
在这里插入图片描述

数据库SQL查询语句

select * from suite where project_id = 5;
select * from cases where suite_id = 1;

SQL查询结果1:
在这里插入图片描述
SQL查询结果2:
在这里插入图片描述

查找工程下所有的套件以及套件下对应的用例

SuiteMapper.java增加如下代码:

package com.one.mapper;

import com.one.pojo.Suite;

import java.util.List;

import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author annie
 * @since 2020-02-16
 */
public interface SuiteMapper extends BaseMapper<Suite> {
	@Select("select * from suite where project_id = #{projectId};")
	@Results({
		@Result(property="id",column="id"),
		@Result(property="cases",column="id",many=@Many(select="com.one.mapper.CasesMapper.findAll"))
	})
	List<Suite> findSuiteAndReleadtedCasesBy(Integer projectId);
}

CasesMapper.java增加如下代码:

package com.one.mapper;

import com.one.pojo.Cases;

import java.util.List;

import org.apache.ibatis.annotations.Select;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author annie
 * @since 2020-02-16
 */
public interface CasesMapper extends BaseMapper<Cases> {
	@Select("select * from cases where suite_id = #{suiteId};")
	List<Cases> findAll(Integer suiteId);
}

SuiteService.java增加如下代码:

package com.one.service;

import com.one.pojo.Suite;

import java.util.List;

import com.baomidou.mybatisplus.extension.service.IService;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author annie
 * @since 2020-02-16
 */
public interface SuiteService extends IService<Suite> {
	List<Suite> findSuiteAndReleadtedCasesBy(Integer projectId);
}

SuiteServiceImpl.java增加如下代码:

package com.one.service.impl;

import com.one.pojo.Suite;
import com.one.mapper.SuiteMapper;
import com.one.service.SuiteService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author annie
 * @since 2020-02-16
 */
@Service
public class SuiteServiceImpl extends ServiceImpl<SuiteMapper, Suite> implements SuiteService {
	
	@Autowired
	SuiteMapper suiteMapper;
	
	@Override
	public List<Suite> findSuiteAndReleadtedCasesBy(Integer projectId){
		return suiteMapper.findSuiteAndReleadtedCasesBy(projectId);
	}
}

ApiClassificationController.java的代码修改如下:

package com.one.controller;


import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.one.common.ApiClassificationVO;
import com.one.common.Result;
import com.one.pojo.ApiClassification;
import com.one.pojo.Suite;
import com.one.service.ApiClassificationService;
import com.one.service.SuiteService;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author annie
 * @since 2020-02-16
 */
@RestController
@RequestMapping("/apiClassification")
public class ApiClassificationController {
	@Autowired
	ApiClassificationService apiClassificationService;
	//如下两行为新增的代码
	@Autowired
	SuiteService suiteService;
	
	@GetMapping("/toIndex")
	public Result getWithApi(Integer projectId, Integer tab){
		Result result = null;
		if(tab==1){
			//接口列表
			List<ApiClassificationVO> list = apiClassificationService.getWithApi(projectId);
			result = new Result("1",list,"查询分类同时也延迟加载api");
		}else{
			//这个条件判断,如下三行为新增的代码
			//tab=2 测试集合
			List<Suite> list2 = suiteService.findSuiteAndReleadtedCasesBy(projectId);
			result = new Result("1",list2);
		}
		return result;
	}
	
	//根据projectid单表查询分类信息
	@GetMapping("/findAll")
	public Result findAll(Integer projectId){
		QueryWrapper queryWrapper = new QueryWrapper();
		queryWrapper.eq("project_id", projectId);
		List<ApiClassification> list = apiClassificationService.list(queryWrapper);
		return new Result("1",list);
	}
	
	@PostMapping("/add2")
	public Result add2(@RequestBody String jsonStr){
		//String[] strArray = jsonStr.split(":");
		
		System.out.println(jsonStr);
		String value = jsonStr.substring(jsonStr.indexOf("[")+2,jsonStr.lastIndexOf("]")-1);//这边如果是通用的,就不需要再截取了,这句话就可以注释掉了
		System.out.println(value);
		//将jsonStr转成java对象
		ApiClassification apiClassification = JSON.parseObject(value, ApiClassification.class);
		System.out.println(apiClassification);
		apiClassificationService.save(apiClassification);
		return new Result("1","新增分类成功");
	}
}

index2.html前端编码

在index2.html中,删除如下代码:
测试用例集保留一个即可,需要进行循环遍历
在这里插入图片描述
测试用例保留一个即可,需要进行循环遍历
在这里插入图片描述
index2.html完整代码如下:

<!DOCTYPE html>
<html class="indexHtml" ang="zh-CN">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>后台管理</title>
    <meta name="description" content=""/>
    <meta name="keywords" content=""/>
    <meta http-equiv="Cache-Control" content="no-transform" />
    <link rel="stylesheet" type="text/css" href="/lemon/css/index.css">
    <link rel="stylesheet" type="text/css" href="/lemon/css/pagination.css">
    <link rel="stylesheet" type="text/css" href="/lemon/css/alert.css">
</head>
<body class="indexBody">
	<input type="hidden" name="projectId" value="4"/>
<div class="con-wripper">
 <div class="con-top clearfix">
        <div class="left-top f-l">
            <div class="logo-top f-l">
            </div>
            <div class="modname-top f-l">API RUNNER</div>
        </div>
        <div class="right-top f-r">
            <div class="srch-top f-l">
                <input type="text"  class="ipt-top" placeholder="搜索分组/项目/接口" />
            </div>
            <div class="handle-top f-l">
                <i class="icon-top icon-collect"></i>
                <i class="icon-top icon-plus"></i>
                <i class="icon-top icon-doubt"></i>
            </div>
           <div class="ctr-top f-l">
                <div class="btn_stretch">
                    <a class="header-top"></a>
                    <i class="icon-arrow"></i>
                </div>
                <ul class="ctrlist-top">
                    <li class="pctr-top">
                        <a href="#">个人中心</a>
                    </li>
                    <li class="quit-top">
                        <a href="/lemon/user/logout">退出</a>
                    </li>
                </ul>
            </div>

        </div>
    </div>    
    <div class="nav-interlist">
        <ul class="clearfix">
            <li class="active"><a href="#">接口</a></li>
            <li><a href="#">设置</a></li>
        </ul>
    </div>
    <div class="main-interlist com-module clearfix">
    <div class="left-interlist f-l">
            <div class="tab-interlist">
                <div class="tabtype-interlist">
                    <ul class="clearfix">
                       <li ><a href="index.html">接口列表</a></li>
                       <li class="active"><a href="index2.html">测试集合</a></li>
                    </ul>
                </div>
                <div class="srchbox-interlist clearfix">
                    <input type="text" placeholder="搜索用例" class="input-com f-l">
                    <a href="javascript:;" class="btn-addfl btn-com f-r" id="addjh">添加集合</a>
                </div>
            </div>
            <div class="list-interlist" id="listInter">
                <ul class="type_menu">
                    <li v-for="suite in suites">
                        <div class="menu-interlist">
                            <a href="/lemon/html/caseList.html" target="rightIframe">
                                <i class="icon-file"></i>
                                <span>{{suite.name}}</span>
                                <div class="hanmenu-interlist">
                                    <i class="icon-add"></i>
                                    <i class="icon-edit"></i>
                                    <i class="icon-delete"></i>
                                </div>
                            </a>
                        </div>
                        <!-- 默认展开第一个套件 -->
                        	<ul class="tmenu-interlist active">
                        		<!-- 加载此套件下的所有测试用例 -->
	                            <li class="" v-for="caseVo in suite.cases">
	                                <a href="/lemon/html/caseEdit.html" target="rightIframe">
	                                    	{{caseVo.name}}
	                                    <div class="hantmenu-interlist">
	                                        <i class="icon-copy"></i>
	                                        <i class="icon-delete"></i>
	                                    </div>
	                                </a>
	                             </li>
	                        </ul>
	                  </li>
                    <li>
                        <div class="menu-interlist">
                            <a href="/lemon/html/caseList.html" target="rightIframe">
                                <i class="icon-file"></i>
                                <span>登录用例集</span>
                                <div class="hanmenu-interlist">
                                    <i class="icon-add"></i>
                                    <i class="icon-edit"></i>
                                    <i class="icon-delete"></i>
                                </div>
                            </a>
                        </div>
                        <!-- 默认展开第一个套件 -->
                        	<ul class="tmenu-interlist">
                        		<!-- 加载此套件下的所有测试用例 -->
	                        </ul>
	                  </li>
                </ul>
            </div>
        </div>
        <iframe class="rightIframe f-l" name="rightIframe" src="/lemon/html/caseList.html" onload="loadFrame(this);" scrolling="yes" frameborder="0"></iframe>
    </div>
    <!-- 测试集合弹窗 -->
    <form id="addSuite">
        <div class="dialog-addinter">
            <div class="line-addinter form_control clearfix" >
                <label><span>*</span>集合名称:</label>
                <input type="text" placeholder="分类名称" class="required" data-valid="isNonEmpty" data-error="内容不能为空" name="name">
                <span class="valid_message"></span>
            </div>
            <div class="line-addinter form_control clearfix describe">
                <label>描述:</label>
                <textarea type="text" class="path-addinter" placeholder="描述" name="description"></textarea>
            </div>
        </div>
    </form>
</div>
<script type="text/javascript" src="/lemon/js/jquery-1.11.3.js"></script>
<script type="text/javascript" src="/lemon/js/jquery.pagination.js"></script>
<script type="text/javascript" src="/lemon/js/alert.js"></script>
<script type="text/javascript" src="/lemon/js/jquery-validate.js"></script>
<script type="text/javascript" src="/lemon/js/common.js"></script>

<script src="/lemon/js/vue.js"></script>
<script src="/lemon/js/axios.min.js"></script>
<script type="text/javascript">
    var app = new Vue({
        el: ".left-interlist",
        data: {
            contextPath: lemon.config.global.adminUrl,
            info: {},
            suites:[]
        },
        methods: {
            goAll(){
                sessionStorage.removeItem("apiClassificationId");
            },
            goTo(apiClassificationId){
                sessionStorage.setItem("apiClassificationId",apiClassificationId);
            },
            goTo2(apiId){
                sessionStorage.setItem("apiId",apiId);
            }
        },
        created () {
            let projectId = sessionStorage.getItem("projectId");
            let tab=sessionStorage.getItem("tab");
            axios.get(this.contextPath+"/apiClassification/toIndex",{
                headers: {"Authorization":$.cookie("sessionId")},
                params: {"projectId": projectId, "tab":2}
            }).then(response=>{
                this.info = response.data;
                //console.log(this.info.data);
                this.suites = this.info.data;
                if(this.info.status==1&this.info.message=="未登陆"){
                    location.href = lemon.config.global.rootUrl+"/html/login.html";
                }
            })
            .catch(error=>console.log(error));
        }
    });
</script>
<script type="text/javascript" src="/lemon/js/base.js"></script>
<script type="text/javascript" src="/lemon/js/index.js"></script>
</body>
</html>

测试用例集左侧栏位展示效果图

在这里插入图片描述

测试用例集右侧栏位展示需求分析

  1. 首次点击测试集合展示suites下面所有cases
  2. 点击测试集合下面某一个,展示这个测试集合下面的cases
    用例名称来自cases表
    通过api_request_param和case_param_value的间接关系去找到api,多表连接

测试用例集右侧栏位展示数据库SQL查询语句

SELECT DISTINCT
 t1.*, t6.*
FROM
 cases t1
JOIN suite t2 ON t1.suite_id = t2.id
JOIN project t3 ON t2.project_id = t3.id
JOIN case_param_value t4 ON t1.id = t4.case_id
JOIN api_request_param t5 ON t4.api_request_param_id = t5.id
JOIN api t6 ON t5.api_id = t6.id
WHERE
 t3.id = 5

在这里插入图片描述

新增类CaseListVO.java的代码

在com.one.common下新增类CaseListVO.java的代码如下:
name:用例名称
apiUrl:接口路径

package com.one.common;

import lombok.Data;

@Data
public class CaseListVO {
	private String id;
	private String name;
	private String apiId;
	private String apiUrl;
}

CasesMapper.java的代码修改

package com.one.mapper;

import com.one.common.CaseListVO;
import com.one.pojo.Cases;

import java.util.List;

import org.apache.ibatis.annotations.Select;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author annie
 * @since 2020-02-16
 */
public interface CasesMapper extends BaseMapper<Cases> {
	@Select("select * from cases where suite_id = #{suiteId};")
	List<Cases> findAll(Integer suiteId);
	
	//如下两行为新增代码
	@Select("SELECT DISTINCT t1.*, t6.* FROM cases t1 JOIN suite t2 ON t1.suite_id = t2.id JOIN project t3 ON t2.project_id = t3.id JOIN case_param_value t4 ON t1.id = t4.case_id JOIN api_request_param t5 ON t4.api_request_param_id = t5.id JOIN api t6 ON t5.api_id = t6.id WHERE t3.id = #{projectId}")
	List<CaseListVO> showCaseUnderProject(Integer projectId);
	
	//如下两行为新增代码
	@Select("SELECT DISTINCT t1.*, t6.* FROM cases t1 JOIN suite t2 ON t1.suite_id = t2.id JOIN case_param_value t4 ON t1.id = t4.case_id JOIN api_request_param t5 ON t4.api_request_param_id = t5.id JOIN api t6 ON t5.api_id = t6.id WHERE t1.suite_id = #{suiteId}")
	List<CaseListVO> showCaseUnderSuite(String suiteId);
}

遇到的问题汇总

问题一:左边的测试集合出不来,报如下错误,点到tab2,没有发出请求。
在这里插入图片描述
在这里插入图片描述
解决方法:在index2.html和caseList.html代码中,少加如下这行代码,在代码中加入即可解决问题。
<script type="text/javascript" src="/lemon/js/jquery.cookie.js" charset="UTF-8"></script>

**问题二:**如何调整案例执行顺序?比如必须先登录再操作其他的,有些用例需要扽股成功后返回的多个token才能成功,需要如何处理?
**解决方法:**可以设置用例的优先级,在数据库再加一列优先级,设置1、2、3、4等的优先级。

发布了64 篇原创文章 · 获赞 2 · 访问量 2800

猜你喜欢

转载自blog.csdn.net/anniewhite/article/details/104885833