前言
最初目的,为了在整体测试平台框架下,测试人员可便捷维护用例,无需启动服务、编译程序,提供一套Excel填写测试用例并能快速执行的解决方案。后续扩展了不同类型的测试用例,本文则对Web类型的测试用例Excel方式执行测试逻辑进行介绍。
开发过程中,本想着网上CV大法搞下来修修改改,结果发现没一个清晰完整的分享,于是,结合自身理解,以及测试框架设计,形成了目前的一个版本,同时分享给测试小伙伴,希望能对各位测试伙伴能有所帮助。
其他说明
- 开发语言Java,采用SpringBoot开发框架(版本2.1.18.RELEASE)(文章尾部会贴出各依赖版本POM文件),测试底层调用Selenium框架方法,以及测试注解引用TestNG测试框架,本文所述功能仅为整体测试框架中一个小功能点,所以分享并没有全部贴出(不是作者不想,作者自研,完全有权限分享,只是内容太多,没整理好,就暂时不发出来)
- 所有代码均有注释,代码基本不再细致说明,以及一些额外相关的代码没贴出来(主要是放这里显得杂乱,有机会单写文章说明整体架构逻辑及源码,有兴趣留言交流)
- 本文主要从作者主观逻辑、代码进行介绍,可能部分方法、部分逻辑并未介绍到位,作者写文纯属锻炼下文档(好久没写文档了),不完善的地方请各位玩家理解,欢迎留言咨询,后续看源码通过什么形式发出来
- 文章作者:@随心自然fqc , 转载时,请注明来源,注明作者,这是对文章作者的尊重,也是对知识的尊重。
整体图解
先看看整体逻辑,看完整体代码逻辑后,建议再回头看看这张图 ><
主要内容
1、测试用例调用方式
import cn.nhdc.cloud.modules.casemanage.model.vo.TestCaseVo;
import cn.nhdc.cloud.testscripts.listener.ExtentTestNGIReporterListener;
import cn.nhdc.cloud.testscripts.testcase.base.WebTestBase;
import org.testng.annotations.Listeners;
import org.testng.annotations.Optional;
import org.testng.annotations.Test;
import java.util.List;
/**
* Web类型 Excel执行方式 自动化测试demo <br>
* Method 1 : {@link #testExcelExcute} 正向逻辑执行 <br>
* Method 2 : {@link #testExcelInvokeExcute} 反射逻辑执行 <br>
*
* ps: 以上2种方式 原理不同 但执行效果类似 具体选择哪种取决于调用者意愿
*
* @author Fan QingChuan
*/
@Test(description = "Excel方式自动化测试示例-正向逻辑&反射执行逻辑")
@Listeners(value = ExtentTestNGIReporterListener.class)
public class ExcelWebTestDemo extends WebTestBase {
@Test(description = "正向逻辑: 操作方法封装在 WebTestBase 中,
测试用例中可直接调用 解析Excel -> caseSteps 根据遍历操作编码switch执行各项操作")
void testExcelExcute(
@Optional("C:\\Users\\allen\\Desktop\\自动化测试_Web类型测试用例_2022_07_07_185853_437.xlsx") String fileName,
@Optional("testcase")String sheetName,@Optional("null")Integer headerRowNumber) {
List<TestCaseVo> caseVoList = analysisExcelUiCase(fileName, sheetName, headerRowNumber);
excuteExcelUiTest(caseVoList);
}
@Test(description = "反射逻辑: 操作封装在 WebCommon 通过 WebTestBase 中反射获取BasePage.class
并实例化 再根据操作编码+分类枚举 获取对应方法 并反射(invoke)执行测试")
void testExcelInvokeExcute(
@Optional("C:\\Users\\allen\\Desktop\\自动化测试_Web类型测试用例_2022_07_21_134019_690.xlsx") String fileName,
@Optional("testcase")String sheetName,@Optional("null")Integer headerRowNumber)
throws IllegalAccessException, InstantiationException {
List<TestCaseVo> caseVoList = analysisExcelUiCase(fileName, sheetName, headerRowNumber);
invokeExcelUiTest(caseVoList);
}
}
2、测试用例对象Vo
import cn.nhdc.cloud.modules.casemanage.service.Add;
import cn.nhdc.cloud.modules.casemanage.service.Update;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
*
* @author Fan QingChuan
*/
@Data
public class TestCaseVo {
@NotNull(message = "caseId(用例ID)不能为空", groups = {Update.class})
private Long caseId;
/**
* 测试集ID
*/
private Long suiteId;
/**
* 团队code
*/
@NotBlank(message = "teamCode 团队code不能为空", groups = {Add.class, Update.class})
private String teamCode;
/**
* 测试用例编码
*/
@NotBlank(message = "caseCode 用例编号不能为空", groups = {Add.class, Update.class})
private String caseCode;
/**
* 测试用例类型 1-接口测试 2-Web测试 3-安卓APP测试 4-IOS APP测试 9-其他混合测试
*/
@NotNull(message = "type 测试用例类型不能为空", groups = {Add.class, Update.class})
private Integer type;
/**
* 用例顺序号
*/
private Integer sort;
/**
* 用例描述
*/
private String description;
/**
* 测试人员姓名
*/
@NotBlank(message = "tester 测试人员姓名不能为空", groups = {Add.class, Update.class})
private String tester;
/**
* 测试步骤List
*/
@Valid
private List<UiCaseStepVo> caseSteps;
@Data
public static class UiCaseStepVo{
@NotNull(message = "caseId 测试用例ID不能为空",groups = {Update.class})
private Long caseId;
@NotBlank(message = "caseCode 测试用例编码不能为空",groups = {Update.class})
private String caseCode;
@NotNull(message = "stepId 步骤ID不能为空",groups = {Update.class})
private Long stepId;
/**
* 步骤顺序号
*/
@NotNull(message = "sort 步骤序号不能为空",groups = {Add.class, Update.class})
private Integer sort;
/**
* 步骤描述
*/
@ExcelProperty("测试步骤描述")
private String description;
/**
* 关键字(操作)编码
*/
@NotBlank(message = "actionKeyword 关键字(操作)编码不能为空",groups = {Add.class, Update.class})
private String actionKeyword;
/**
* 元素定位方式(类型)
*/
private String elementLocateType;
/**
* 元素定位信息
*/
private String elementLocateValue;
/**
* 输入值
*/
private String parameter;
}
}
- 如代码所示,将测试用例各字段都考虑进去,如需扩展API测试,可在放进该对象
- 字段上各校验注解,是用例管理CRUD接口中需要的,与本次分享毫无关系(例如 @NotNull(message = “caseId(用例ID)不能为空”, groups = {Update.class})),如有测试小白,可忽略,作者懒癌犯了,就没删除
3、解析Excel >> 测试用例
这个步骤就是将Excel填写好的测试用例,解析成我们刚才看到的一个个TestCaseVo对象,即List<TestCaseVo>
, 用的EasyExcel工具解析
import cn.hutool.core.util.ObjectUtil;
import cn.nhdc.cloud.common.utils.HttpUtils;
import cn.nhdc.cloud.modules.casemanage.model.vo.ExcelCaseStepVo;
import cn.nhdc.cloud.modules.casemanage.model.vo.TestCaseVo;
import cn.nhdc.cloud.testscripts.config.ReportLog;
import cn.nhdc.cloud.testscripts.testcase.base.TestBase;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xiaoleilu.hutool.bean.BeanUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
*
* @author Fan QingChuan
*/
public interface TestCommon{
/**
* 解析Excel UI测试用例 <br>
* 解析逻辑: 按测试用例编码(caseCode)进行分组,将所有步骤封装到对应用例编码下 <br>
* 与测试用