Go to file
彭宇琦 730a173392 调整等待事件类结构,修改元素重新拉取方法 2020-12-09 07:57:51 +08:00
.settings 添加启动IE浏览器方法 2020-11-08 17:12:53 +08:00
.vscode 添加配置文件抽象类 2020-09-29 20:08:31 +08:00
ConfigurationFiles 完成测试测试用例生成工具改造以及单元测试编写,并删除已作废的测试用例生成工具代码 2020-11-16 14:19:26 +08:00
Readme/Image/TestCase 添加readme所需的素材 2020-08-08 16:41:32 +08:00
Resource/BrowersDriver 添加火狐浏览器,并修改信息输出方法的位置 2020-11-10 08:22:58 +08:00
Result 添加配置文件抽象类 2020-09-29 20:08:31 +08:00
Templet 更换仓库 2020-01-17 17:46:43 +08:00
Test 添加随机词语返回方法 2020-07-04 18:42:13 +08:00
lib 更换仓库 2020-01-17 17:46:43 +08:00
src 调整等待事件类结构,修改元素重新拉取方法 2020-12-09 07:57:51 +08:00
tessdata 更换仓库 2020-01-17 17:46:43 +08:00
设计图 添加元素类 2020-04-19 22:22:01 +08:00
.classpath 调试事件类,使其适应当前元素类,并添加事件及返回值 2020-10-18 16:39:25 +08:00
.factorypath 添加配置文件抽象类 2020-09-29 20:08:31 +08:00
.gitignore 添加元素信息类 2020-09-27 07:58:01 +08:00
.project 更换仓库 2020-01-17 17:46:43 +08:00
LICENSE add LICENSE. 2020-12-07 08:06:47 +08:00
README.md 添加README文件内容 2020-09-06 16:16:29 +08:00
pom.xml 测试pom文件引入javadoc插件 2020-12-08 14:56:47 +08:00

README.md

autest

简介

autest设计初衷

autest为Auxiliary Test的英文缩写意为辅助测试其中包括日常测试工作中能用到的工具包括测试用例编写工具简化Web UI自动化测试工具以及测试报告生成工具和日常工作中使用的小工具等。开发这个项目的目的在于使用简单的代码来简化我们测试日常中较为繁杂的操作使测试的效率得到一定的提升。

autest比起说是一个工具不如说是我在工作中的一个总结在我看来测试工作就是一个机械式的工作既然是机械式的工作就应该用机械来代替抱着这个想法于是我就启动了这个项目。但我并不是开发转测试在大学学习的也是化学工程专业并未系统地学习过软件工程所以在编写代码时会有许多与开发规范不符合的地方关于这点希望大家能在使用时多多海涵同时也希望大家能对工具多多批评和指点我会尽可能地做出改正使工具更加地完善。

目标

autest的目标是使用代码来简化繁杂的测试工作让测试工作变得轻松同时也让不会写代码的测试工程师开始熟悉代码通过代码编写自动化测试脚本脱离被自动化测试软件束缚让自动化测试变得更加自由。

工具概要

模块 介绍
auxiliary.tool 包含日常测试工作中可以使用的测试工具,例如表格处理工具、文本处理工具、日期处理工具等
auxiliary.work.selenium 对Web UI自动化工具selenium的二次封装简化了selenium中比较复杂的代码
auxiliary.work.testcase 用于编写测试用例的工具
auxiliary.work.http 用于做接口测试时使用的工具
auxiliary.work.sql 用于对oralc数据库简单查询的工具

工具介绍

目前整个项目比较成熟的工具是测试用例编写工具和Web UI自动化辅助编码工具下面我将主要介绍这两个工具的使用。

1 测试用例编写工具

该工具是通过预先写好的测试用例文件模板调用其中添加内容的方法对测试用例进行编写之后再生成一个Excel文件以方便测试用例阅读与上传。当然看到这许多人就有疑问了既然最后要生成一个Excel文件那编写测试用例直接在Excel文档里写就好何必还要编写代码然后再生成呢的确在office的Excel软件中其可视化界面确实要比写代码要强很多但Excel软件也存在上下滚动不方便的缺点并且大家也清楚很多测试用例都可以复用在编写过程中难免会有大量的复制和替换的工作对于少量的用例还好一旦用例较多时复制用例后就容易遗漏需要替换文本的用例或者多复制用例导致编写出错。为解决这一类的问题所以我封装了一个测试用例编写工具将测试用例的编写工作由Excel向eclipse不要问我为什么不用IDEA我是特别不喜欢IDEA转移当然缺点就是可视化差了一些。

1.1 测试用例文件创建

1.1.1 测试用例模板配置文件创建

在编写测试用例时,我们需要有一个存放测试用例的文件,之后在文件中编写测试用例,程序中也不例外,首先我们需要创建测试用例模板文件,该模板文件可以是自行创建,也可以是根据配置文件中编写的内容,通过程序进行创建,个人建议选择后者,因为我们创建的配置文件模板是符合我们在类中定义的字段位置的,若是通过自行创建的模板,此时可能遗漏字段或字段位置有误,导致程序失效。下面将介绍如何使用配置文件来创建测试用例模板。

首先配置文件采用xml的文件形式其内容主要是对测试用例模板文件中一些基本的参数进行配置例如行宽、字段名称、是否居中等等其结构如下

<?xml version='1.0' encoding='UTF-8'?>
<templet>
	<sheet name='测试用例' freeze='2'>
		<column id='标题' name='Name' wide='30.88' align='left'/>
		<column id='步骤' name='Test Script (Step-by-Step) - Step' wide='45.75' align='left' row_text='1' index='true'/>

		<datas id='优先级'>
			<data name='High' />
			<data name='Normal' />
			<data name='Low' />
		</datas>
		
		<datas id='项目'>
			<file path='JiraCaseFileTemplet/Jira数据有效性.xlsx' regex='Sheet1' column='0' start_row='1' />
		</datas>
	</sheet>
</templet>

配置文件中的标签解释如下:

  • templet是根标签其不包含属性可包含多个sheet标签
  • sheet标签表示其下的字段标签或数据有效性标签写入的工作簿位置该标签下可有多个column和datas标签其具有以下属性
属性 介绍
name 工作簿的名称,该属性必须存在
freeze 需要冻结的列数值为2表示冻结前两列若不写则表示不冻结
  • column标签表示需要生成到文件中的字段其具有以下属性
属性 介绍
id 程序中的标识符,在程序中填写内容时使用该字段作为传参,该属性必须存在
name 在测试用例模板中的字段名称,该名称不能作为程序中的传参,该属性必须存在
wide 字段在模板文件中所占的宽度,该属性必须存在
align 字段内容在模板文件中的对其方式有三个可选值left左对齐、center(居中对齐)、right右对齐该属性必须存在
row_text 字段每段内容在文件中所占的行数值为1表示每段内容在文件中占1个单元格一段一分行若无该属性则表示所有内容只写在一个单元格中
index 字段每段内容是否自动加上编号有两个可选值true创建编号、false不创建编号若无该属性则默认为false
  • datas标签表示写在sheet标签中的数据有效性内容可包含多个data和file标签其具有以下属性
属性 介绍
id 程序中的标识符,在程序中填写内容时使用该字段作为传参,该属性必须存在
  • data标签表示数据有效性的内容是直接写在xml文件中的数据有效具有以下属性
属性 介绍
name 数据有效性的内容,该属性必须存在
  • file标签表示数据有效性的内容该标签表示需要读取写在其他文件中的数据有效性可与data标签同时存在不会冲突具有以下属性
属性 介绍
path 文件所在路径支持word文件、excel文件、txt文件以及csv文件该属性必须存在
regex 内容切分规则若为excel文件则需要写入需要读取sheet名称若为文本文件则传入切分文件的规则对csv文件则无效该属性必须存在
column 需要读取的列,该属性必须存在
start_row 需要读取的起始行,该属性必须存在
end_row 需要读取的结束行,该属性必须存在

注意file标签所有属性完全参考 pres.auxiliary.work.selenium.datadriven.ListFileRead 类的内容支持的文件及参数介绍可查询该类的api

1.1.2 通过配置文件并创建测试用例模板文件

当我们编辑完配置文件后调用CreateCaseFile中的create()方法即可完成测试用例模板文件的创建具体方法如下假设xml文件放在ConfigurationFiles/jira测试用例导入模板.xml路径下

@Test
public void createCaseTemplate() {
    //模板文件类对象,指向模板文件生成的路径
    File tempFile = new File("Result/测试用例.xlsx");
    //配置文件类对象指向xml配置文件的存放路径
    File conFile = new File("ConfigurationFiles/jira测试用例导入模板.xml");
    
    //构造对象
    CreateCaseFile ccf = new CreateCaseFile(conFile, tempFile);
    //创建文件
    ccf.create();
}

在类中,有提供一种文件的保护机制,在多次生成同一个文件时,是否允许直接覆盖文件,默认是不允许直接覆盖文件,及多次创建文件名相同的文件时,程序将抛出异常,从而保护之前已创建的文件,如有需要,可通过方法将其设置为允许覆盖。例如以下两个测试方法:

@Test
public void createCaseTemplate() {
    //模板文件类对象,指向模板文件生成的路径
    File tempFile = new File("Result/测试用例.xlsx");
    //配置文件类对象指向xml配置文件的存放路径
    File conFile = new File("ConfigurationFiles/jira测试用例导入模板.xml");
    
    //构造对象
    CreateCaseFile ccf = new CreateCaseFile(conFile, tempFile);
    
    //设置允许覆盖文件
	temp.setCoverFile(true);
	temp.create();
	temp.create();
}

@Test(expectedExceptions = IncorrectFileException.class)//捕捉IncorrectFileException异常
public void createCaseTemplate() {
    //模板文件类对象,指向模板文件生成的路径
    File tempFile = new File("Result/测试用例.xlsx");
    //配置文件类对象指向xml配置文件的存放路径
    File conFile = new File("ConfigurationFiles/jira测试用例导入模板.xml");
    
    //构造对象
    CreateCaseFile ccf = new CreateCaseFile(conFile, tempFile);
    
    //设置不允许覆盖
	temp.setCoverFile(false);
	temp.create();
	temp.create();//此时再次调用 创建方法时将抛出IncorrectFileException异常
}

到此,我们查看生成测试用例文件的路径中,已经存在我们测试用例模板文件,可继续进行下一步操作。

1.2 测试用例编写

1.2.1 构造用例编写类对象

首先通过以下xml文件来生成一个测试用例文件模板

<?xml version='1.0' encoding='UTF-8'?>
<templet>
	<sheet name='测试用例' freeze='2'>
		<column id='标题' name='Name' wide='30.88' align='left'/>
		<column id='目的' name='Objective' wide='18.25' align='left'/>
		<column id='前置条件' name='Precondition' wide='18.25' align='left' index='true'/>
		<column id='步骤' name='Test Script (Step-by-Step) - Step' wide='45.75' align='left' row_text='1' index='true'/>
		<column id='预期' name='Test Script (Step-by-Step) - Expected Result' wide='45.75' align='left' row_text='1' index='true'/>
		<column id='模块' name='Folder' wide='22.00' align='center'/>
		<column id='状态' name='Status' wide='10.00' align='center'/>
		<column id='优先级' name='Priority' wide='10.00' align='center'/>
		<column id='项目' name='Component' wide='10.00' align='center'/>
		<column id='设计者' name='Owner' wide='10.00' align='center'/>
		<column id='关键用例' name='关键用例' wide='10.00' align='center'/>
		<column id='关联需求' name='Coverage (Issues)' wide='20.00' align='center'/>
	
		<datas id='状态'>
			<data name='Approved' />
			<data name='Draft' />
			<data name='Deprecated' />
		</datas>
		
		<datas id='优先级'>
			<data name='High' />
			<data name='Normal' />
			<data name='Low' />
		</datas>
		<datas id='关键用例'>
			<data name='是' />
			<data name='否' />
		</datas
    <sheet/>
</templet>

得到测试用例模板文件后我们则需要通过用例模板文件对象和创建模板使用的xml文件对象来构造编写测试用例的类对象这里我们需要调用包中的BasicTestCaseWrite类框架选用TestNG

/**
 * 用例编写类
 */
BasicTestCaseWrite wtc;
/**
 * 配置文件类对象
 */
File conFile = new File("ConfigurationFiles/CaseConfigurationFile/FileTemplet/JiraCaseFileTemplet/jira测试用例导入模板.xml");
/**
 * 模板文件类对象
 */
File tempFile = new File("Result/测试用例.xlsx");

@BeforeClass
public void createTemplet() throws DocumentException, IOException {
	CreateCaseFile temp = new CreateCaseFile(conFile, tempFile);
	temp.setCoverFile(true);
	temp.create();

	wtc = new BasicTestCaseWrite(conFile, tempFile);
}

@AfterClass
public void openFolder() throws IOException {
	wtc.writeFile();
}
1.2.2 添加测试用例

得到了测试用例类对象后,我们则需要对需求中的内容设计测试用例。假设有一个需求,需要对创建账号界面进行测试,界面上有一个姓名文本框(非必填,无输入限制)和一个身份证文本框(必填,校验是否为正确的身份证号),那么,我们需要在测试用例中添加以下用例(简单编写):

  • 对姓名文本框的测试用例:
标题:
    通过不同的姓名创建账号
目的:
    验证创建账号界面各个控件输入是否有效
前置条件:
    1.已在创建账号界面
    2.除姓名字段外,其他信息均正确填写
步骤:
    1.“姓名”文本框不输入任何信息,点击“保存”按钮
    2.在“姓名”文本框中只输入空格,点击“保存”按钮
    3.在“姓名”文本框中输入HTML代码点击“保存”按钮
预期:
    1.账号创建成功
    2.账号创建成功
    3.账号创建成功且HTML代码不会被转义
模块:
    /测试项目/账号管理/创建账号
状态:
    Approved
优先级:
    Normal
项目:
    
设计者:
    test
关键用例:
    否
关联需求:
    TEST-1
  • 对身份证文本框的测试用例:
标题:
    通过不同的身份证创建账号
目的:
    验证创建账号界面各个控件输入是否有效
前置条件:
    1.已在创建账号界面
    2.除身份证字段外,其他信息均正确填写
步骤:
    1.“身份证”文本框不输入任何信息,点击“保存”按钮
    2.在“身份证”文本框中只输入空格,点击“保存”按钮
    3.输入15位的证件信息点击“保存”按钮
    4.输入18位的证件信息点击“保存”按钮
    5.输入末尾带“X”或“x”的证件信息点击“保存”按钮
    6.输入大于18位的数字点击“保存”按钮
    7.输入小于18位但大于15位的数字点击“保存”按钮
    8.输入小于15位的数字点击“保存”按钮
    9.输入不符合证件规则但长度符合规则的数字如123456789012345678点击“保存”按钮
    10.输入非数字字符,点击“保存”按钮
预期:
    1.账号创建失败,并给出相应的提示
    2.账号创建失败,并给出相应的提示
    3.账号创建成功
    4.账号创建成功
    5.账号创建成功
    6.账号创建失败,并给出相应的提示
    7.账号创建失败,并给出相应的提示
    8.账号创建失败,并给出相应的提示
    9.账号创建失败,并给出相应的提示
    10.账号创建失败,并给出相应的提示
模块:
    /测试项目/账号管理/创建账号
状态:
    Approved
优先级:
    Normal
项目:
    
设计者:
    test
关键用例:
    否
关联需求:
    TEST-1

设计好测试用例后,我们则需要将相应的字段,以及内容写入到代码中,此时,我们调用类中的

addContent(String field, String... contents)

方法即可方法第一个参数为xml文件中字段的id属性contents参数表示需要在字段中填写的内容该参数为可变参数可传入多个值每传入一个值表示一行文本在系统内部将自动进行换行若字段值为数据有效性标签的内容则可直接传入数据数据序号需要注意的是数据序号是从1开始。具体代码如下测试方法上接章节开始时编写的代码之后的测试均是如此

@Test
public void addCase() {
    //添加姓名相关的用例
	wtc.addContent("标题", "通过不同的姓名创建账号")
			.addContent("目的", "验证创建账号界面各个控件输入是否有效")
			.addContent("前置条件", 
					"已在创建账号界面", 
					"除姓名字段外,其他信息均正确填写"
					)
			.addContent("步骤", 
					"“姓名”文本框不输入任何信息,点击“保存”按钮", 
					"在“姓名”文本框中只输入空格,点击“保存”按钮", 
					"在“姓名”文本框中输入HTML代码点击“保存”按钮"
					)
			.addContent("预期", 
					"账号创建成功", 
					"账号创建成功", 
					"账号创建成功且HTML代码不会被转义"
					)
			.addContent("模块", "/测试项目/账号管理/创建账号")
			.addContent("状态", "1")
			.addContent("优先级", "2")
			.addContent("项目", "")
			.addContent("设计者", "test")
			.addContent("关键用例", "2")
			.addContent("关联需求", "TEST-1")
			.end();
    
    //添加身份证相关的用例
	wtc.addContent("标题", "通过不同的身份证创建账号")
			.addContent("目的", "验证创建账号界面各个控件输入是否有效")
			.addContent("前置条件", 
					"已在创建账号界面", 
					"除姓身份证段外,其他信息均正确填写"
					)
			.addContent("步骤", 
					"“身份证”文本框不输入任何信息,点击“保存”按钮", 
					"在“身份证”文本框中只输入空格,点击“保存”按钮", 
					"输入15位的证件信息点击“保存”按钮", 
					"输入18位的证件信息点击“保存”按钮", 
					"输入末尾带“X”或“x”的证件信息点击“保存”按钮", 
					"输入大于18位的数字点击“保存”按钮", 
					"输入小于18位但大于15位的数字点击“保存”按钮", 
					"输入小于15位的数字点击“保存”按钮", 
					"输入不符合证件规则但长度符合规则的数字如123456789012345678点击“保存”按钮", 
					"输入非数字字符,点击“保存”按钮"
					)
			.addContent("预期", 
					"账号创建失败,并给出相应的提示", 
					"账号创建失败,并给出相应的提示", 
					"账号创建成功", 
					"账号创建成功", 
					"账号创建成功", 
					"账号创建失败,并给出相应的提示", 
					"账号创建失败,并给出相应的提示", 
					"账号创建失败,并给出相应的提示", 
					"账号创建失败,并给出相应的提示", 
					"账号创建失败,并给出相应的提示"
					)
			.addContent("模块", "/测试项目/账号管理/创建账号")
			.addContent("状态", "1")
			.addContent("优先级", "1")
			.addContent("项目", "")
			.addContent("设计者", "test")
			.addContent("关键用例", "1")
			.addContent("关联需求", "TEST-1")
			.end();
}

运行测试方法后,可以生成如下图的效果:

image

类中还提供了对字段内容进行删除、替换和插入的方法,用法基本与添加测试用例方法类似,这里就不过多赘述,您可参考工具的文档,选择性使用。

需要注意的是在编写完一条测试用例后一定要在末尾加上end()方法,否则该条测试用例不会被记录。

1.2.3 添加字段常量

在上述测试用例中,可以很明显地看出,部分字段的内容其实是重复的,但每一条用例都必须要包含,故需要引入常量的概念,通过对字段设置一次内容,使其在每次执行时会自动将字段的内容填写至测试用例中。当然,通过该方法设置的字段值并非真正意义上的常量,其值是可以改变的,可根据需要,实时改变字段相应的值。调用的方法为:

setFieldValue(String field, String content)

其方法第一个参数为需要写入的字段名,第二个参数为需要在该字段中写入的内容,需要注意的是,字段内容参数不是可变参数,只能传入一个值,需要自行换行。 于是,在上一节中,我们编写的代码则可以改为:

/**
 * 用例编写类
 */
BasicTestCaseWrite wtc;
/**
 * 配置文件类对象
 */
File conFile = new File(
		"ConfigurationFiles/CaseConfigurationFile/FileTemplet/JiraCaseFileTemplet/jira测试用例导入模板.xml");
/**
 * 模板文件类对象
 */
File tempFile = new File("Result/测试用例.xlsx");

@BeforeClass
public void createTemplet() throws DocumentException, IOException {
	//创建测试用例模板文件
	CreateCaseFile temp = new CreateCaseFile(conFile, tempFile);
	temp.setCoverFile(true);
	temp.create();

	//构造用例编写类对象
	wtc = new BasicTestCaseWrite(conFile, tempFile);
	
	//添加常量词语
	wtc.setFieldValue("模块", "/测试项目/账号管理/创建账号");
	wtc.setFieldValue("目的", "验证创建账号界面各个控件输入是否有效");
	wtc.setFieldValue("状态", "1");
	wtc.setFieldValue("设计者", "test");
	wtc.setFieldValue("关联需求", "TEST-1");
}

@AfterClass
public void openFolder() throws IOException {
	//将测试用例内容写入到文件中
	wtc.writeFile();
}

@Test
public void addCase() {
	//添加姓名相关的用例
	wtc.addContent("标题", "通过不同的姓名创建账号")
			.addContent("前置条件", 
					"已在创建账号界面", 
					"除姓名字段外,其他信息均正确填写"
					)
			.addContent("步骤", 
					"“姓名”文本框不输入任何信息,点击“保存”按钮", 
					"在“姓名”文本框中只输入空格,点击“保存”按钮", 
					"在“姓名”文本框中输入HTML代码点击“保存”按钮"
					)
			.addContent("预期", 
					"账号创建成功", 
					"账号创建成功", 
					"账号创建成功且HTML代码不会被转义"
					)
			.addContent("优先级", "2")
			.addContent("关键用例", "2")
			.end();
			
	//添加身份证相关的用例
	wtc.addContent("标题", "通过不同的身份证创建账号")
			.addContent("前置条件", 
					"已在创建账号界面", 
					"除姓身份证段外,其他信息均正确填写"
					)
			.addContent("步骤", 
					"“身份证”文本框不输入任何信息,点击“保存”按钮", 
					"在“身份证”文本框中只输入空格,点击“保存”按钮", 
					"输入15位的证件信息点击“保存”按钮", 
					"输入18位的证件信息点击“保存”按钮", 
					"输入末尾带“X”或“x”的证件信息点击“保存”按钮", 
					"输入大于18位的数字点击“保存”按钮", 
					"输入小于18位但大于15位的数字点击“保存”按钮", 
					"输入小于15位的数字点击“保存”按钮", 
					"输入不符合证件规则但长度符合规则的数字如123456789012345678点击“保存”按钮", 
					"输入非数字字符,点击“保存”按钮"
					)
			.addContent("预期", 
					"账号创建失败,并给出相应的提示", 
					"账号创建失败,并给出相应的提示", 
					"账号创建成功", 
					"账号创建成功", 
					"账号创建成功", 
					"账号创建失败,并给出相应的提示", 
					"账号创建失败,并给出相应的提示", 
					"账号创建失败,并给出相应的提示", 
					"账号创建失败,并给出相应的提示", 
					"账号创建失败,并给出相应的提示"
					)
			.addContent("优先级", "1")
			.addContent("关键用例", "1")
			.end();
}
1.2.4 添加词语替换

在上一节中,我们虽然用常量代替了部分内容,但在用例步骤与预期中仍然存在较多的重复内容,这些内容无法用常量代替。为解决这一问题,类中还提供了一个词语替换的方法,先在使用标记前,对需要替换的词语设置好以后,在文本中使用“#内容#”进行标记即可。替换词语的方法为:

setReplactWord(String word, String replactWord)

方法中,第一个参数表示需要替换的词语,第二个参数表示替换的内容。在传入需要替换的词语时无需加上两个“#”符号。根据上一节编写的测试方法,加上替换词语的方法后,可以将测试方法改写为如下形式:

@Test
public void addCase() {
	wtc.setFieldValue("界面", "已在创建账号界面");
	wtc.setFieldValue("填写", "其他信息均正确填写");
	wtc.setFieldValue("保存", "点击“保存”按钮");
	wtc.setFieldValue("成功", "账号创建成功");
	wtc.setFieldValue("失败", "账号创建失败,并给出相应的提示");
	
	//添加姓名相关的用例
	wtc.addContent("标题", "通过不同的姓名创建账号")
			.addContent("前置条件", "#界面#", "除姓名字段外,#填写#")
			.addContent("步骤", 
					"“姓名”文本框不输入任何信息,#保存#", 
					"在“姓名”文本框中只输入空格,#保存#", 
					"在“姓名”文本框中输入HTML代码#保存#"
					)
			.addContent("预期", 
					"#成功#", 
					"#成功#", 
					"#成功#且HTML代码不会被转义"
					)
			.addContent("优先级", "2")
			.addContent("关键用例", "2")
			.end();

	//添加身份证相关的用例
	wtc.addContent("标题", "通过不同的身份证创建账号")
			.addContent("前置条件", "#界面#", "除姓身份证段外,#填写#")
			.addContent("步骤", 
					"“身份证”文本框不输入任何信息,#保存#", 
					"在“身份证”文本框中只输入空格,#保存#", 
					"输入15位的证件信息#保存#", 
					"输入18位的证件信息#保存#", 
					"输入末尾带“X”或“x”的证件信息#保存#", 
					"输入大于18位的数字#保存#", 
					"输入小于18位但大于15位的数字#保存#", 
					"输入小于15位的数字#保存#", 
					"输入不符合证件规则但长度符合规则的数字如123456789012345678#保存#", 
					"输入非数字字符,#保存#"
					)
			.addContent("预期", 
					"#失败#", 
					"#失败#", 
					"#成功#", 
					"#成功#", 
					"#成功#", 
					"#失败#", 
					"#失败#", 
					"#失败#", 
					"#失败#", 
					"#失败#"
					)
			.addContent("优先级", "1")
			.addContent("关键用例", "1")
			.end();
}

需要注意以下几点:

  1. 标记的词语被重复定义替换的内容时,其替换的内容以最后一次修改为准
  2. 在文本中,若使用了未被定义的词语,则不会被替换,保留原始内容(包括标记符号)

1.3 测试用例模板

一般情况下,我们编写的测试用例大多都是重复的,根据需求描述中相应的规则,对这一类的测试用例进行一定的修改,一条新的用例就写好了。同样的,在程序中,也同样可以使用模板的方式来添加测试用例。当前工具中已提供了部分测试用例模板,可直接调用使用。当然,工具中提供的测试用例模板是按照我的想法写的,可能不能保证您写的用例也是如此,所以在工具中有提供模板的扩展,可供使用。下面先简单介绍测试用例模板写入到测试用例中的方法。

1.3.1 测试用例模板使用

在工具中,我简单编写了添加信息、浏览列表以及地图操作等相关的测试用例,这里就简单介绍如何使用模板。

要使用测试用例模板首先需要对用例模板的内容进行存储同样存储模板也是用过xml文件的形式。由于模板是已经写好的内容过长就不在这里展示可在项目下的“ConfigurationFiles/CaseConfigurationFile/CaseTemplet”文件夹中找到所有的模板。 在上一节中,我们编写的新增账号时对身份证和姓名的测试用例实际可以使用模板来进行代替,使用的模板就是添加信息模板,通过调用测试用例模板类中的方法,从而达到添加测试用例的目的。

首先我们需要构造信息编辑用例模板类InformationCase并将测试用例模板中的字段与测试用例文件模板的字段进行一个关联由于测试用例模板配置文件的写法是固定的所以我们只需要定义一次用例模板字段即可。关联测试用例的方法为

relevanceCase(String field, String labelType)

其第一个参数为在测试用例文件模板xml文件中的字段id第二个参数为测试用例模板中的标签名称该名称可以通过LabelType枚举类进行获取亦可直接填入。为便于今后的扩展故没有把labelType参数作为枚举故在获取到枚举值后再调用枚举中的getName()方法进行,返回相应的标签名称。

在得到类对象后我们还需要对模板中部分内容进行替换就如同您从其他位置将模板内容复制到excel中然后逐个替换为所需要的内容一样。替换词语的方法为

setReplaceWord(String word, String text)

用法与用例编写类中的替换词语方法类似,需要替换的词语可以使用类名调用,您可选择性使用并进行替换。建议您在查看用例模板后,尽可能替换相应的内容。

了解上述两个方法后,于是我们需要修改上一节中的前置条件方法:

@BeforeClass
public void createTemplet() throws DocumentException, IOException {
	//创建测试用例模板文件
	CreateCaseFile temp = new CreateCaseFile(conFile, tempFile);
	temp.setCoverFile(true);
	temp.create();

	//构造用例编写类对象
	wtc = new BasicTestCaseWrite(conFile, tempFile);
	
	//添加常量词语
	wtc.setFieldValue("模块", "/测试项目/账号管理/创建账号");
	wtc.setFieldValue("目的", "验证创建账号界面各个控件输入是否有效");
	wtc.setFieldValue("状态", "1");
	wtc.setFieldValue("设计者", "test");
	wtc.setFieldValue("关联需求", "TEST-1");
	
	//添加与测试用例模板的字段关联
	wtc.relevanceCase("步骤", LabelType.STEP.getName());
	wtc.relevanceCase("预期", LabelType.EXCEPT.getName());
	wtc.relevanceCase("前置条件", LabelType.PRECONDITION.getName());
	wtc.relevanceCase("优先级", LabelType.RANK.getName());
	wtc.relevanceCase("标题", LabelType.TITLE.getName());
	
	//构造测试用例模板类对象
	ic = new InformationCase(caseTempFile);
	//添加需要替换的词语
	ic.setReplaceWord(InformationCase.ADD_INFORMATION, "账号");
	ic.setReplaceWord(InformationCase.BUTTON_NAME, "保存");
}

当我们完成以上构造后,我们只需要调用方法,写入测试用例模板即可,这里需要使用以下方法,首先测试用例编写类中写入测试用例模板文本的方法:

addCase(Case testCase)

传入的参数为继承至Case类的测试用例模板类。在案例中姓名与身份证分别用到测试用例模板的以下方法

//添加姓名
addBasicTextboxCase(String name, boolean isMust, boolean isRepeat, boolean isClear, InputRuleType... inputRuleTypes)
//添加身份证
addIdCardCase(String name, boolean isMust, boolean isRepeat, boolean isClear)

在方法中各个参数表示控件的个性化内容由于参数过多就不大篇幅介绍您可以参考项目的API文档。于是我们可以将上一节中的测试方法改为

@Test
public void addCase() {
	wtc.addCase(ic.addBasicTextboxCase("姓名", false, true, false)).end();
	wtc.addCase(ic.addIdCardCase("身份证", true, false, false)).end();
}
1.3.2 测试用例模板文件扩展

同配置测试用例文件模板一样测试用例模板也是通过xml文件进行配置目的是为了方便后续的字段扩展以及用例的扩展其xml文件相对与文件模板而言就简单一些大致结构如下

<?xml version='1.0' encoding='UTF-8'?>
<cases>
	<case name=''>
		<steps>
			<step id='' value=''/>
			<step id='' value=''/>
		</steps>
		<excepts>
			<except id='' value=''/>
		</excepts>
		<titles>
			<title id='' value='' />
		</titles>
		<preconditions>
			<precondition id='' value='' />
		</preconditions>
		<ranks>
			<rank id='' value='' />
		</ranks>
		<keys>
			<key id='' value='' />
		</keys>
	</case>
</cases>

当然除了编写配置文件外我们还需要编写一个类这样才能实现测试用例的扩展其测试用例类的编写将在下一节中讲解。先解释下xml配置文件的标签

  • cases是根标签其不包含属性可包含多个case标签
  • case标签表示一条用例模板的开始可包含测试用例所需要的字段内容标签子标签可根据需要进行扩展但扩展的标签需要按照一定的规则编写其具有以下属性
属性 介绍
name 标记用例在代码中的标识,代码中将根据该字段查找相应的用例模板,该属性必须存在

--case下其他子标签用例标签下的子标签为扩展的字段标签表示用例下的字段的取值可以在其中找到虽然该标签可以自定义但还是需要遵循一定的规则

  1. 字段的名称必须是“扩展字段名+"s"”例如其中的steps、titles等标签
  2. 其标签下必须包含与其同名但不包含s的标签表示该字段的可选值例如steps下的step。该标签可以同时存在多个其应包含以下属性
属性 介绍
id 标记该可选值在代码中的标识,在代码中使用其值时通过该属性值获取,该属性必须存在
value 表示需要填写至测试用例中的内容,该属性必须存在

需要注意的是标签的value属性允许编写可替换的词语使用“*{词语}*”进行标记

例如,以下是一个比较完整的测试用例模板配置文件,截取至已有的文件:

<?xml version='1.0' encoding='UTF-8'?>
<cases project='BrowseList'>
	<case name='addAppBrowseListCase'>
		<titles>
			<title id='1' value='浏览*{信息}*列表' />
		</titles>
		<keys>
			<key id='1' value='*{信息}*列表,刷新,加载' />
		</keys>
		<ranks>
			<rank id='1' value='1' />
		</ranks>
		<preconditions>
			<precondition id='1' value='列表中有信息存在' />
		</preconditions>
		<steps>
			<step id='1' value='查看*{信息}*列表' />
			<step id='2' value='下拉刷新列表' />
			<step id='3' value='上拉加载列表' />
			<step id='4' value='在无剩余数据时,上拉加载列表' />
			<step id='5' value='加载或刷新列表时点击某一个信息或某一个按钮' />
		</steps>
		<excepts>
			<except id='1' value='能看到当前存在的所有信息,且信息按一定规则排序'/>
			<except id='2' value='列表被刷新,若有新增信息则被显示出来,且原有数据排序不会混乱'/>
			<except id='3' value='能加载剩下的信息'/>
			<except id='4' value='上拉有效,但不加载出数据或数据不会错乱'/>
			<except id='5' value='app不会闪退且能正常显示'/>
		</excepts>
	</case>
	
	<case name='addWebBrowseListCase'>
		<titles>
			<title id='1' value='浏览*{信息}*列表' />
		</titles>
		<keys>
			<key id='1' value='*{信息}*列表,刷新,加载' />
		</keys>
		<ranks>
			<rank id='1' value='1' />
		</ranks>
		<preconditions>
			<precondition id='1' value='列表中有信息存在' />
		</preconditions>
		<steps>
			<step id='1' value='查看*{信息}*列表' />
			<step id='2' value='翻页查看*{信息}*列表' />
			<step id='3' value='在首页上点击“首页”按钮' />
			<step id='4' value='在首页上点击“上一页”按钮' />
			<step id='5' value='在尾页上点击“尾页”按钮' />
			<step id='6' value='在尾页上点击“下一页”按钮' />
		</steps>
		<excepts>
			<except id='1' value='能看到当前存在的所有信息,且信息按一定规则排序'/>
			<except id='2' value='能看到不同页上的列表信息,且切换页后列表的排序不变'/>
			<except id='3' value='按钮无法点击或点击无效,且当前页列表排序不变'/>
			<except id='4' value='按钮无法点击或点击无效,且当前页列表排序不变'/>
			<except id='5' value='按钮无法点击或点击无效,且当前页列表排序不变'/>
			<except id='6' value='按钮无法点击或点击无效,且当前页列表排序不变'/>
		</excepts>
	</case>
</cases>
1.3.3 测试用例模板类代码扩展

由于公司不同或者说测试用例编写风格不同,其测试用例的字段也大相径庭,为避免模板过于死板,所以就没对模板中的字段做过多的指定,也正因如此,才需要编写一个与之匹配的测试用例模板类来支撑测试用例的获取。 首先我们先创建一个类命名为“MyCacse”并继承包中的“pres.auxiliary.work.testcase.templet.Case”类添加两个父类的构造方法后可得到如下'代码:

public class MyCase extends Case {
	public MyCase(File configXmlFile) {
		super(configXmlFile);
	}
}

之后便是获取测试用例模板xml文件中的内容这里将要用到内容获取以及词语替换方法。
内容获取: 即从测试用例模板xml文件中获取到相应的文本内容。在父类中提供了

protected String getLabelText(String caseName, String labelName, String id)

方法用于获取到在xml文件中指定标签下的内容其caseName参数与case标签的name属性对应labelName属性与case标签下的字段标签名称对应不带“s”的标签id与相应字段标签中的id属性对应。例如在上述xml文件中我们要获取用例名称为"BrowseList"下的steps标签下的第四个子标签的内容

String text = getLabelText("addAppBrowseListCase", "step", "4");

单词替换: 在上一节介绍中,有提到关于词语的替换,需要使用“*{单词}*”来标记在调用getLabelText方法后系统会查找预设替换的词语若存在与之匹配的词语后则对文本进行词语替换。设置预设词语则需要使用父类的一个属性“wordMap”该属性是一个HashMap类直接调用其put方法添加需要替换的词语即可。例如我们需要替换上述例子中的“信息”词语

wordMap.put("信息", "用户");

文本存储: 当我们获取到写在xml文件内容并添加了相应需要替换的词语后我们就需要将用例文本的最终内容写入到类中进行存储以方便写入到测试用例文件中。存储测试用例文本的方法也写在父类中可调用以下方法

protected void addFieldText(String labelName, String text)

其中labelName为在需要写入的类中的字段名称其必须与写在xml文件中的标签字段名称一致否则在调用方式时将抛出异常text即需要写入的内容。使用该方法不仅可以写入在xml文件获取的内容也可以写入自定义的内容。该方法还有三个重载方法

protected void addFieldText(String labelName, List<String> texts)
protected void addFieldText(LabelType label, String text)
protected void addFieldText(LabelType label, List<String> texts)

对于第一个重载方法即可根据字段内容传入一组文本内容。对于第三、四个重载方法其形参label表示标签枚举即对于一些常用的标签进行了枚举方便标签名称与关联字段能统一进行管理具体枚举的内容可参考代码中的LabelType枚举类。 例如对于上述xml中我们需要获取并存储第一条用例的标题时可以通过以下方法实现

addFieldText("title", getLabelText("addAppBrowseListCase", "title", "1"));

或者

addFieldText(LabelType.TITLE, getLabelText("addAppBrowseListCase", LabelType.TITLE, "1"));

通过以上介绍的方法并对需要获取的测试用例内容自由获取、组合便可得到一个测试用例模板类。例如上述的MyCase类我们可以做如下的改造

public class MyCase extends Case {
	public MyCase(File configXmlFile) {
		super(configXmlFile);
	}
	
	public Case appBrowseListCase() {
	    //必须调用该方法来清除类中上一次调用存储的内容,否则会重复
		clearFieldText();
		wordMap.put("信息", "用户");
		String caseName = "addAppBrowseListCase";
		addFieldText(LabelType.TITLE, getLabelText(caseName, LabelType.TITLE, "1"));
		relevanceAddData(caseName, ALL, ALL);
		addFieldText(LabelType.PRECONDITION, getAllLabelText(caseName, LabelType.PRECONDITION));
		addFieldText(LabelType.KEY, getLabelText(caseName, LabelType.KEY, "1"));
		addFieldText(LabelType.RANK, getLabelText(caseName, LabelType.RANK, "1"));
		return this;
	}
	
	public Case webBrowseListCase() {
		clearFieldText();
		wordMap.put("信息", "用户");
		String caseName = "addWebBrowseListCase";
		addFieldText(LabelType.TITLE, getLabelText(caseName, LabelType.TITLE, "1"));
		relevanceAddData(caseName, ALL, ALL);
		addFieldText(LabelType.PRECONDITION, getAllLabelText(caseName, LabelType.PRECONDITION));
		addFieldText(LabelType.KEY, getLabelText(caseName, LabelType.KEY, "1"));
		addFieldText(LabelType.RANK, getLabelText(caseName, LabelType.RANK, "1"));
		return this;
	}
}

之后,我们在写入测试用例用例类中,构造该类,并调用其中的方法,即可将模板中的内容写入到测试用例文件中

1.4 测试用例字段标记

1.5 测试用例编写类扩展

1.5.1 jira测试用例编写类的使用
1.5.2 自定义测试用例编写类
1.5.3 测试用例模板类字段枚举(可选)