完成测试测试用例生成工具改造以及单元测试编写,并删除已作废的测试用例生成工具代码

This commit is contained in:
彭宇琦 2020-11-16 14:19:26 +08:00
parent f36fd8dba3
commit cbb1a13cf1
41 changed files with 324 additions and 6937 deletions

View File

@ -2,13 +2,13 @@
<cases project="Video">
<case name="addPlayVideoCase">
<titles>
<title value="播放/暂停*{视频类型}*" />
<title id='1' value="播放/暂停*{视频类型}*" />
</titles>
<keys>
<key value="播放/暂停" />
<key id='1' value="播放/暂停" />
</keys>
<ranks>
<rank value="1" />
<rank id='1' value="1" />
</ranks>
<preconditions>
</preconditions>
@ -32,13 +32,13 @@
<case name="addVideoScreenshotCase">
<titles>
<title value="对*{视频类型}*进行截图" />
<title id='1' value="对*{视频类型}*进行截图" />
</titles>
<keys>
<key value="*{视频类型}*,截图" />
<key id='1' value="*{视频类型}*,截图" />
</keys>
<ranks>
<rank value="2" />
<rank id='1' value="2" />
</ranks>
<preconditions>
</preconditions>
@ -58,13 +58,13 @@
<case name="addVideoAdvanceCase">
<titles>
<title value="快进/快退*{视频类型}*" />
<title id='1' value="快进/快退*{视频类型}*" />
</titles>
<keys>
<key value="*{视频类型}*,快进,快退" />
<key id='1' value="*{视频类型}*,快进,快退" />
</keys>
<ranks>
<rank value="2" />
<rank id='1' value="2" />
</ranks>
<preconditions>
</preconditions>
@ -96,13 +96,13 @@
<case name="addVideoSpeedCase">
<titles>
<title value="快放/慢放*{视频类型}*" />
<title id='1' value="快放/慢放*{视频类型}*" />
</titles>
<keys>
<key value="*{视频类型}*,快放,慢放" />
<key id='1' value="*{视频类型}*,快放,慢放" />
</keys>
<ranks>
<rank value="2" />
<rank id='1' value="2" />
</ranks>
<preconditions>
</preconditions>
@ -122,13 +122,13 @@
<case name="addVideoProgressBarCase">
<titles>
<title value="拖动进度条" />
<title id='1' value="拖动进度条" />
</titles>
<keys>
<key value="进度条" />
<key id='1' value="进度条" />
</keys>
<ranks>
<rank value="2" />
<rank id='1' value="2" />
</ranks>
<preconditions>
</preconditions>
@ -149,13 +149,13 @@
<case name="addFullScreenPlayCase">
<titles>
<title value="全屏播放*{视频类型}*" />
<title id='1' value="全屏播放*{视频类型}*" />
</titles>
<keys>
<key value="全屏*{视频类型}*" />
<key id='1' value="全屏*{视频类型}*" />
</keys>
<ranks>
<rank value="2" />
<rank id='1' value="2" />
</ranks>
<preconditions>
</preconditions>

View File

@ -1,164 +0,0 @@
package pres.auxiliary.work.old.testcase.change;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import pres.auxiliary.work.old.testcase.exception.IncorrectCaseFileException;
public abstract class CaseAttribute {
// 用于指向测试用例文件
protected static File excel;
// 用于设置是否允许覆盖已有的文字默认为不允许
protected static boolean isReplace = false;
//用于指向测试用例文件中需要添加或修改的测试用例的实际位置
protected static int rowNum = 0;
//用于存储单元格所在的列数
protected static int cellNum = 0;
/**
* 该方法用于设置需要添加或修改的测试用例在文件中的实际位置
* @param rowNum 需要添加或修改的测试用例在文件中的实际位置
*/
public void setRowNum(int rowNum) {
CaseAttribute.rowNum = rowNum;
}
/**
* 用于设置是否允许覆盖已有的文字true时则表示可以覆盖false表示不可以覆盖
*/
public void isReplace(boolean isReplace) {
CaseAttribute.isReplace = isReplace;
}
/**
* 用于指向测试用例文件
* @param excelFile 测试用例文件的文件对象
*/
public void setExcel(File excel) {
if ( excel == null ) {
throw new IncorrectCaseFileException("未定义测试用例文件");
}
CaseAttribute.excel = excel;
}
/**
* 该方法用于创建一个XSSFWorkbook对象
*
* @return
* @throws IOException
*/
protected XSSFWorkbook before() throws IOException {
FileInputStream fip = new FileInputStream(excel);
XSSFWorkbook xw = new XSSFWorkbook(fip);
fip.close();
return xw;
}
/**
* 该方法用于将修改后的表格写入测试用例文件中
*
* @param xw
* @throws IOException
*/
protected void after(XSSFWorkbook xw) throws IOException {
FileOutputStream fop = new FileOutputStream(excel);
xw.write(fop);
fop.close();
}
/**
* 该方法用于读取并通过字符串的形式返回单元格的值
*
* @param cell
* @return
*/
protected String valueOf(XSSFCell cell) {
String s;
if (cell.getCellTypeEnum().equals(CellType.STRING) ) {
s = cell.getStringCellValue();
}
else if (cell.getCellTypeEnum().equals(CellType.NUMERIC)) {
if (DateUtil.isCellDateFormatted(cell)) {
double d = cell.getNumericCellValue();
Date date = DateUtil.getJavaDate(d);
s = new SimpleDateFormat("yyyy-MM-dd").format(date);
} else {
s = String.valueOf((int) cell.getNumericCellValue());
}
} else if (cell.getCellTypeEnum().equals(CellType.BLANK)) {
s = "";
} else if (cell.getCellTypeEnum().equals(CellType.BOOLEAN)) {
s = String.valueOf(cell.getBooleanCellValue());
} else if (cell.getCellTypeEnum().equals(CellType.ERROR)) {
s = "";
} else if (cell.getCellTypeEnum().equals(CellType.FORMULA)) {
s = cell.getCellFormula().toString();
} else {
s = null;
}
return s;
}
//TODO 模板问题暂缓计划直接写将模版存储在XML中并根据不同的类传值写入的文件不同
/**
* 该方法用于返回存储在类的中的模版列表
*
* @return 存储在类的中的模版列表
*/
/*
public ArrayList<StringBuilder> getTemplates() {
return templates;
}
*/
/**
* 该方法用于向类中写入模版
*
* @param templates
* 需要写入的模版
* @see #setTemplate(List)
*/
/*
public void setTemplate(String... templates) {
for (String template : templates) {
this.templates.add(new StringBuilder(template));
}
}
*/
/**
* 该方法用于向类中写入模版
*
* @param templates
* 需要写入的模版
* @see #setTemplate(String...)
*/
/*
public void setTemplate(List<StringBuilder> templates) {
this.templates.addAll(templates);
}
*/
/**
* 该方法用于将模版存储在xml文件中
*/
/*
public void templateToXml() {
}
*/
}

View File

@ -1,201 +0,0 @@
package pres.auxiliary.work.old.testcase.change;
import java.io.File;
import java.io.IOException;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* 该方法扩充了对测试用例进行标记方法
*
* @author 彭宇琦
* @version V1.0
* @since JDK1.7
* @since POI3.10
*/
public class CaseTab extends Tab {
// 用于构造对象
private static CaseTab c = null;
/**
* 私有构造禁止直接创建类对象
* */
private CaseTab(File caseFile) {
// TODO CaseTab(File caseFile)
super(caseFile);
}
/**
* 该方法用于构造CaseTab对象
*
* @param caseFile
* 测试用例文件对象
* @return CaseTab对象
*/
public static CaseTab newInstence(File caseFile) {
// TODO newInstence(File caseFile)
// 判断类中的属性c是否已被构造若未被构造则进行构造对象操作若已被构造则将传入的文件对象赋给属性中
if (c == null) {
c = new CaseTab(caseFile);
} else {
Tab.caseFile = caseFile;
}
return c;
}
/**
* 该方法用于向指定行的第三列即用例标题那一列中设置一个注释
*
* @param rowNum
* 行数
* @param content
* 注释的内容
* @return CaseTab对象
* @throws IOException
*/
public CaseTab setTab(int rowNum, String content) throws IOException {
// TODO setTab(int rowNum, String content)
return (CaseTab) setTab(before(), rowNum, 2, content);
}
/**
* 该方法用于向指定单元格中设置一个注释需要传入制定行中对应的列名称
*
* @param rowNum
* 指定的行
* @param tableName
* 列的名称
* @param content
* 标注的内容
* @return
* @throws IOException
*/
public CaseTab setTab(int rowNum, String tableName, String content)
throws IOException {
// TODO setTab(int rowNum, String tableName, String content)
int cellNum = 2;
if (tableName != null) {
if ("所属模块".equals(tableName)) {
cellNum = 0;
} else if ("相关需求".equals(tableName)) {
cellNum = 1;
} else if ("用例标题".equals(tableName)) {
cellNum = 2;
} else if ("步骤".equals(tableName)) {
cellNum = 3;
} else if ("预期".equals(tableName)) {
cellNum = 4;
} else if ("关键词".equals(tableName)) {
cellNum = 5;
} else if ("用例类型".equals(tableName)) {
cellNum = 6;
} else if ("优先级".equals(tableName)) {
cellNum = 7;
} else if ("用例状态".equals(tableName)) {
cellNum = 8;
} else if ("适用阶段".equals(tableName)) {
cellNum = 9;
} else if ("前置条件".equals(tableName)) {
cellNum = 10;
}
}
return setTab(rowNum, cellNum, content);
}
/**
* 该方法用于向指定行与指定的列中设置一个注释
*
* @param rowNum
* 行数
* @param cellNum
* 列数
* @param content
* 注释的内容
* @return CaseTab对象
* @throws IOException
*/
public CaseTab setTab(int rowNum, int cellNum, String content)
throws IOException {
// TODO setTab(int rowNum, int cellNum, String content)
return (CaseTab) setTab(before(), rowNum, cellNum, content);
}
/**
* 该方法用于向指定的单元格中的字体设置颜色标注需要传入制定行中对应的列名称
*
* @param rowNum
* 行数
* @param tableName
* 列名称
* @param color
* 颜色代码可在类中选择
* @return CaseTab对象
* @throws IOException
*/
public CaseTab setTableColorTab(int rowNum, String tableName, short color)
throws IOException {
//TODO setTableColorTab(int rowNum, String tableName, short color)
//给表格列数一个默认值即默认标记指定行的用例标题那一列
int cellNum = 2;
if (tableName != null) {
if ("所属模块".equals(tableName)) {
cellNum = 0;
} else if ("相关需求".equals(tableName)) {
cellNum = 1;
} else if ("用例标题".equals(tableName)) {
cellNum = 2;
} else if ("步骤".equals(tableName)) {
cellNum = 3;
} else if ("预期".equals(tableName)) {
cellNum = 4;
} else if ("关键词".equals(tableName)) {
cellNum = 5;
} else if ("用例类型".equals(tableName)) {
cellNum = 6;
} else if ("优先级".equals(tableName)) {
cellNum = 7;
} else if ("用例状态".equals(tableName)) {
cellNum = 8;
} else if ("适用阶段".equals(tableName)) {
cellNum = 9;
} else if ("前置条件".equals(tableName)) {
cellNum = 10;
}
}
setTableColorTab(rowNum, cellNum, color);
return c;
}
/**
* 该方法用于向指定的单元格中的字体设置颜色标注
*
* @param rowNum
* 行数
* @param cellNum
* 列数
* @param color
* 颜色代码可在类中选择
* @return CaseTab对象
* @throws IOException
*/
public CaseTab setTableColorTab(int rowNum, int cellNum, short color)
throws IOException {
//TODO setTableColorTab(int rowNum, int cellNum, short color)
// 获取工作表
XSSFWorkbook xw = before();
XSSFSheet xs = xw.getSheetAt(0);
// 设置单元格内字体颜色
setColorTab(xs.getRow(rowNum).getCell(cellNum), color);
after(xw);
return c;
}
}

View File

@ -1,41 +0,0 @@
package pres.auxiliary.work.old.testcase.change;
import java.io.File;
import pres.auxiliary.work.old.testcase.exception.IncorrectCaseFileException;
public abstract class ChangeCase {
//用于指向测试用例文件
private static File excel;
//用于存储指定修改测试用例文件中的行数
private static int rowNum;
/**
* 指定测试用例文件对象
* @param excel 测试用例文件对象
* @param rowNum 文件中需要修改的测试用例位置所在表格的实际行数
*/
public ChangeCase(File excel, int rowNum) {
//判断文件对象是否定义
if ( excel == null ) {
throw new IncorrectCaseFileException("未定义测试用例文件");
}
//判断传入行数是否有意义
if ( rowNum < 1 ) {
throw new IncorrectCaseFileException("指定的行数无意义");
}
ChangeCase.excel = excel;
//传入的是实际行数所以要减去1
ChangeCase.rowNum = rowNum - 1;
}
/**
* 该方法用于编辑标题
* @return Title对象
*/
public Title changeTitle() {
return Title.newInstence(excel, rowNum, true);
}
}

View File

@ -1,5 +0,0 @@
package pres.auxiliary.work.old.testcase.change;
public class Expectation {
}

View File

@ -1,51 +0,0 @@
package pres.auxiliary.work.old.testcase.change;
import java.io.IOException;
/**
* 该接口定义对单步内容进行的操作
* @author 彭宇琦
*/
interface OperationContent {
/**
* 用于存储单元格中的内容
*/
StringBuilder content = new StringBuilder("");
/**
* 该方法用于返回单元格被修改前的内容
* @return 单元格被修改前的内容
*/
public String getPreviousContent();
/**
* 该方法用于将需要设置的内容写入到单元格中该方法检查是否允许覆盖原有内容
* @param content 需要在单元格中填写的内容
* @throws IOException
*/
public OperationContent write(String content) throws IOException;
/**
* 该方法用于清空单元格中的内容该方法不检查是否允许覆盖原有内容
* @return
* @throws IOException
*/
public OperationContent clear() throws IOException;
/**
* 该方法用于替换文本中的内容该方法不检查是否允许覆盖原有内容
* @param findText 需要查找的内容
* @param replaceText 待替换的内容
* @return
* @throws IOException
*/
public OperationContent replace(String findText, String replaceText) throws IOException;
/**
* 该方法用于删除指定的内容该方法不检查是否允许覆盖原有内容
* @param findText 需要被删除的内容
* @return
* @throws IOException
*/
public OperationContent delete(String findText) throws IOException;
}

View File

@ -1,21 +0,0 @@
package pres.auxiliary.work.old.testcase.change;
import java.util.ArrayList;
/**
* 该接口用于设置有多条内容需要写入时使用的的便捷方法
* @author 彭宇琦
* @version Ver1.0
*/
interface OperationContents {
/**
* 用于存储单元格中的多条内容
*/
ArrayList<StringBuilder> content = new ArrayList<>();
/**
* 该方法用于将需要设置多条的容写入到单元格中调用该方法用可不需要自行添加序号及换行
* @param contents 需要在单元格中填写的多条内容
*/
public void write(String... contents);
}

View File

@ -1,5 +0,0 @@
package pres.auxiliary.work.old.testcase.change;
public class Precondition {
}

View File

@ -1,5 +0,0 @@
package pres.auxiliary.work.old.testcase.change;
public class Step {
}

View File

@ -1,300 +0,0 @@
package pres.auxiliary.work.old.testcase.change;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import pres.auxiliary.work.old.testcase.writecase.Case;
/**
* 该类提供标记测试用例文件中最后一条测试用例的一些方法包括添加注释改变整行字体颜色和改变某一步骤的字体颜色
*
* @author 彭宇琦
* @version V1.1
* @since JDK1.7
* @since POI3.17
*/
public class Tab {
// 用于构造对象
private static Tab t = null;
// 用于指向测试用例文件
protected static File caseFile;
// 添加字体颜色
/**
* 设置字体颜色为红色
*/
public static final short RED = IndexedColors.RED.getIndex();
/**
* 设置字体颜色为黄色
*/
public static final short YELLOW = IndexedColors.YELLOW.getIndex();
/**
* 设置字体颜色为蓝色
*/
public static final short BLUE = IndexedColors.BLUE.getIndex();
/**
* 设置字体颜色为绿色
*/
public static final short GREEN = IndexedColors.GREEN.getIndex();
/**
* 私有构造禁止直接创建类对象
* */
protected Tab(File caseFile) {
Tab.caseFile = caseFile;
}
/**
* 该方法用于构造CaseTab对象
*
* @param caseFile
* 测试用例文件对象
* @return Tab对象
*/
public static Tab newInstence(File caseFile) {
// 判断类中的属性c是否已被构造若未被构造则进行构造对象操作若已被构造则将传入的文件对象赋给属性中
if (Tab.caseFile != caseFile) {
t = new Tab(caseFile);
}
return t;
}
/**
* 该方法用于向测试用例文件最后一行的第三列即用例标题那一列中设置一个注释
*
* @param content
* 注释的内容
* @return Tab对象
* @throws IOException
*/
public Tab setTab(String content) throws IOException {
XSSFWorkbook xw = before();
return setTab(xw, Case.getInsertRowNum(), 2, content);
}
/**
* 该方法用于将最后一行标记为指定的颜色
*
* @param color
* 颜色代码可在类中选择
* @return Tab对象
* @throws IOException
*/
public Tab setRowColorTab(short color) throws IOException {
// 获取工作表
XSSFWorkbook xw = before();
XSSFSheet xs = xw.getSheetAt(0);
// 获取最后一行
XSSFRow xr = xs.getRow(Case.getInsertRowNum());
// 循环标记该段落所有单元格的颜色
for (int i = 0; i < xr.getLastCellNum() + 1; i++) {
try {
setColorTab(xr.getCell(i), color);
} catch (NullPointerException e) {
continue;
}
}
after(xw);
return this;
}
/**
* 该方法用于为用例某一个步骤添加颜色标记
* @param step 指定的步骤
* @param color 标记的颜色
* @return Tab对象
* @throws IOException
*/
public Tab setStepColorTab(int step, short color) throws IOException {
// 获取工作表
XSSFWorkbook xw = before();
XSSFSheet xs = xw.getSheetAt(0);
setStepColorTab(xw, xs.getRow(Case.getInsertRowNum()).getCell(3), xs
.getRow(Case.getInsertRowNum()).getCell(4), step, color);
after(xw);
return this;
}
/**
* 该方法用于创建一个XSSFWorkbook对象
*
* @return
* @throws IOException
*/
protected XSSFWorkbook before() throws IOException {
FileInputStream fip = new FileInputStream(caseFile);
XSSFWorkbook xw = new XSSFWorkbook(fip);
fip.close();
return xw;
}
/**
* 该方法用于将修改后的表格写入测试用例文件中
*
* @param xw
* @throws IOException
*/
protected void after(XSSFWorkbook xw) throws IOException {
FileOutputStream fop = new FileOutputStream(caseFile);
xw.write(fop);
fop.close();
}
/**
* 该方法用于向单元格添加标注
*
* @param xw
* @param rowNum
* @param content
* @return
* @throws IOException
*/
protected Tab setTab(XSSFWorkbook xw, int rowNum, int cellNum,
String content) throws IOException {
// 读取第一个工作表
XSSFSheet xs = xw.getSheetAt(0);
/*
* //创建一个poi工具类用于创建标注 CreationHelper ch = xw.getCreationHelper();
* //创建一个换图对象 Drawing dr = xs.createDrawingPatriarch();
* //ClientAnchor是附属在WorkSheet上的一个对象用于将标注其固定在一个单元格的左上角和右下角.
* ClientAnchor ca = ch.createClientAnchor();
*/
// 创建一个标注并确定其在一个单元格的左上角和右下角
Comment com = xs.createDrawingPatriarch().createCellComment(
xw.getCreationHelper().createClientAnchor());
// 创建标注的内容
com.setString(xw.getCreationHelper().createRichTextString(content));
// 创建标注的作者(作者为计算机名称)
com.setAuthor(System.getenv().get("COMPUTERNAME"));
// 将标注附加到单元格上
xs.getRow(rowNum).getCell(cellNum).setCellComment(com);
// 写入测试用例文件
after(xw);
return this;
}
/**
* 该方法用于对单元格设置颜色标记
*
* @param xc
* @param rowNum
* @param cellNum
* @param color
* @throws IOException
*/
protected void setColorTab(XSSFCell xc, short color) throws IOException {
// 获取单元格的样式并设置字体颜色
XSSFCellStyle xcs = xc.getCellStyle();
XSSFFont xf = xcs.getFont();
xf.setColor(color);
// 将样式表设置回单元格中
xc.setCellStyle(xcs);
}
/**
* 该方法用于设置用例
*
* @param stxc
* 步骤单元格
* @param exxc
* 预期单元格
* @param step
* 待标记的步骤
* @param color
* 待标记的颜色
*/
protected void setStepColorTab(XSSFWorkbook xw, XSSFCell stxc,
XSSFCell exxc, int step, short color) throws IOException {
// color)
// 如果单元格没有数据则直接返回
if (stxc == null || exxc == null) {
return;
}
/*
* 颜色需要重新创建不能直接读取 // 获取单元格的样式并设置字体颜色 XSSFFont stxf =
* stxc.getCellStyle().getFont(); stxf.setColor(color); XSSFFont exxf =
* exxc.getCellStyle().getFont(); exxf.setColor(color);
*/
// 判断单元格中是否存在数据如果不存在则直接返回
String[] st = stxc.getStringCellValue().split("\n");
String[] ex = exxc.getStringCellValue().split("\n");
// 由于第一步与其他步骤的处理方式不同故需要单独分离
if (step == 1) {
// 将新的样式设置入指定的步骤中
stxc.getRichStringCellValue().applyFont(0, st[0].length(),
font(xw, color));
exxc.getRichStringCellValue().applyFont(0, ex[0].length(),
font(xw, color));
} else {
// 判断传入的步骤是否大于当前共有的步骤若大于则直接返回
if (step > st.length) {
return;
}
// 用于计算传入的步骤在步骤单元格与预期单元格的中的位置
int stIndex = 0;
int exIndex = 0;
// 计算步骤位置的算法为传入的步骤数之前的步骤的所有文字数量
// 循环累加字符串的长度
for (int i = 1; i < step; i++) {
// 文字的数量
stIndex += st[i - 1].length();
// \n符的占位量
stIndex += 1;
exIndex += ex[i - 1].length();
exIndex += 1;
}
// 设置字体
stxc.getRichStringCellValue().applyFont(stIndex,
(stIndex + st[step - 1].length()), font(xw, color));
exxc.getRichStringCellValue().applyFont(exIndex,
(exIndex + ex[step - 1].length()), font(xw, color));
}
}
/**
* 创建标记的新字体
*
* @param xw
* @param color
* @return
*/
private XSSFFont font(XSSFWorkbook xw, short color) {
XSSFFont xf = xw.createFont();
// 设置字体名称
xf.setFontName("宋体");
// 设置字体大小注意字体大小单位为磅小四字体对应12磅
xf.setFontHeightInPoints((short) 12);
// 设置颜色
xf.setColor(color);
return xf;
}
}

View File

@ -1,159 +0,0 @@
package pres.auxiliary.work.old.testcase.change;
import java.io.File;
import java.io.IOException;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import pres.auxiliary.work.old.testcase.exception.ExistentContentException;
/**
* 该类用于编写测试用例的标题
*
* @author 彭宇琦
* @version Ver1.0
*/
public class Title extends CaseAttribute implements OperationContent {
private static Title t = null;
/**
* 该构造用于在创建一条新的测试用例时使用的构造并定义是否允许覆盖
*
* @param excel
* 测试用例文件的文件对象
* @param isReplace
* 是否允许覆盖表格内容
*/
private Title(File excel, boolean isReplace) {
setExcel(excel);
CaseAttribute.isReplace = isReplace;
}
/**
* 该构造用于指向测试用例文件并指定需要修改或添加的测试用例在文件中的实际位置
*
* @param excel
* 测试用例文件的
* @param rowNum
* 文件中需要修改的测试用例位置
* @param isReplace
* 是否允许覆盖表格内容
*/
private Title(File excel, int rowNum, boolean isReplace) {
setExcel(excel);
CaseAttribute.rowNum = rowNum;
CaseAttribute.isReplace = isReplace;
}
/**
* 该方法用于构造Title对象
*
* @param excel
* 测试用例文件的文件对象
* @param isReplace
* 是否允许覆盖表格内容
* @return Title对象
*/
public static Title newInstence(File excel, boolean isReplace) {
if (excel.equals(CaseAttribute.excel)) {
t = new Title(excel, isReplace);
}
// 定位到标题那一列
cellNum = 2;
return t;
}
/**
* 该方法用于构造Title对象
*
* @param excel
* 测试用例文件的
* @param rowNum
* 文件中需要修改的测试用例位置
* @param isReplace
* 是否允许覆盖表格内容
* @return Title对象
*/
public static Title newInstence(File excel, int rowNum, boolean isReplace) {
if (excel != CaseAttribute.excel) {
t = new Title(excel, rowNum, isReplace);
}
// 定位到标题那一列
cellNum = 2;
return t;
}
@Override
public String getPreviousContent() {
return content.toString();
}
@Override
public Title write(String content) throws IOException {
// 定位到测试用例所在的工作簿位置
XSSFWorkbook xw = before();
// 判断rowNum是是否存储过数字未存储过数字时则获取工作簿的最后一行加上2表示实际位置
if (rowNum <= 0) {
rowNum = xw.getSheetAt(0).getLastRowNum() + 2;
}
XSSFRow xr = xw.getSheetAt(0).getRow(rowNum - 1);
// 判断单元格是否被创建若被创建则进一步判断是否允许覆盖若不允许覆盖则抛出异常
if (xr.getCell(cellNum) != null && !isReplace) {
throw new ExistentContentException("单元格已被创建,且不能覆盖已有的内容");
}
// 保存单元格中原有的内容
OperationContent.content.delete(0, OperationContent.content.length());
OperationContent.content.append(valueOf(xr.getCell(cellNum)));
// 写入需要添加的内容
xr.getCell(cellNum).setCellValue(content);
after(xw);
return this;
}
@Override
public Title clear() throws IOException {
// 定位到测试用例所在的工作簿位置
XSSFWorkbook xw = before();
// 判断rowNum是是否存储过数字未存储过数字时则获取工作簿的最后一行加上2表示实际位置
if (rowNum <= 0) {
rowNum = xw.getSheetAt(0).getLastRowNum() + 2;
}
XSSFRow xr = xw.getSheetAt(0).getRow(rowNum - 1);
// 判断单元格是否被创建若被创建则直接结束若已被创建则设置单元格内容为空
if (xr.getCell(cellNum) != null) {
// 保存单元格中原有的内容
OperationContent.content.delete(0, OperationContent.content.length());
OperationContent.content.append(valueOf(xr.getCell(cellNum)));
//替换单元格中的内容为空
xr.getCell(cellNum).setCellValue("");
}
// 写入需要添加的内容
after(xw);
return this;
}
@Override
public Title replace(String findText, String replaceText)
throws IOException {
return this;
}
@Override
public Title delete(String findText) throws IOException {
// TODO Auto-generated method stub
return this;
}
}

View File

@ -1,74 +0,0 @@
package pres.auxiliary.work.old.testcase.change;
import java.io.File;
import java.io.IOException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* 该类定义了通过读取XML方式来生成用例的基本方法通过该方法生成的用例有测试用例及自动化测试脚本用例
* @author 彭宇琦
* @version V1.0
* @since JDK 1.7
* @since DOM4J 1.6.1
* @since POI 13.0
*/
public abstract class WriteCase implements Runnable {
//用于读取XML文件
protected Document dom;
/**
* 该方法用于设置xml文件
* @param xmlFile xml文件
* @throws DocumentException
*/
public void setDocument(File xmlFile) throws DocumentException {
dom = new SAXReader().read(xmlFile);
}
/**
* 该方法用于设置xml文件
* @param dom 指向xml文件的Document对象
* @throws DocumentException
*/
public void setDocument(Document dom) throws DocumentException {
this.dom = dom;
}
/**
* 该方法用于通过XML来创建用例
*/
public abstract void write() throws IOException ;
/**
* 该方法用于启动多线程来创建测试用例
*
* @see java.lang.Runnable#run()
*/
@Override
public abstract void run();
/**
* 该方法用于对模块标签进行操作
* @param mocule 模块标签的Element对象
* @throws IOException
*/
protected abstract void disposeModule(Element mocule) throws IOException;
/**
* 该方法用于对用例类型进行操作
* @param type 类型标签的Element对象
* @throws IOException
*/
protected abstract void disposeType(Element type) throws IOException;
/**
* 该方法用于对需要编写用例的元素进行操作
* @param element 待编写用例的元素标签的Element对象
* @throws IOException
*/
protected abstract void disposeElement(Element element) throws IOException;
}

View File

@ -1,5 +0,0 @@
package pres.auxiliary.work.old.testcase.change;
public abstract class WriteCaseScript extends WriteCase {
}

View File

@ -1,828 +0,0 @@
package pres.auxiliary.work.old.testcase.change;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import pres.auxiliary.work.old.testcase.templet.ZentaoTemplet;
import pres.auxiliary.work.old.testcase.writecase.AddInformation;
import pres.auxiliary.work.old.testcase.writecase.BrowseList;
import pres.auxiliary.work.old.testcase.writecase.FileType;
import pres.auxiliary.work.old.testcase.writecase.InputType;
import pres.auxiliary.work.old.testcase.writecase.PhoneType;
/**
* 该类用于通过XML文件结构来生成测试用例
*
* @author 彭宇琦
* @version V1.0
* @since JDK 1.7
* @since DOM4J 1.6.1
* @since POI 13.0
*/
public class WriteTestCase extends WriteCase {
// 用于生成添加信息的测试用例类
AddInformation ai = null;
// 用于生成浏览信息的测试用例类
BrowseList bl = null;
public WriteTestCase(File xmlFile) throws DocumentException {
setDocument(xmlFile);
}
public WriteTestCase(Document dom) throws DocumentException {
setDocument(dom);
}
@Override
public void run() {
try {
write();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void write() throws IOException {
// 获取根节点
Element root = dom.getRootElement();
// 创建禅道模版
// 添加创建模版的属性判断各个属性是否正确填入
// 判断用例存放位置是否定义
if (root.attribute("case_file_path") != null
&& !root.attributeValue("case_file_path").equals("")) {
ZentaoTemplet.setSavePath(root.attributeValue("case_file_path"));
} else {
throw new IncorrectXmlPathException(
"未定义XML中case标签的\"case_file_path\"属性的值");
}
// 判断用例名称是否定义
if (root.attribute("name") != null
&& !root.attributeValue("name").equals("")) {
ZentaoTemplet.setFileName(root.attributeValue("name"));
} else {
throw new IncorrectXmlPathException("未定义XML中case标签的\"name\"属性的值");
}
// 创建模版
ZentaoTemplet.create();
// 判断是否添加模块与需求的数据有效性若属性不存在或者为空则表示不添加
if (root.attribute("module_file_path") != null
&& !root.attributeValue("module_file_path").equals("")) {
ZentaoTemplet.readModlueData(new File(root
.attributeValue("module_file_path")));
}
if (root.attribute("story_file_path") != null
&& !root.attributeValue("story_file_path").equals("")) {
ZentaoTemplet.readStoryData(new File(root
.attributeValue("story_file_path")));
}
// 遍历根节点下所有的子节点即遍历所有需要写测试用例的子模块
for (@SuppressWarnings("unchecked")
Iterator<Element> modules = root.elementIterator(); modules.hasNext();) {
disposeModule(modules.next());
}
// 添加数据有效性
ZentaoTemplet.setAllDataValidation();
}
@Override
protected void disposeModule(Element module) throws IOException {
// 判断是否已经创建了AddInformationBrowseList对象若未创建则创建对象若已创建则不再创建对象
if (ai == null) {
ai = new AddInformation();
}
if (bl == null) {
bl = new BrowseList();
}
// 判断XML中是否设置了模块的名称
if (module.attribute("name") != null
&& !module.attributeValue("name").equals("")) {
ai.setModule(module.attributeValue("name"));
} else {
throw new IncorrectXmlPathException("未定义XML中module标签的\"name\"属性的值");
}
// 对模块中的生成用例的类型
for (@SuppressWarnings("unchecked")
Iterator<Element> types = module.elementIterator(); types.hasNext();) {
disposeType(types.next());
}
}
@SuppressWarnings("unchecked")
@Override
protected void disposeType(Element type) throws IOException {
// 判断待生成的测试用例类型
// TODO 若新添加测试用例的类型则需要向此处添加
if (type.getName().equalsIgnoreCase("form")) {
// 添加新增信息类型的测试用例
// 设置新增的信息名称
if (type.attribute("inormation") != null
&& !type.attributeValue("inormation").equals("")) {
ai.setInformationName(type.attributeValue("inormation"));
} else {
throw new IncorrectXmlPathException(
"未定义XML中form标签的\"inormation\"属性的值");
}
// 用于定位元素
Element temp = null;
// 设置添加信息成功的预期
if ((temp = type.element("success")) != null) {
// 判断元素是否有内容没有内容则不进行设置
if (!"".equals(temp.getText())) {
ai.setSuccessExpectation(temp.getText());
}
}
// 设置失败时的期望
if ((temp = type.element("fail")) != null) {
// 判断元素是否有内容没有内容则不进行设置
if (!"".equals(temp.getText())) {
ai.setFailExpectation(temp.getText());
}
}
// 设置前置条件
if ((temp = type.element("precondition")) != null) {
// 读取填写的所有前置条件的步骤
for (Iterator<Element> step = temp.elementIterator(); step
.hasNext();) {
ai.setPrecondition(step.next().getText());
}
}
// 读取提交按钮名称
if ((temp = type.element("submit")) != null) {
if (!"".equals(temp.attribute("name"))) {
ai.setButtonName(temp.attributeValue("name"));
}
} else {
throw new IncorrectXmlPathException("未定义提交信息按钮标签");
}
//写入添加信息必要的前两条用例
ai.addWholeInformationCase();
ai.addUnWholeInformationCase();
// 读取待写入测试用例的元素
if ((temp = type.element("element")) != null) {
// 循环将调用处理元素的方法将所有的元素生成测试用例
for (Iterator<Element> elements = temp.elementIterator(); elements
.hasNext();) {
disposeElement(elements.next());
}
} else {
throw new IncorrectXmlPathException("未定义元素标签");
}
} else if (type.getName().equalsIgnoreCase("list")) {
// 添加浏览列表的测试用例
// 判断是否存在列表名称
if (type.attribute("name") != null
&& !type.attributeValue("name").equals("")) {
} else {
throw new IncorrectXmlPathException(
"未定义XML中list标签的\"name\"属性的值");
}
// 判断需要浏览的列表属于何种样式
if (type.attribute("type") != null
&& !type.attributeValue("type").equals("")) {
if (type.attributeValue("type").equals("web")) {
bl.addWebBrowseListCase(type.attributeValue("name"));
} else {
bl.addAppBrowseListCase(type.attributeValue("name"));
}
}
} else if (type.getName().equalsIgnoreCase("search")) {
// 添加搜索列表的测试用例
// 判断是否存在列表名称
if (type.attribute("name") != null
&& !type.attributeValue("name").equals("")) {
} else {
throw new IncorrectXmlPathException(
"未定义XML中search标签的\"name\"属性的值");
}
// 循环将调用处理元素的方法将所有的元素生成测试用例
for (Iterator<Element> elements = type.elementIterator(); elements
.hasNext();) {
disposeElement(elements.next());
}
}
}
@Override
protected void disposeElement(Element element) throws IOException {
//存储父节点的标签的名称
String parentName = element.getParent().getName();
//判断标签的类型即控件的类型
if (element.getName().equalsIgnoreCase("textbox")) {
//判断父标签是什么种类的标签并使用其对应的方法
if ( parentName.equalsIgnoreCase("element") ) {
//定义属性
String name;
boolean isMust = true;
boolean isRepeat = false;
char[] inputConfine;
int[] lengthConfine;
int[] numConfine;
//判断是否定义控件的名称并存储控件的名称
if ( (name = element.attributeValue("name")) == null) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"name\"属性的值");
}
//判断是否定义了是否必填的属性
try {
isMust = Boolean.valueOf(element.attributeValue("must"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"must\"属性的值");
}
//判断是否定义了是否重复的属性
try {
isRepeat = Boolean.valueOf(element.attributeValue("repeat"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"repeat\"属性的值");
}
//用于获取到被分割后的输入限制
String[] s = null;
//判断是否定义了输入限制的属性
try {
//判断获取到的元素是否为空或是字符串null
if ( element.attributeValue("input_confine").equals("") || element.attributeValue("input_confine").equals("null") ) {
inputConfine = null;
} else {
//分割获取到的字符串
//TODO 在实现信息采集功能后分隔符应改为可自定义
s = element.attributeValue("input_confine").split(",");
//定义用于临时存放数据的数组
ArrayList<Character> temp = new ArrayList<Character>();
//解析输入的限制将其转为char类型存入数组中
for ( String str : s ) {
//将字符串中的信息转为小写
str = str.toLowerCase();
//判断限制的信息并将存入tem中
switch ( str ) {
case "num":
temp.add(InputType.NUM);
break;
case "en":
temp.add(InputType.EN);
break;
case "ch":
temp.add(InputType.CH);
break;
case "spe":
temp.add(InputType.SPE);
break;
default:
break;
}
}
//判断temp中是否有元素存在若不为0则存储反之则将inputConfine设为null
if ( temp.size() != 0 ) {
//初始化inputConfine数组
inputConfine = new char[temp.size()];
//将元素存入inputConfine数组中
for ( int i = 0; i < temp.size(); i++ ) {
inputConfine[i] = temp.get(i).charValue();
}
} else {
inputConfine = null;
}
}
} catch (NullPointerException e) {
//若抛出空指针异常时则将输入限制置为null
inputConfine = null;
}
//获取长度限制信息
try {
//判断获取到的元素是否为空或是字符串null
if ( element.attributeValue("length_confine").equals("") || element.attributeValue("length_confine").equals("null") ) {
lengthConfine = null;
} else {
//分割获取到的字符串
//TODO 在实现信息采集功能后分隔符应改为可自定义
s = element.attributeValue("length_confine").split(",");
//定义用于临时存放数据的数组
ArrayList<Integer> temp = new ArrayList<Integer>();
//循环获取长度限制存入temp中若出现无法转换的字符串则不进行存储
for ( String str : s ) {
try {
//判断字符串是否是NAN
if ( str.equalsIgnoreCase("nan") ) {
temp.add(ai.NUM_NAN);
} else {
temp.add(Integer.valueOf(str));
}
} catch(NumberFormatException e) {
continue;
}
}
//判断temp中是否有元素存在若不为0则存储反之则将lengthConfine设为null
if ( temp.size() != 0 ) {
//初始化lengthConfine数组
lengthConfine = new int[temp.size()];
//将元素存入inputConfine数组中
for ( int i = 0; i < temp.size(); i++ ) {
lengthConfine[i] = temp.get(i).intValue();
}
} else {
lengthConfine = null;
}
}
} catch (NullPointerException e) {
//若抛出空指针异常时则将长度限制置为null
lengthConfine = null;
}
//获取数字大小限制信息
try {
//判断获取到的元素是否为空或是字符串null
if ( element.attributeValue("num_confine").equals("") || element.attributeValue("num_confine").equals("null") ) {
numConfine = null;
} else {
//分割获取到的字符串
//TODO 在实现信息采集功能后分隔符应改为可自定义
s = element.attributeValue("num_confine").split(",");
//定义用于临时存放数据的数组
ArrayList<Integer> temp = new ArrayList<Integer>();
//循环获取长度限制存入temp中若出现无法转换的字符串则不进行存储
for ( String str : s ) {
try {
//判断字符串是否是NAN
if ( str.equalsIgnoreCase("nan") ) {
temp.add(ai.NUM_NAN);
} else {
temp.add(Integer.valueOf(str));
}
} catch(NumberFormatException e) {
continue;
}
}
//判断temp中是否有元素存在若不为0则存储反之则将numConfine设为null
if ( temp.size() != 0 ) {
//初始化numConfine数组
numConfine = new int[temp.size()];
//将元素存入numConfine数组中
for ( int i = 0; i < temp.size(); i++ ) {
numConfine[i] = temp.get(i).intValue();
}
} else {
numConfine = null;
}
}
} catch (NullPointerException e) {
//若抛出空指针异常时则将长度限制置为null
numConfine = null;
}
//添加测试用例
ai.addTextboxCase(name, isMust, isRepeat, inputConfine, lengthConfine, numConfine);
} else if ( parentName.equalsIgnoreCase("search") ) {
//判断获取到的元素是否为空或是字符串null
if ( element.attributeValue("name").equals("") || element.attribute("name") == null ) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"name\"属性的值");
} else {
//添加测试用例
bl.addInputSearchCase(element.attributeValue("name"), element.getParent().attributeValue("name"));
}
}
} else if ( element.getName().equalsIgnoreCase("select") ) {
//设置类型为下拉框时的测试用例
//判断父节点的类型并添加相应的测试用例
if ( parentName.equalsIgnoreCase("element") ) {
//若父节点的名称为element时则添加ai中的测试用例
//定义编写测试用例时需要传入的属性
String name;
boolean isMust;
//判断是否定义控件的名称并存储控件的名称
if ( (name = element.attributeValue("name")) == null) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"name\"属性的值");
}
//判断是否定义了是否必填的属性
try {
isMust = Boolean.valueOf(element.attributeValue("must"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"must\"属性的值");
}
//添加测试用例
ai.addSelectboxCase(name, isMust);
} else if ( parentName.equalsIgnoreCase("search") ) {
//若父节点的名称为search时则添加bl中的测试用例
//判断获取到的元素是否为空或是字符串null
if ( element.attributeValue("name").equals("") || element.attribute("name") == null ) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"name\"属性的值");
} else {
//添加测试用例
bl.addSelectSearchCase(element.attributeValue("name"), element.getParent().attributeValue("name"));
}
}
} else if ( element.getName().equalsIgnoreCase("radio") ) {
//添加单选按钮的测试用例
//定义编写测试用例时需要传入的属性
String name;
boolean isMust;
//判断是否定义控件的名称并存储控件的名称
if ( (name = element.attributeValue("name")) == null) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"name\"属性的值");
}
//判断是否定义了是否必填的属性
try {
isMust = Boolean.valueOf(element.attributeValue("must"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"must\"属性的值");
}
//添加测试用例
ai.addRadioButtonCase(name, isMust);
} else if ( element.getName().equalsIgnoreCase("check") ) {
//定义编写测试用例时需要传入的属性
String name;
boolean isMust;
//判断是否定义控件的名称并存储控件的名称
if ( (name = element.attributeValue("name")) == null) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"name\"属性的值");
}
//判断是否定义了是否必填的属性
try {
isMust = Boolean.valueOf(element.attributeValue("must"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"must\"属性的值");
}
//添加测试用例
ai.addCheckboxCase(name, isMust);
} else if ( element.getName().equalsIgnoreCase("date") ) {
//添加与日期相关的测试用例包括普通日期开始与结束相应的日期
//定义编写测试用例时需要传入的属性
String name;
boolean isMust;
boolean isInput;
String typeName;
//判断是否定义控件的名称并存储控件的名称
if ( (name = element.attributeValue("name")) == null) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"name\"属性的值");
}
//判断是否定义了是否必填的属性
try {
isMust = Boolean.valueOf(element.attributeValue("must"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"must\"属性的值");
}
//判断是否定义了是否可输入的属性
try {
isInput = Boolean.valueOf(element.attributeValue("input"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"input\"属性的值");
}
//获取type属性中的内容用以添加对应的测试用例
typeName = element.attributeValue("type");
//判断是否定义日期的类型并按照类型添加不同的测试用例
//若为获取到type中的内容则添加普通日期的测试用例
if ( typeName == null || typeName.equals("")) {
ai.addDateCase(name, isMust, isInput);
} else if ( typeName.equalsIgnoreCase("start") ) {
//若获取到的样式为start则在该元素标签的兄弟节点中查找带end标记的标签
//若未找到被end标记的标签则仍然按照普通日期添加用例
//若查找到该标签则将标签name属性值赋给typeName
//NOTE:被end标记的日期读取方式与其相反
if ( element.selectSingleNode("../date[@type='end']") == null ) {
ai.addDateCase(name, isMust, isInput);
} else {
Element d = (Element) element.selectSingleNode("../date[@type='end']");
ai.addStartDateCase(name, isMust, isInput, d.attributeValue("name"));
}
} else if ( typeName.equalsIgnoreCase("end") ) {
if ( element.selectSingleNode("../date[@type='start']") == null ) {
ai.addDateCase(name, isMust, isInput);
} else {
Element d = (Element) element.selectSingleNode("../date[@type='start']");
ai.addEndDateCase(name, isMust, isInput, d.attributeValue("name"));
}
}
} else if ( element.getName().equalsIgnoreCase("phone") ) {
//添加与号码相关的测试用例
//定义编写测试用例时需要传入的属性
String name;
boolean isMust;
boolean isRepeat;
PhoneType phone;
//判断是否定义控件的名称并存储控件的名称
if ( (name = element.attributeValue("name")) == null) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"name\"属性的值");
}
//判断是否定义了是否必填的属性
try {
isMust = Boolean.valueOf(element.attributeValue("must"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"must\"属性的值");
}
//判断是否定义了是否必填的属性
try {
isRepeat = Boolean.valueOf(element.attributeValue("repeat"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"repeat\"属性的值");
}
//定义一个临时存储获取属性值的字符串变量用以存储从type属性中获取到的值
String temp;
//判断是否定义号码的类型并存储其值若未定义则抛出异常若已定义则对类型进行处理
if ( (temp = element.attributeValue("type")) == null ) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"type\"属性的值");
} else {
//判断temp中的内容并设置其对应的PhoneType
if ( temp.equalsIgnoreCase("moble") ) {
phone = PhoneType.MOBLE;
} else if ( temp.equalsIgnoreCase("fixed") ) {
phone = PhoneType.FIXED;
} else {
throw new IncorrectXmlPathException(
"XML中" + element.getName() + "标签的\"type\"属性值不能为:" + temp);
}
}
ai.addPhoneCase(name, isMust, isRepeat, phone);
} else if ( element.getName().equalsIgnoreCase("idcard") ) {
//添加与身份证相关的测试用例
//定义编写测试用例时需要传入的属性
String name;
boolean isMust;
boolean isRepeat;
//判断是否定义控件的名称并存储控件的名称
if ( (name = element.attributeValue("name")) == null) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"name\"属性的值");
}
//判断是否定义了是否必填的属性
try {
isMust = Boolean.valueOf(element.attributeValue("must"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"must\"属性的值");
}
//判断是否定义了是否必填的属性
try {
isRepeat = Boolean.valueOf(element.attributeValue("repeat"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"repeat\"属性的值");
}
ai.addIDCardCase(name, isMust, isRepeat);
} else if ( element.getName().equalsIgnoreCase("upload") ) {
//添加上传文件的测试用例包括上传文件以及上传图片
//定义基本参数
String name;
boolean isMust;
boolean isRepeat;
boolean isSizeConfine;
char[] fileConfine;
int[] fileNumConfine;
//判断是否定义控件的名称并存储控件的名称
if ( (name = element.attributeValue("name")) == null) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"name\"属性的值");
}
//判断是否定义了是否必填的属性
try {
isMust = Boolean.valueOf(element.attributeValue("must"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"must\"属性的值");
}
//判断是否定义了是否必填的属性
try {
isRepeat = Boolean.valueOf(element.attributeValue("repeat"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"repeat\"属性的值");
}
//判断是否定义了是否有大小限制的属性
try {
isSizeConfine = Boolean.valueOf(element.attributeValue("size"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"size\"属性的值");
}
//用于获取到被分割后的输入限制
String[] s = null;
//判断是否定义了格式限制的属性
try {
//判断获取到的元素是否为空或是字符串null
if ( element.attributeValue("file_confine").equals("") || element.attributeValue("file_confine").equals("null") ) {
fileConfine = null;
} else {
//分割获取到的字符串
//TODO 在实现信息采集功能后分隔符应改为可自定义
s = element.attributeValue("file_confine").split(",");
//定义用于临时存放数据的数组
ArrayList<Character> temp = new ArrayList<Character>();
//解析输入的限制将其转为char类型存入数组中
for ( String str : s ) {
//将字符串中的信息转为小写
str = str.toLowerCase();
//判断限制的信息并将存入tem中
switch ( str ) {
case "jpg":
temp.add(FileType.JPG);
break;
case "gif":
temp.add(FileType.GIF);
break;
case "png":
temp.add(FileType.PNG);
break;
case "bmp":
temp.add(FileType.BMP);
break;
case "doc":
temp.add(FileType.DOC);
break;
case "docx":
temp.add(FileType.DOCX);
break;
case "xls":
temp.add(FileType.XLS);
break;
case "xlsx":
temp.add(FileType.XLSX);
break;
case "txt":
temp.add(FileType.TXT);
break;
default:
break;
}
}
//判断temp中是否有元素存在若不为0则存储反之则将fileConfine设为null
if ( temp.size() != 0 ) {
//初始化inputConfine数组
fileConfine = new char[temp.size()];
//将元素存入inputConfine数组中
for ( int i = 0; i < temp.size(); i++ ) {
fileConfine[i] = temp.get(i).charValue();
}
} else {
fileConfine = null;
}
}
} catch (NullPointerException e) {
//若抛出空指针异常时则将输入限制置为null
fileConfine = null;
}
//获取文件图片个数限制信息
try {
//判断获取到的元素是否为空或是字符串null
if ( element.attributeValue("num_confine").equals("") || element.attributeValue("num_confine").equals("null") ) {
fileNumConfine = null;
} else {
//分割获取到的字符串
//TODO 在实现信息采集功能后分隔符应改为可自定义
s = element.attributeValue("num_confine").split(",");
//定义用于临时存放数据的数组
ArrayList<Integer> temp = new ArrayList<Integer>();
//循环获取长度限制存入temp中若出现无法转换的字符串则不进行存储
for ( String str : s ) {
try {
//判断字符串是否是NAN
if ( str.equalsIgnoreCase("nan") ) {
temp.add(ai.NUM_NAN);
} else {
temp.add(Integer.valueOf(str));
}
} catch(NumberFormatException e) {
continue;
}
}
//判断temp中是否有元素存在若不为0则存储反之则将lengthConfine设为null
if ( temp.size() != 0 ) {
//初始化lengthConfine数组
fileNumConfine = new int[temp.size()];
//将元素存入inputConfine数组中
for ( int i = 0; i < temp.size(); i++ ) {
fileNumConfine[i] = temp.get(i).intValue();
}
} else {
fileNumConfine = null;
}
}
} catch (NullPointerException e) {
//若抛出空指针异常时则将长度限制置为null
fileNumConfine = null;
}
//获取type属性判断上传的文件类型并添加对应的测试用例
if ( element.attributeValue("type").equalsIgnoreCase("file") ) {
//如果是文件类型则根据其属性添加测试用例
ai.addUploadFileCase(name, isMust, isRepeat, isSizeConfine, fileConfine, fileNumConfine);
} else if ( element.attributeValue("type").equalsIgnoreCase("image") ) {
//如果是图片类型则继续获取其两个属性值
boolean isPhotogeraph;
boolean isUpload;
//判断是否定义了是否允许拍照上传的限制
try {
isPhotogeraph = Boolean.valueOf(element.attributeValue("photogeraph"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"photogeraph\"属性的值");
}
//判断是否定义了是否允许从文件夹或者相册等本地文件直接上传的限制
try {
isUpload = Boolean.valueOf(element.attributeValue("upload"));
} catch (NullPointerException e) {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"upload\"属性的值");
}
ai.addUploadImageCase(name, isMust, isRepeat, isPhotogeraph, isUpload, isSizeConfine, fileConfine, fileNumConfine);
} else {
throw new IncorrectXmlPathException(
"未定义XML中" + element.getName() + "标签的\"type\"属性的值");
}
}
//TODO 此处之上用于添加需要添加测试用例的类型
}
}

View File

@ -1,38 +0,0 @@
package pres.auxiliary.work.old.testcase.exception;
/**
* 该异常在所填写的单元格中有信息存在且不允许被覆盖是抛出的异常
* @author 彭宇琦
* @version Ver1.0
*/
public class ExistentContentException extends RuntimeException {
private static final long serialVersionUID = 1L;
public ExistentContentException() {
super();
// TODO Auto-generated constructor stub
}
public ExistentContentException(String message, Throwable cause,
boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public ExistentContentException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public ExistentContentException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public ExistentContentException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}

View File

@ -1,38 +0,0 @@
package pres.auxiliary.work.old.testcase.exception;
/**
* 该异常在新增用例信息不全时抛出
* @author 彭宇琦
* @version Ver1.0
*/
public class IncompleteInformationException extends RuntimeException {
private static final long serialVersionUID = 1L;
public IncompleteInformationException() {
super();
// TODO Auto-generated constructor stub
}
public IncompleteInformationException(String message, Throwable cause,
boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public IncompleteInformationException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public IncompleteInformationException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public IncompleteInformationException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}

View File

@ -1,36 +0,0 @@
package pres.auxiliary.work.old.testcase.exception;
/**
* 在定义的测试用例文件有误时抛出的异常
* @author 彭宇琦
*/
public class IncorrectCaseFileException extends RuntimeException {
public IncorrectCaseFileException() {
super();
// TODO Auto-generated constructor stub
}
public IncorrectCaseFileException(String message, Throwable cause,
boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public IncorrectCaseFileException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public IncorrectCaseFileException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public IncorrectCaseFileException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
private static final long serialVersionUID = 1L;
}

View File

@ -1,33 +0,0 @@
package pres.auxiliary.work.old.testcase.exception;
public class ModuleDataNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
public ModuleDataNotFoundException() {
super();
// TODO Auto-generated constructor stub
}
public ModuleDataNotFoundException(String message, Throwable cause,
boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public ModuleDataNotFoundException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public ModuleDataNotFoundException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public ModuleDataNotFoundException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}

View File

@ -1,37 +0,0 @@
package pres.auxiliary.work.old.testcase.exception;
/**
* 该异常在指定的单元格对象无效抛出的异常
* @author 彭宇琦
* @version Ver1.0
*/
public class TableNotCreateException extends RuntimeException {
private static final long serialVersionUID = 1L;
public TableNotCreateException() {
super();
// TODO Auto-generated constructor stub
}
public TableNotCreateException(String message, Throwable cause,
boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public TableNotCreateException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public TableNotCreateException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public TableNotCreateException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}

View File

@ -1,39 +0,0 @@
package pres.auxiliary.work.old.testcase.exception;
/**
* 该异常在未指定excel文件时抛出
* @author 彭宇琦
* @version Ver1.0
*
*/
public class UndefinedExcelDiractoryException extends RuntimeException {
private static final long serialVersionUID = 1L;
public UndefinedExcelDiractoryException() {
super();
// TODO Auto-generated constructor stub
}
public UndefinedExcelDiractoryException(String arg0, Throwable arg1,
boolean arg2, boolean arg3) {
super(arg0, arg1, arg2, arg3);
// TODO Auto-generated constructor stub
}
public UndefinedExcelDiractoryException(String arg0, Throwable arg1) {
super(arg0, arg1);
// TODO Auto-generated constructor stub
}
public UndefinedExcelDiractoryException(String arg0) {
super(arg0);
// TODO Auto-generated constructor stub
}
public UndefinedExcelDiractoryException(Throwable arg0) {
super(arg0);
// TODO Auto-generated constructor stub
}
}

View File

@ -1,257 +0,0 @@
package pres.auxiliary.work.old.testcase.templet;
import java.io.File;
import java.util.List;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public enum ZentaoExcel {
/**
* 指向id为case的sheet
*/
SHEET_CASE("/templet/sheet[@id='case']"),
/**
* 指向id为case的sheet中id为case_id的列
*/
CASE_COLUMN_CASE_ID(SHEET_CASE.getXpath() + "/column[@id='case_id']"),
/**
* 指向id为case的sheet中id为module的列
*/
CASE_COLUMN_MODULE(SHEET_CASE.getXpath() + "/column[@id='module']"),
/**
* 指向id为case的sheet中id为story的列
*/
CASE_COLUMN_STORY(SHEET_CASE.getXpath() + "/column[@id='story']"),
/**
* 指向id为case的sheet中id为title的列
*/
CASE_COLUMN_TITLE(SHEET_CASE.getXpath() + "/column[@id='title']"),
/**
* 指向id为case的sheet中id为step的列
*/
CASE_COLUMN_STEP(SHEET_CASE.getXpath() + "/column[@id='step']"),
/**
* 指向id为case的sheet中id为expect的列
*/
CASE_COLUMN_EXPECT(SHEET_CASE.getXpath() + "/column[@id='expect']"),
/**
* 指向id为case的sheet中id为keys的列
*/
CASE_COLUMN_KEYS(SHEET_CASE.getXpath() + "/column[@id='keys']"),
/**
* 指向id为case的sheet中id为type的列
*/
CASE_COLUMN_TYPE(SHEET_CASE.getXpath() + "/column[@id='type']"),
/**
* 指向id为case的sheet中id为priority的列
*/
CASE_COLUMN_RANK(SHEET_CASE.getXpath() + "/column[@id='rank']"),
/**
* 指向id为case的sheet中id为state的列
*/
CASE_COLUMN_STATE(SHEET_CASE.getXpath() + "/column[@id='state']"),
/**
* 指向id为case的sheet中id为apply的列
*/
CASE_COLUMN_STAGE(SHEET_CASE.getXpath() + "/column[@id='stage']"),
/**
* 指向id为case的sheet中id为condition的列
*/
CASE_COLUMN_CONDITION(SHEET_CASE.getXpath() + "/column[@id='condition']"),
/**
* 指向id为case的sheet中id为flow的列
*/
CASE_COLUMN_FLOW(SHEET_CASE.getXpath() + "/column[@id='flow']");
// 用于存储xml文件位置
private final String CONFIG_FILE_PATH = "ConfigurationFiles/CaseConfigurationFile/CaseTemplet.xml";
// 存储xpath
private String xpath;
// 存储节点的标记
private short type;
// 存储节点的id属性
private String id;
// 用于存储父节点的id
private String parentId;
private ZentaoExcel(String xpath) {
this.xpath = xpath;
// 判断其xptah是否含有column若包含则表示其为column节点否则为sheet节点
if (this.xpath.indexOf("column") > -1) {
this.type = 1;
} else {
this.type = 0;
}
// 获取其id属性
this.id = xpath.substring(xpath.lastIndexOf("@id='") + "@id='".length(),
xpath.lastIndexOf("'"));
// 获取该节点的父节点
if (this.type == 1) {
this.parentId = this.xpath.substring(
this.xpath.indexOf("@id='") + "@id='".length(),
this.xpath.indexOf("']/column"));
} else {
this.parentId = "";
}
}
/**
* 返回枚举对应的Elemen对象
*
* @return Elemen对象
*/
public Element getElement() {
try {
return (Element) (new SAXReader().read(new File(CONFIG_FILE_PATH))
.selectSingleNode(xpath));
} catch (DocumentException e) {
e.printStackTrace();
return null;
}
}
/**
* 根据Column元素的id查找元素并将其枚举常量返回若id查找不到则返回null根据调用的节点不同其返回方式也有一些不同
* 具体的方式如下
* <ol>
* <li>若参数本身为sheet节点type值为0则判断每个元素的父节点id是否为当前节点的id再判断子节点id元素column节点的id
* 是否为传入的id</li>
* <li>若参数本身为column节点type值为1则判断每个元素的父节点id是否为当前节点父节点的id再判断子节点id
* 元素column节点的id是否为传入的id</li>
* </ol>
*
* @param sonId
* 节点的id
* @return id对应的枚举常量
*/
public ZentaoExcel getColumnExcel(String sonId) {
// 遍历枚举类中的所有枚举常量
for (ZentaoExcel excel : ZentaoExcel.values()) {
// 返回依据
// 1.若参数本身为sheet节点type值为0则判断每个元素的父节点id是否为当前节点的id再判断子节点id元素column节点的id是否为传入的id
// 2.若参数本身为column节点type值为1则判断每个元素的父节点id是否为当前节点父节点的id再判断子节点id元素column节点的id是否为传入的id
// 简单来说若节点为sheet节点则直接获取子节点若节点为colnum节点则先获取起sheet节点再获取column节点
if (type == (short) 0 && excel.parentId.equals(id)
&& excel.id.equals(sonId)) {
return excel;
} else if (type == (short) 1 && excel.parentId.equals(parentId)
&& excel.id.equals(sonId)) {
return excel;
}
}
return null;
}
/**
* 根据传入id来返回sheet节点
*
* @param id
* sheet节点id
* @return id对应的sheet节点
*/
public ZentaoExcel getSheetExcel(String id) {
// 遍历枚举类中的所有枚举常量
for (ZentaoExcel excel : ZentaoExcel.values()) {
// 判断参数是否为sheet节点再判断其id是否一致都一致则返回起枚举常量
if (excel.type == (short) 0 && excel.id.equals(id)) {
return excel;
}
}
return null;
}
/**
* 用于返回当前column节点所在的sheet节点若传入的是sheet节点则直接返回本身
*
* @return sheet节点
*/
public ZentaoExcel getSheetExcel() {
// 判断当前节点是否为sheet节点若是则直接返回其本身
if (type == (short) 0) {
return this;
}
// 遍历枚举类中的所有枚举常量
for (ZentaoExcel excel : ZentaoExcel.values()) {
// 判断参数是否为sheet节点再判断其id是否一致都一致则返回起枚举常量
if (excel.type == (short) 0 && excel.id.equals(parentId)) {
return excel;
}
}
return null;
}
/**
* 用于返回元素对应的xpath路径
*
* @return xpath路径
*/
public String getXpath() {
return xpath;
}
/**
* 用于返回元素在xml文件中的位置以达到确定其在Excel文件中所在的列元素的下标从0开始
* 注意该方法无论是sheet节点还是column节点其返回的方法都是按照通过父节点来查找子节点的
* 方式进行所以其返回值在不同的节点下返回的结果可能相同
*
* @return 元素位置
*/
public int getValue() {
// 记录其元素的位置
int value = -1;
// 获取元素
Element element = getElement();
// 获取元素的父节点
Element fElement = element.getParent();
// 获取父节点下的所有节点的迭代器
List<?> elements = fElement.elements();
// 循环遍历所有节点找到与需要查找的元素匹配的元素返回其位置
for (int i = 0; i < elements.size(); i++) {
if (((Element) (elements.get(i))).attributeValue("id")
.equals(getElement().attributeValue("id"))) {
value = i;
break;
}
}
return value;
}
/**
* 用于返回其元素对应的表格列标记即在Excel中第一列的标记为A以此类推
* 注意若元素为sheet标签则同样以其value值加上65的形式以字符返回
*
* @return 元素在Excel文件中列的标记
*/
public char getCell() {
return (char) (65 + getValue());
}
/**
* 用于返回节点的id属性
*
* @return 节点的id属性
*/
public String getId() {
return id;
}
/**
* 返回父节点的id属性
*
* @return 父节点id属性
*/
public String getParentId() {
return parentId;
}
}

View File

@ -1,894 +0,0 @@
package pres.auxiliary.work.old.testcase.templet;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFDataValidationConstraint;
import org.apache.poi.xssf.usermodel.XSSFDataValidationHelper;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* 该类用于向指定的路径下生成用于上传至禅道上的测试用例模版目前实现已基本模拟从禅道专业版上导出的
* 模版文件用户从禅道开源版导出csv的模块数据后通过类中存储的方法可实现向模块项与需求项中添加数据有效性
*
* @author 彭宇琦
* @version Ver2.4
* @since POI 3.10
*/
public class ZentaoTemplet {
// 用于存储用例模版存放路径
private static StringBuilder savePath = new StringBuilder("");
// 用于存储Excel文件的名称
private static StringBuilder fileName = new StringBuilder("");
// 用于存储模版中存在的字段
//private static ArrayList<String> field = new ArrayList<>();
//用于设置是否覆盖原文本
private static boolean cover = false;
//指向配置文件的位置
private final static String CONFIG_FILE_PATH = "ConfigurationFiles/CaseConfigurationFile/CaseTemplet.xml";
/**
* 该方法用于以字符串形式返回用例文件保存路径
*
* @return 测试用例文件的保存路径
*/
public static String getSavePath() {
return savePath.toString();
}
/**
* 该方法用于设置测试用例文件保存的位置可传入相对路径也可传入绝对路径
* 若传入的路径不符合windows下文件夹名称的命名规则时则抛出IncorrectDirectoryException异常
*
* @param savePath
* 传入的测试结果文件保存路径
* @throws IncorrectDirectoryException
* 传入路径不合法时抛出的异常
*/
public static void setSavePath(String savePath) {
// 将传入的路径封装成StringBuilder以便格式化
StringBuilder sb = new StringBuilder(savePath);
// 格式化传入的路径
MakeDirectory.formatPath(sb);
// 判断传入的路径是否符合windows下对文件夹名称命名的规则如果不符合则抛出IncorrectDirectoryException异常
if (!MakeDirectory.isPath(sb.toString())) {
throw new IncorrectDirectoryException(
"不合理的文件夹路径,文件路径:" + sb.toString());
}
// 将通过判断的sb赋给savePath属性
ZentaoTemplet.savePath = sb;
}
/**
* 以字符串的形式返回测试用例文件的名称
*
* @return 测试用例文件的名称
*/
public static String getFileName() {
return fileName.toString();
}
/**
* 该方法用于设置测试用例文件的文件名称若传入的文件名不符合windows下文件的命名规则
* 则抛出IncorrectDirectoryException异常
*
* @param fileName
* 指定的测试结果文件名称
* @throws IncorrectDirectoryException
* 文件命名不正确时抛出的异常
*/
public static void setFileName(String fileName) {
// 判断传入的测试结果文件名称是否符合windows下的命名规则若不符合则抛出IncorrectDirectoryException异常
if (!MakeDirectory.isFileName(fileName)) {
throw new IncorrectDirectoryException("不合理的文件名称,文件名称:" + fileName);
}
// 通过判断后则清空fileName存储的信息并将新的文件名称放入fileName种属性中
ZentaoTemplet.fileName.delete(0, ZentaoTemplet.fileName.length());
ZentaoTemplet.fileName.append(fileName);
}
/**
* 该方法用于返回模板文件的文件对象
*
* @return 模板文件对象
*/
public static File getTempletFile() {
// 判断模版文件保存路径与模板文件名是否定义若已定义则返回模板的文件对象若未定义则抛出异常
if (!ZentaoTemplet.savePath.equals("")
&& !ZentaoTemplet.fileName.equals("")) {
return new File(getSavePath() + getFileName() + ".xlsx");
} else {
throw new IncorrectDirectoryException("模板保存路径或模板文件名未定义");
}
}
/**
* 用于设置是否允许覆盖文件当设置为false时在创建测试用例模板时会判断文件是否存在文件同名若存在则抛出异常若设置为true
* 则不做重复文件判断直接覆盖在类中默认为false
* @param cover 是否覆盖文件
*/
public static void setCoverFile(boolean cover) {
ZentaoTemplet.cover = cover;
}
/**
* 该方法用于向指定的文件路径下写入禅道的测试用例模版
*/
public static void create() {
// 判断测试用例文件保存路径是否定义若未定义则给予其默认值
if (savePath.toString().equals("")) {
savePath.append("C:\\AutoTest\\Case\\");
}
// 测试用例文件名是否定义若未定义则给予其
if (fileName.toString().equals("")) {
fileName.append("NewCase");
}
// 创建文件夹
File f = new File(savePath.toString());
if (!f.exists()) {
f.mkdirs();
}
// 拼接存储路径以及文件名称
f = new File(savePath.toString() + (fileName.toString() + ".xlsx"));
// 判断文件是否存在存在则抛出IncorrectDirectoryException异常
if (f.exists() && !cover) {
throw new IncorrectDirectoryException(
"文件名存在:" + fileName.toString() + ".xlsx");
}
// 通过判断后向文件中写入模版
writeTemplet(f);
}
/**
* 该方法用于读取从禅道出的禅道模版中的模块数据并将其内容存储在模版中以添加关于模块的数据有效性
*
* @param moduleList
* 导出的禅道模版文件名称
* @param sheetName
* 模版文件中需要读取的工作博名称
* @see #readModlueData(File)
* @throws IOException
*/
public static void readModlueData(File moduleList) throws IOException {
// 用于读取Excel模版文件的流
FileInputStream fip;
// 若抛出文件不存在的异常时则直接返回
try {
fip = new FileInputStream(moduleList);
} catch (FileNotFoundException e) {
return;
}
// 创建存储模块信息的xml文件的根节点
Element root = DocumentHelper.createElement("data");
// 创建xml文件到内存
Document dom = DocumentHelper.createDocument(root);
// 指向模版文件
XSSFWorkbook xw = new XSSFWorkbook(fip);
// 读取生成的模版
fip = new FileInputStream(
new File(getSavePath() + getFileName() + ".xlsx"));
// 指向生成的测试用例模版
XSSFWorkbook temxw = new XSSFWorkbook(fip);
// 关闭流
fip.close();
// 读取第一个工作博
XSSFSheet xs = xw.getSheet(ZentaoExcel.SHEET_CASE.getElement().attributeValue("name"));
// 获取系统数据工作簿
XSSFSheet temxs;
// 判断系统数据工作簿是否存在不存在则创建该工作簿
if ((temxs = temxw.getSheet("系统数据")) == null) {
temxs = temxw.createSheet("系统数据");
}
// 循环获取模版中所有的系统数据
for (int i = 2; i < xs.getLastRowNum() + 1; i++) {
// 由于模版是从第三行开始编写的数据故从第三行开始获取
XSSFRow xr = xs.getRow(i);
// 存储从单元格中获取到的数据
String cellValue = xr.getCell(0).toString();
// 在新的工作簿中写入数据
XSSFRow temxr;
// 判断行是否已被创建若未被创建则向工作簿中创建行
if ((temxr = temxs.getRow(i - 2)) == null) {
temxr = temxs.createRow(i - 2);
}
// 写入模块数据
temxr.createCell(1).setCellValue(cellValue);
// 将数据按照/进行分割存储得到的数组
String[] modules = cellValue.split("\\/");
// 循环将得到的模块转换为查找元素的xpath路径
StringBuilder xpath = new StringBuilder("/data");
for (int j = 1; j < modules.length; j++) {
// 判断循环是否到最后一次若循环到最后一次则进行元素的添加
if (j == modules.length - 1) {
// 获取到待添加模块的父节点
Element e = (Element) dom
.selectSingleNode(xpath.toString());
// 链式编程添加元素标签
e.addElement("module")
// 添加元素的name属性即模块的名称
.addAttribute("name",
modules[j].substring(0,
modules[j].indexOf("(")))
// 添加元素的id属性即在禅道中的标识
.addAttribute("id",
modules[j].substring(
modules[j].indexOf("(") + 2,
modules[j].indexOf(")")));
// 结束循环
break;
}
// 将路径加上当前获取到的元素
xpath.append("/" + "module[@name='" + modules[j] + "']");
}
}
// 使用dom4j的漂亮格式
OutputFormat format = OutputFormat.createPrettyPrint();
// 设置xml文件的编码方式
format.setEncoding("GBK");
// 写入xml
XMLWriter xmlWriter = new XMLWriter(
new FileOutputStream(savePath.toString() + ("ModuleData.xml")),
format);
xmlWriter.write(dom);
xmlWriter.close();
// 定义输出流
FileOutputStream fop = new FileOutputStream(
new File(getSavePath() + getFileName() + ".xlsx"));
// 将temxw的内容写入到模版中
temxw.write(fop);
// 关闭流
fop.close();
// 关闭表格文件
xw.close();
temxw.close();
}
/**
* 该方法用于读取从禅道导出的需求文件并将其内容存储在模版中以添加关于需求的数据有效性
*
* @param storyList
* 需求文件
* @throws IOException
*/
public static void readStoryData(File storyList) throws IOException {
// 用于读取Excel模版文件的流
FileInputStream fip;
// 若抛出文件不存在的异常时则直接返回
try {
fip = new FileInputStream(storyList);
} catch (FileNotFoundException e) {
return;
}
// 创建存储模块信息的xml文件的根节点
Element root = DocumentHelper.createElement("data");
// 创建xml文件到内存
Document dom = DocumentHelper.createDocument(root);
// 指向模版文件
XSSFWorkbook xw = new XSSFWorkbook(fip);
// 读取生成的模版
fip = new FileInputStream(
new File(getSavePath() + getFileName() + ".xlsx"));
// 指向生成的测试用例模版
XSSFWorkbook temxw = new XSSFWorkbook(fip);
// 关闭流
fip.close();
// 读取第一个工作博
// XSSFSheet xs = xw.getSheet(sheetName);
//XSSFSheet xs = xw.getSheetAt(0);
XSSFSheet xs = xw.getSheet(ZentaoExcel.SHEET_CASE.getElement().attributeValue("name"));
// 获取系统数据工作簿
XSSFSheet temxs;
// 判断系统数据工作簿是否存在不存在则创建该工作簿
if ((temxs = temxw.getSheet("系统数据")) == null) {
temxs = temxw.createSheet("系统数据");
}
// 循环读取需求文件中存储的数据
for (int i = 1; i < xs.getLastRowNum() + 1; i++) {
// 由于模版是从第二行开始编写的数据故从第二行开始获取
XSSFRow xr = xs.getRow(i);
// 存储从单元格中获取到的需求名称数据
StringBuilder name = new StringBuilder(
xr.getCell(5).getStringCellValue());
// 获取编号数据
int id = (int) xr.getCell(0).getNumericCellValue();
// 将数据添加到xml中
root.addElement("story").addText(name.toString()).addAttribute("id",
String.valueOf(id));
// 拼接字符串使其能存储在模版文件中
name.append("(#").append(id).append(")");
// 在新的工作簿中写入数据
XSSFRow temxr;
// 判断行是否已被创建若未被创建则向工作簿中创建行
if ((temxr = temxs.getRow(i - 1)) == null) {
temxr = temxs.createRow(i - 1);
}
// 创建单元格用于录入数据
temxr.createCell(0).setCellValue(name.toString());
}
// 使用dom4j的漂亮格式
OutputFormat format = OutputFormat.createPrettyPrint();
// 设置xml文件的编码方式
format.setEncoding("GBK");
// 写入xml
XMLWriter xmlWriter = new XMLWriter(
new FileOutputStream(savePath.toString() + ("StoryData.xml")),
format);
xmlWriter.write(dom);
xmlWriter.close();
// 定义输出流
FileOutputStream fop = new FileOutputStream(
new File(getSavePath() + getFileName() + ".xlsx"));
// 将temxw的内容写入到模版中
temxw.write(fop);
// 关闭流
fop.close();
// 关闭表格文件
xw.close();
temxw.close();
}
/**
* 该方法用于向模版中添加模块的数据有效性
*
* @throws IOException
*/
public static void setModuleDataValidation() throws IOException {
int id = ZentaoExcel.CASE_COLUMN_MODULE.getValue();
// 用于读取文件
FileInputStream fip = new FileInputStream(
getSavePath() + getFileName() + ".xlsx");
// 创建XSSFWorkbook对象用于向Excel文件中写入模版
XSSFWorkbook xw = new XSSFWorkbook(fip);
// 关闭流
fip.close();
// 创建指向工作簿的对象并命名为用例
XSSFSheet xs = xw.getSheet(ZentaoExcel.SHEET_CASE.getElement().attributeValue("name"));
// 加载下拉列表内容由于Excel对序列有字数的限制无法添加大量的数据进入序列所以需要使用以下的方法实现
// XSSFDataValidationConstraint constraint = new
// XSSFDataValidationConstraint(
// new String[]{"=$A$1:$A$12"});
// 计算存储模块的列的行数
XSSFSheet dataxs = xw.getSheet("系统数据");
int row = dataxs.getLastRowNum();
// 循环判断该行是否能获取到数据如果能则证明需求从该行获取结束
while (dataxs.getRow(row).getCell(id) == null) {
row--;
}
// 创建公式约束
DataValidationConstraint constraint = new XSSFDataValidationHelper(xs)
.createFormulaListConstraint(
"=系统数据!$B$1:$B$" + String.valueOf(row + 1));
// 设置数据有效性加载在哪个单元格上,四个参数分别是起始行终止行起始列终止列
CellRangeAddressList regions = new CellRangeAddressList(1,
xs.getLastRowNum(), id, id);
// 数据有效性对象
DataValidation d = new XSSFDataValidationHelper(xs)
.createValidation(constraint, regions);
xs.addValidationData(d);
// 向excel中写入数据
FileOutputStream fop = new FileOutputStream(
getSavePath() + getFileName() + ".xlsx");
// 写入模版
xw.write(fop);
// 关闭流
fop.close();
// 关闭表格文件
xw.close();
}
/**
* 该方法用于向模版中添加需求的数据有效性
*
* @throws IOException
*/
public static void setStoryDataValidation() throws IOException {
int id = ZentaoExcel.CASE_COLUMN_STORY.getValue();
// 用于读取文件
FileInputStream fip = new FileInputStream(
getSavePath() + getFileName() + ".xlsx");
// 创建XSSFWorkbook对象用于向Excel文件中写入模版
XSSFWorkbook xw = new XSSFWorkbook(fip);
// 关闭流
fip.close();
// 创建指向工作簿的对象并命名为用例
XSSFSheet xs = xw.getSheet(ZentaoExcel.SHEET_CASE.getElement().attributeValue("name"));
// 计算存储需求的列的行数
XSSFSheet dataxs = xw.getSheet("系统数据");
int row = dataxs.getLastRowNum();
// 循环判断该行是否能获取到数据如果能则证明需求从该行获取结束
while (dataxs.getRow(row).getCell(id) == null) {
row--;
}
// 创建公式约束
DataValidationConstraint constraint = new XSSFDataValidationHelper(xs)
.createFormulaListConstraint(
"=系统数据!$A$1:$A$" + String.valueOf(row + 1));
// 设置数据有效性加载在哪个单元格上,四个参数分别是起始行终止行起始列终止列
CellRangeAddressList regions = new CellRangeAddressList(1,
xs.getLastRowNum(), id, id);
// 数据有效性对象
DataValidation d = new XSSFDataValidationHelper(xs)
.createValidation(constraint, regions);
xs.addValidationData(d);
// 向excel中写入数据
FileOutputStream fop = new FileOutputStream(
getSavePath() + getFileName() + ".xlsx");
// 写入模版
xw.write(fop);
// 关闭流
fop.close();
// 关闭表格文件
xw.close();
}
/**
* 该方法用于添加优先级的数据有效性
*
* @throws IOException
*/
public static void setRankDataValidation() throws IOException {
int id = ZentaoExcel.CASE_COLUMN_RANK.getValue();
// 用于读取文件
FileInputStream fip = new FileInputStream(
getSavePath() + getFileName() + ".xlsx");
// 创建XSSFWorkbook对象用于向Excel文件中写入模版
XSSFWorkbook xw = new XSSFWorkbook(fip);
// 关闭流
fip.close();
// 创建指向工作簿的对象并命名为用例
XSSFSheet xs = xw.getSheet(ZentaoExcel.SHEET_CASE.getElement().attributeValue("name"));
// 创建优先级的数据有效性
XSSFDataValidationConstraint constraint = new XSSFDataValidationConstraint(
new String[] { "3", "1", "2", "4" });
// 设置数据有效性加载在哪个单元格上,四个参数分别是起始行终止行起始列终止列
CellRangeAddressList regions = new CellRangeAddressList(1,
xs.getLastRowNum(), id, id);
// 数据有效性对象
DataValidation d = new XSSFDataValidationHelper(xs)
.createValidation(constraint, regions);
// 添加数据有效性
xs.addValidationData(d);
// 向excel中写入数据
FileOutputStream fop = new FileOutputStream(
getSavePath() + getFileName() + ".xlsx");
// 写入模版
xw.write(fop);
// 关闭流
fop.close();
// 关闭表格文件
xw.close();
}
/**
* 该方法用于添加用例状态的数据有效性
*
* @throws IOException
*/
public static void setStateDataValidation() throws IOException {
int id = ZentaoExcel.CASE_COLUMN_STATE.getValue();
// 用于读取文件
FileInputStream fip = new FileInputStream(
getSavePath() + getFileName() + ".xlsx");
// 创建XSSFWorkbook对象用于向Excel文件中写入模版
XSSFWorkbook xw = new XSSFWorkbook(fip);
// 关闭流
fip.close();
// 创建指向工作簿的对象并命名为用例
XSSFSheet xs = xw.getSheet(ZentaoExcel.SHEET_CASE.getElement().attributeValue("name"));
// 添加用例状态的数据有效性
XSSFDataValidationConstraint constraint = new XSSFDataValidationConstraint(
new String[] { "待评审", "正常", "被阻塞", "研究中" });
CellRangeAddressList regions = new CellRangeAddressList(1,
xs.getLastRowNum(), id, id);
DataValidation d = new XSSFDataValidationHelper(xs)
.createValidation(constraint, regions);
xs.addValidationData(d);
// 向excel中写入数据
FileOutputStream fop = new FileOutputStream(
getSavePath() + getFileName() + ".xlsx");
// 写入模版
xw.write(fop);
// 关闭流
fop.close();
// 关闭表格文件
xw.close();
}
/**
* 该方法用于添加适用阶段的数据有效性
*
* @throws IOException
*/
public static void setStageDataValidation() throws IOException {
int id = ZentaoExcel.CASE_COLUMN_STAGE.getValue();
// 用于读取文件
FileInputStream fip = new FileInputStream(
getSavePath() + getFileName() + ".xlsx");
// 创建XSSFWorkbook对象用于向Excel文件中写入模版
XSSFWorkbook xw = new XSSFWorkbook(fip);
// 关闭流
fip.close();
// 创建指向工作簿的对象并命名为用例
XSSFSheet xs = xw.getSheet(ZentaoExcel.SHEET_CASE.getElement().attributeValue("name"));
// 添加用例状态的数据有效性
XSSFDataValidationConstraint constraint = new XSSFDataValidationConstraint(
new String[] { "单元测试阶段", "功能测试阶段", "集成测试阶段", "系统测试阶段", "冒烟测试阶段",
"版本验证阶段" });
CellRangeAddressList regions = new CellRangeAddressList(1,
xs.getLastRowNum(), id, id);
DataValidation d = new XSSFDataValidationHelper(xs)
.createValidation(constraint, regions);
xs.addValidationData(d);
// 向excel中写入数据
FileOutputStream fop = new FileOutputStream(
getSavePath() + getFileName() + ".xlsx");
// 写入模版
xw.write(fop);
// 关闭流
fop.close();
// 关闭表格文件
xw.close();
}
/**
* 该方法用于添加用例类型的数据有效性
*
* @throws IOException
*/
public static void setTypeDataValidation() throws IOException {
int id = ZentaoExcel.CASE_COLUMN_TYPE.getValue();
// 用于读取文件
FileInputStream fip = new FileInputStream(
getSavePath() + getFileName() + ".xlsx");
// 创建XSSFWorkbook对象用于向Excel文件中写入模版
XSSFWorkbook xw = new XSSFWorkbook(fip);
// 关闭流
fip.close();
// 创建指向工作簿的对象并命名为用例
XSSFSheet xs = xw.getSheet(ZentaoExcel.SHEET_CASE.getElement().attributeValue("name"));
// 添加用例状态的数据有效性
XSSFDataValidationConstraint constraint = new XSSFDataValidationConstraint(
new String[] { "功能测试", "性能测试", "配置相关", "安装部署", "安全相关", "接口测试",
"其他" });
CellRangeAddressList regions = new CellRangeAddressList(1,
xs.getLastRowNum(), id, id);
DataValidation d = new XSSFDataValidationHelper(xs)
.createValidation(constraint, regions);
xs.addValidationData(d);
// 向excel中写入数据
FileOutputStream fop = new FileOutputStream(
getSavePath() + getFileName() + ".xlsx");
// 写入模版
xw.write(fop);
// 关闭流
fop.close();
// 关闭表格文件
xw.close();
}
/**
* 该方法用于设置所有类型的数据有效性
*
* @throws IOException
*/
public static void setAllDataValidation() throws IOException {
// 添加模块信息的数据有效性若抛出异常则说明未定义模块信息的数据有效性则不添加
try {
setModuleDataValidation();
} catch (NullPointerException e) {
}
// 添加需求信息的数据有效性若抛出异常则说明未定义模块信息的数据有效性则不添加
try {
setStoryDataValidation();
} catch (NullPointerException e) {
}
// 添加优先级的数据有效性
setRankDataValidation();
// 添加用例状态的数据有效性
setStateDataValidation();
// 添加适用阶段的数据
setStageDataValidation();
// 添加用例类型的数据有效性
setTypeDataValidation();
}
/**
* 该方法用于对测试用例文件进行处理以便于上传至禅道
*
* @param caseFile
* 测试用例文件
* @throws IOException
*/
public static void disposeCaseFile(File caseFile) throws IOException {
// 定义输入流用于读取模版文件
FileInputStream fip = new FileInputStream(caseFile);
// 通过输入流使XSSFWorkbook对象指向模版文件
XSSFWorkbook xw = new XSSFWorkbook(fip);
// 关闭流
fip.close();
// 获取名为用例的工作簿
XSSFSheet xs = xw.getSheet(ZentaoExcel.SHEET_CASE.getElement().attributeValue("name"));
// 循环重头遍历所有的行
for (int i = 1; i < xs.getLastRowNum() + 1; i++) {
// 读取测试步骤一列的数据
XSSFCell xcs = xs.getRow(i).getCell(ZentaoExcel.CASE_COLUMN_STEP.getValue());
// 存储获取到的步骤文字
StringBuilder sbs = new StringBuilder(xcs.getStringCellValue());
// 对文本内容拆分后判断其数组是否只包含一个数据若只包含一个数据则添加序号2.
if (sbs.toString().split("\\n").length == 1
&& !sbs.toString().equals("")) {
// 确认步骤只存在一条时再读取预期信息以加快获取速度
XSSFCell xce = xs.getRow(i).getCell(ZentaoExcel.CASE_COLUMN_EXPECT.getValue());
StringBuilder sbe = new StringBuilder(xce.getStringCellValue());
sbs.append("\r\n2.");
sbe.append("\r\n2.");
// 重写表格中的内容
xcs.setCellValue(sbs.toString());
xce.setCellValue(sbe.toString());
}
}
FileOutputStream fop = new FileOutputStream(caseFile);
// 写入excel文件
xw.write(fop);
// 关闭流
fop.close();
xw.close();
}
/**
* 该方法用于向模版中写入数据
*
* @param f
*/
private static void writeTemplet(File f) {
// 创建excel文件
XSSFWorkbook xw = new XSSFWorkbook();
// 读取xml文件的信息
Document d = null;
try {
d = new SAXReader().read(new File(CONFIG_FILE_PATH));
} catch (DocumentException e) {
e.printStackTrace();
}
// 读取所有sheet标签
List<?> sheetList = d.getRootElement().elements("sheet");
// 循环创建sheet
for (int i = 0; i < sheetList.size(); i++) {
// 获取标签的name属性并将该属性值作为sheet的名称
XSSFSheet xs = xw.createSheet(((Element) (sheetList.get(i))).attributeValue("name"));
// 获取sheet标签下的所有column标签
List<?> columnList = ((Element) (sheetList.get(i))).elements("column");
// 创建第一行用于编写表头
XSSFRow xr = xs.createRow(0);
// 循环创建单元格并将其赋值
for (int j = 0; j < columnList.size(); j++) {
// 创建单元格
XSSFCell xc = xr.createCell(j);
// 填写表头
xc.setCellValue(((Element) (columnList.get(j))).attributeValue("name"));
// 读取宽度信息并设置单元格的宽度
xs.setColumnWidth(j,
(short) (Double.valueOf(((Element) (columnList.get(j))).attributeValue("wide")) * 256));
// 创建样式
XSSFCellStyle xcs = xw.createCellStyle();
// 设置单元格水平居中
xcs.setAlignment(HorizontalAlignment.CENTER);
// 设置单元格垂直居中
xcs.setVerticalAlignment(VerticalAlignment.CENTER);
// 创建字体样式
XSSFFont xf = xw.createFont();
// 设置字体名称
xf.setFontName("宋体");
// 设置字体大小注意字体大小单位为磅小四字体对应12磅
xf.setFontHeightInPoints((short) 12);
// 设置字体加粗
xf.setBold(true);
// 设置字体的样式
xcs.setFont(xf);
// 设置单元格自动换行
xcs.setWrapText(true);
// 设置单元格的样式
xc.setCellStyle(xcs);
}
// 添加筛选按钮
xs.setAutoFilter(CellRangeAddress.valueOf(
(String.valueOf((char) (65)) + "1:" + String.valueOf((char) (65 + columnList.size() - 1)) + "1")));
// 冻结表格
int z = Integer.valueOf(((Element) (sheetList.get(i))).attributeValue("freeze"));
xs.createFreezePane(z, 1, z, 1);
}
// 将预设内容写入Excel文件中异常直接处理不抛出
try {
// 定义输出流用于向指定的Excel文件中写入内容
FileOutputStream fop = new FileOutputStream(f);
// 写入文件
xw.write(fop);
// 关闭流
fop.close();
xw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 用于写入单元格信息
*/
/*
private XSSFCell writeCell(XSSFRow xr, Excel value, String context) {
XSSFCell xc = xr.createCell(Integer.valueOf(value.getValue()));
// 创建并写入操作系统信息
xc.setCellValue(context);
xc.setCellStyle(textStyle(xr.getSheet().getWorkbook(), value.getElement().attributeValue("align")));
return xc;
}
*/
/**
* 创建文本样式其按照传入的参数进行选定
*/
/*
private XSSFCellStyle textStyle(XSSFWorkbook xw, String align) {
// 创建样式
XSSFCellStyle xcs = xw.createCellStyle();
// 设置单元格水平居中
if (align.equalsIgnoreCase("center")) {
xcs.setAlignment(HorizontalAlignment.CENTER);
} else {
xcs.setAlignment(HorizontalAlignment.LEFT);
}
// 设置单元格垂直居中
xcs.setVerticalAlignment(VerticalAlignment.CENTER);
// 创建字体样式
XSSFFont xf = xw.createFont();
// 设置字体名称
xf.setFontName("宋体");
// 设置字体大小注意字体大小单位为磅小四字体对应12磅
xf.setFontHeightInPoints((short) 12);
// 设置字体的样式
xcs.setFont(xf);
// 设置单元格自动换行
xcs.setWrapText(true);
// 设置单元格的样式
return xcs;
}
*/
/**
* 该方法用于设置项目的样式
*/
/*
private static XSSFCellStyle style(XSSFWorkbook xw) {
XSSFCellStyle xs = xw.createCellStyle();
// 设置内容的水平居中对齐:HorizontalAlignment.CENTER
// 设置内容的水平左对齐:HorizontalAlignment.LEFT
// 设置内容的水平右对齐:HorizontalAlignment.RIGHT
xs.setAlignment(HorizontalAlignment.CENTER);
// 设置内容的垂直居中VerticalAlignment.CENTER
// 设置内容的底端对齐VerticalAlignment.BOTTOM
// 设置内容的顶端对齐VerticalAlignment.TOP
xs.setVerticalAlignment(VerticalAlignment.CENTER);
// 设置单元格自动换行
xs.setWrapText(true);
// 设置字体的样式
xs.setFont(font(xw));
return xs;
}
*/
/**
* 该方法用于设置字体
*/
/*
private static XSSFFont font(XSSFWorkbook xw) {
XSSFFont xf = xw.createFont();
// 设置字体名称
xf.setFontName("宋体");
// 设置字体大小注意字体大小单位为磅小四字体对应12磅
xf.setFontHeightInPoints((short) 12);
// 设置字体加粗
xf.setBold(true);
return xf;
}
*/
}

View File

@ -1,333 +0,0 @@
package pres.auxiliary.work.old.testcase.writecase;
import java.io.File;
import java.io.IOException;
import pres.auxiliary.work.old.testcase.change.Tab;
/**
* 该类用于生成预设的浏览列表相关的测试用例
*
* @author 彭宇琦
* @version Ver1.0
*/
public class BrowseList extends Case {
/**
* 在创建了模版后可调用该构造方法该构造会检测模版类中存储的模板文件保存路径及文件名若模板文件保存路径及文件名的其中一项为空
* 则抛出UndefinedDirectoryException异常此时请使用带参构造
*/
public BrowseList() {
super();
}
/**
* 用于指定模板文件对象
*
* @param excel
* 模板文件对象
* @throws IOException
*/
public BrowseList(File excel) throws IOException {
super(excel);
}
/**
* 该方法用于生成app上浏览列表的测试用例
*
* @param name
* 列表的名称
* @return Tab对象
* @throws IOException
*/
public Tab addAppBrowseListCase(String name) throws IOException {
//存储方法名
String methodName = "addAppBrowseListCase";
//存储变量信息
textMap.put("name", name);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 该方法用于生成web上列表的测试用例
*
* @param name
* 列表的名称
* @return Tab对象
* @throws IOException
*/
public Tab addWebBrowseListCase(String name) throws IOException {
//存储方法名
String methodName = "addWebBrowseListCase";
//存储变量信息
textMap.put("name", name);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 该方法用于添加输入条件对列表进行搜索的测试用例
*
* @param condition
* 搜索的条件
* @param information
* 被搜索信息的名称
* @return Tab对象
* @throws IOException
*/
public Tab addInputSearchCase(String condition, String information)
throws IOException {
//存储方法名
String methodName = "addInputSearchCase";
//存储变量信息
textMap.put("condition", condition);
textMap.put("information", information);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 该方法用于添加选择条件对列表进行搜索的测试用例
*
* @param condition
* 搜索的条件
* @param information
* 被搜索信息的名称
* @return Tab对象
* @throws IOException
*/
public Tab addSelectSearchCase(String condition, String information)
throws IOException {
//存储方法名
String methodName = "addSelectSearchCase";
//存储变量信息
textMap.put("condition", condition);
textMap.put("information", information);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 该方法用于添加通过时间或时间段对列表进行搜索的测试用例
*
* @param condition
* 搜索的条件名称
* @param isTimeSlot
* 是否为时间段
* @param information
* 被搜索信息的名称
* @return Tab对象
* @throws IOException
*/
public Tab addDateSearchCase(String condition, boolean isTimeSlot,
String information) throws IOException {
//存储方法名
String methodName = "addDateSearchCase";
//存储变量信息
textMap.put("condition", condition);
textMap.put("information", information);
textMap.put("s", isTimeSlot ? "时间段" : "时间");
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = null;
if ( !isTimeSlot ) {
contents = getStep(methodName, 1, 2, 3);
} else {
contents = getStep(methodName, -1);
}
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 该方法用于生成对列表排序的测试用例
*
* @param information
* 列表的名称
* @return Tab对象
* @throws IOException
*/
public Tab addListSortCase(String condition, String information) throws IOException {
//存储方法名
String methodName = "addListSortCase";
//存储变量信息
textMap.put("information", information);
textMap.put("condition", condition);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 该方法用于添加导出信息的测试用例
*
* @param information
* 列表的名称
* @param isCheck
* 是否可以勾选列表上的内容
* @return Tab对象
* @throws IOException
*/
public Tab addExportListCase(String information, boolean isCheck)
throws IOException {
//存储方法名
String methodName = "addExportListCase";
//存储变量信息
textMap.put("information", information);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = null;
if (isCheck) {
contents = getStep(methodName, 1, 5);
} else {
contents = getStep(methodName, 2, 3, 4, 5);
}
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 该方法用于添加导入信息的测试用例
*
* @param information
* 需要导入的信息名称
* @return Tab对象
* @throws IOException
*/
public Tab addImportListCase(String information) throws IOException {
//存储方法名
String methodName = "addImportListCase";
//存储变量信息
textMap.put("information", information);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 该方法用于生成重置搜索功能的测试用例
* @return
* @throws IOException
*/
public Tab addResetSearchCase() throws IOException {
//存储方法名
String methodName = "addResetSearchCase";
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 该方法用于生成切换列表单页数据显示量的用例
* @return
* @throws IOException
*/
public Tab addSwitchListShowDataCase() throws IOException {
//存储方法名
String methodName = "addSwitchListShowDataCase";
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
}

View File

@ -1,581 +0,0 @@
package pres.auxiliary.work.old.testcase.writecase;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFComment;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import pres.auxiliary.work.old.testcase.change.CaseTab;
import pres.auxiliary.work.old.testcase.change.Tab;
import pres.auxiliary.work.old.testcase.templet.ZentaoExcel;
import pres.auxiliary.work.old.testcase.templet.ZentaoTemplet;
/**
* 该类定义了所有预设用例都包含的基本信息<br/>
* <b><i>NOTE:若文件中存在手动添加的标注时应将标注标在用例标题那一列上以避免在插入表格时会被程序删除掉</i></b>
*
* @author 彭宇琦
* @version Ver2.1
* @since POI3.17
*/
public abstract class Case {
// 用于存储模版文件存储的位置
private static StringBuilder savePath = new StringBuilder(
ZentaoTemplet.getSavePath());
// 用于存储模版文件存储的位置
private static StringBuilder fileName = new StringBuilder(
ZentaoTemplet.getFileName() + ".xlsx");
// 用于存储所属模块信息
private static StringBuilder module = new StringBuilder();
// 用于存储当前测试用例的位置永远指向被新插入的测试用例的位置
private static int insertRowNum = 0;
//TODO 续写会有序号不正确的问题需要解决
//用于记录模块序号
private static int moduleId = 0;
//用于记录用例序号
private static int caseId = 0;
//用于配置模块及用例条数的最大值位数例如编号最大到Test_99_99则其位数都设置为2编号最大到Test_999_99则其模块位数都设置为3用例位数为2
private static int ModuleNum = 2;
private static int CaseNum = 2;
//用于存储模块信息
private HashMap<String, Integer> moduleMap = new HashMap<String, Integer>();
private HashMap<String, Integer> caseMap = new HashMap<String, Integer>();
//存储测试用例模板的文件夹位置
private final String CASE_TEMPLET_FOLDER = "ConfigurationFiles/CaseConfigurationFile/CaseTemplet/";
//存储读取xml文件的类对象
Document dom;
//用于存储需要编写的变量信息
HashMap<String, String> textMap = new HashMap<String, String>();
/**
* 在创建了模版后可调用该构造方法该构造会检测模版类中存储的模板文件保存路径及文件名若模板文件保存路径及文件名的其中一项为空
* 则抛出UndefinedDirectoryException异常此时请使用带参构造
*/
public Case() {
if (getSavePath().equals("") || getFileName().equals("")) {
throw new UndefinedDirectoryException("未指定excel文件存储路径");
}
if ( !this.getClass().getSimpleName().equals("PresetCase") && !this.getClass().getSimpleName().equals("MyCase") ) {
try {
dom = new SAXReader().read(new File(CASE_TEMPLET_FOLDER + this.getClass().getSimpleName() + ".xml"));
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
/**
* 用于指定模板文件对象
*
* @param excel
* 模板文件对象
* @throws IOException
*/
public Case(File excel) throws IOException {
setExcelFile(excel);
if ( !this.getClass().getSimpleName().equals("PresetCase") && !this.getClass().getSimpleName().equals("MyCase") ) {
try {
dom = new SAXReader().read(new File(CASE_TEMPLET_FOLDER + this.getClass().getSimpleName() + ".xml"));
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
/**
* 该方法用于返回模板文件名
*
* @return 文件名
*/
public String getFileName() {
return fileName.toString();
}
/**
* 该方法用于返回模版存储路径
*
* @return 模版存储的路径
*/
public String getSavePath() {
return savePath.toString();
}
/**
* 该方法用于指定模板文件
*
* @param excelFile
* 模版文件对象
* @throws IOException
*/
public void setExcelFile(File excelFile) throws IOException {
// 读取文件名存入fileName中
Case.fileName.delete(0, Case.fileName.length());
Case.fileName.append(excelFile.getName());
// 读取存储路径存入savePath中
Case.savePath.delete(0, Case.savePath.length());
Case.savePath.append(excelFile.getParent() + "\\");
}
/**
* 该方法用于返回测试用例文件的文件对象
*
* @return 测试用例文件的文件对象
*/
public File getTempletFile() {
return new File(savePath.toString() + fileName.toString());
}
/**
* 该方法用于返回存储的所属模块信息
*
* @return 存储的所属模块信息
*/
public String getModule() {
return module.toString();
}
/**
* 该方法用于设置所属模块信息
*
* @param module
* 待存储的所属模块信息
*/
public void setModule(String module) {
if (Case.module.toString().equals(module)) {
return;
}
Case.module.delete(0, Case.module.length());
Case.module.append(module);
//若模块信息不存在时则初始化序号
if ( !moduleMap.containsKey(module) ) {
moduleId++;
caseId = 0;
moduleMap.put(module, moduleId);
caseMap.put(module, caseId);
} else {
moduleId = moduleMap.get(module);
caseId = caseMap.get(module);
}
// 读取xml中的模块数据
try {
// 读取模版的数据
Document dom = new SAXReader()
.read(new File(savePath.toString() + "ModuleData.xml"));
// 解析传入的模块信息
String[] s = module.split("\\/");
// 定义xpath
String xpath = "/data";
// 循环将模块信息解析成xpath
for (int i = 1; i < s.length; i++) {
xpath += ("/module[@name='" + s[i] + "']");
}
// 在xml中查找模块信息
Element e = (Element) dom.selectSingleNode(xpath);
// 如果查找到该元素则读取其元素的id属性向模块中继续添加该模块在禅道中的信息否则将不做更改
if (e != null) {
// 添加在上传禅道时需要填写格式
Case.module.append("(#");
// 读取元素的id属性并该属性的值写入模块信息中
Case.module.append(e.attributeValue("id"));
Case.module.append(")");
} else {
return;
}
// 如果未读到数据则会抛出DocumentException异常此时则不更改添加的模块信息
} catch (DocumentException e) {
return;
}
}
/**
* 用于返回模块序号的长度位数例如位数为2则表示模块序号为两位数序号不足两位数的则前方补0两位数序号为12时显示为12序号为9时显示为09
* @return 返回模块序号位数
*/
public static int getModuleNum() {
return ModuleNum;
}
/**
* 用于设置模块序号的长度位数例如位数为2则表示模块序号为两位数序号不足两位数的则前方补0两位数序号为12时显示为12序号为9时显示为09
* @param moduleNum 需要设置的模块序号位数
*/
public static void setModuleNum(int moduleNum) {
ModuleNum = moduleNum;
}
/**
* 用于返回用例序号的长度位数例如位数为2则表示用例序号为两位数序号不足两位数的则前方补0两位数序号为12时显示为12序号为9时显示为09
* @return 返回用例序号位数
*/
public static int getCaseNum() {
return CaseNum;
}
/**
* 用于设置用例序号的长度位数例如位数为2则表示用例序号为两位数序号不足两位数的则前方补0两位数序号为12时显示为12序号为9时显示为09
* @param caseNum 需要设置的用例序号位数
*/
public static void setCaseNum(int caseNum) {
CaseNum = caseNum;
}
/**
* 该方法用于向测试用例文件中插入一条空的测试用例等价于预留一个位置
*
* @return Tab对象
* @throws IOException
*/
public Tab addEmptyCase() throws IOException {
return after("", new StringBuilder("\r\n"), new StringBuilder("\r\n"),
"", 1, "");
}
/**
* 封装各个方法结束前必须使用的代码
*
* @param title
* 用例标题
* @param step
* 用例步骤
* @param expectation
* 用例预期
* @param keyword
* 用例关键词
* @param rank
* 优先级
* @param precondition
* 前置条件
* @throws IOException
*/
protected Tab after(String title, StringBuilder step,
StringBuilder expectation, String keyword, int rank,
String precondition) throws IOException {
// 若stepexpectation中最后一个是空行\r\n则处理其最后一个空行
if (step.lastIndexOf("\r\n") == step.length() - 2) {
step.delete(step.lastIndexOf("\r\n"), step.lastIndexOf("\r\n") + 3);
}
if (expectation.lastIndexOf("\r\n") == expectation.length() - 2) {
expectation.delete(expectation.lastIndexOf("\r\n"),
expectation.lastIndexOf("\r\n") + 3);
}
// 定义输入流用于读取模版文件
FileInputStream fip = new FileInputStream(
new File(getSavePath() + getFileName()));
// 通过输入流使XSSFWorkbook对象指向模版文件
XSSFWorkbook xw = new XSSFWorkbook(fip);
// 关闭流
fip.close();
// 获取用例的工作簿
XSSFSheet xs = xw.getSheet(
ZentaoExcel.SHEET_CASE.getElement().attributeValue("name"));
// 判断新加入的测试用例其模块是否与文件中最后一行的模块信息一致若一致则直接向下方添加一行若不是则判断该模块是否存在与文件中
XSSFRow xr;
if (getModule().equals(xs.getRow(insertRowNum)
.getCell(ZentaoExcel.CASE_COLUMN_MODULE.getValue())
.getStringCellValue())) {
// 判断当前caseNum指向的行是否为最后一行若是最后一行则直接向下增加测试用例若不是则调用插入行的方式将测试用例插入表格中
if (insertRowNum == xs.getLastRowNum()) {
xr = xs.createRow(++insertRowNum);
} else {
// 在插入表格前需要将caseNum增加1以保证移动单元格时无误
++insertRowNum;
xr = insertRow(xs);
}
} else {
// 用于判断模块信息是否能在文件的表格中查找得到
boolean isHas = false;
// 循环判断文件中存储的模块是否包含正在添加的模块信息
for (int i = 0; i < xs.getLastRowNum(); i++) {
// 判断当前行查找的模块信息是否与正在添加的测试用例的模块信息相同若相同则将isHas变为true存储当前的行数并结束循环
if (xs.getRow(i)
.getCell(ZentaoExcel.CASE_COLUMN_MODULE.getValue())
.getStringCellValue().equals(getModule())) {
insertRowNum = i;
isHas = true;
break;
}
}
// 判断isHas中的信息若为false则说明整个文档中未查到该模块信息则直接在文档表格的最后一行添加测试用例
if (!isHas) {
insertRowNum = xs.getLastRowNum();
xr = xs.createRow(++insertRowNum);
} else {
// 如果在文件中查到了模块信息则需要将该测试用例插入到该模块现有的测试用例的最后一条
// 循环判断比该模块的最后一行多一行的行数即正好与需要添加的模块信息不同的那一行
for (int i = insertRowNum; i < xs.getLastRowNum(); i++) {
// 判断当前行查找的模块信息是否与正在添加的测试用例的模块信息相同若相同则将isHas变为true存储当前的行数并结束循环
if (!xs.getRow(i)
.getCell(ZentaoExcel.CASE_COLUMN_MODULE.getValue())
.getStringCellValue().equals(getModule())) {
insertRowNum = i;
break;
}
}
// 插入行
xr = insertRow(xs);
}
}
// 处理用例序号信息
String id = "Test_";
//判断模块和用例编号的位数是否达到 设置的位数位达到则补0
if ( String.valueOf(moduleId).length() < ModuleNum ) {
for ( int i = 0; i < ModuleNum - String.valueOf(moduleId).length(); i++ ) {
id += "0";
}
}
id += (moduleId + "_");
if ( String.valueOf(++caseId).length() < CaseNum ) {
for ( int i = 0; i < CaseNum - String.valueOf(caseId).length(); i++ ) {
id += "0";
}
}
id += (caseId);
//存储用例编号
caseMap.put(getModule(), caseId);
//添加序号信息
writeCell(xr, ZentaoExcel.CASE_COLUMN_CASE_ID, id);
// 添加所属模块信息
writeCell(xr, ZentaoExcel.CASE_COLUMN_MODULE, getModule());
// 添加用例标题信息
writeCell(xr, ZentaoExcel.CASE_COLUMN_TITLE, title);
// 添加用例步骤信息
writeCell(xr, ZentaoExcel.CASE_COLUMN_STEP, step.toString());
// 添加预期信息
writeCell(xr, ZentaoExcel.CASE_COLUMN_EXPECT, expectation.toString());
// 添加关键词信息
writeCell(xr, ZentaoExcel.CASE_COLUMN_KEYS, keyword);
// 添加用例类型信息
writeCell(xr, ZentaoExcel.CASE_COLUMN_TYPE, "功能测试");
// 添加优先级信息
writeCell(xr, ZentaoExcel.CASE_COLUMN_RANK, String.valueOf(rank));
// 添加用例状态信息
writeCell(xr, ZentaoExcel.CASE_COLUMN_STATE, "待评审");
// 添加适用阶段信息
writeCell(xr, ZentaoExcel.CASE_COLUMN_STAGE, "功能测试阶段");
// 添加前置条件信息
writeCell(xr, ZentaoExcel.CASE_COLUMN_CONDITION, precondition);
FileOutputStream fop = new FileOutputStream(
new File(getSavePath() + getFileName()));
// 写入excel文件
xw.write(fop);
// 关闭流
fop.close();
xw.close();
return CaseTab.newInstence(new File(getSavePath() + getFileName()));
}
/**
* 用于移动并插入单元格
*/
private XSSFRow insertRow(XSSFSheet xs) {
// 为避免移动后会删除用户添加的注解应添加处理方式保证移动表格后不会删除手动添加的标注若需要保证速度则可以注释掉对标注的处理
// 调用Map集合来存储行标以及标注对象
HashMap<Integer, XSSFComment> map = new HashMap<Integer, XSSFComment>();
// 循环判断该行的指定列是否包含标注若包含标注则将该行的行标及标注对象存入Map数组中
// 注意即使未移动的单元格中有标注也会受到影响故需要从头开始检测
for (int i = 0; i < xs.getLastRowNum() + 1; i++) {
if (xs.getRow(i).getCell(ZentaoExcel.CASE_COLUMN_TITLE.getValue()).getCellComment() != null) {
map.put(i, xs.getRow(i).getCell(2).getCellComment());
}
}
// 移动单元格
xs.shiftRows(insertRowNum, xs.getLastRowNum(), 1);
XSSFRow xr = xs.createRow(insertRowNum);
// 循环读取集合中的元素并获取第(key + 1)行的表格向该行指定的单元格中添加元素
for (Entry<Integer, XSSFComment> e : map.entrySet()) {
// 判断标注是否在未被移动的单元格上若是则行数不加1若不是则行数加1
if (e.getKey() < insertRowNum) {
xs.getRow(e.getKey()).getCell(2).setCellComment(e.getValue());
}
else {
xs.getRow(e.getKey() + 1).getCell(2)
.setCellComment(e.getValue());
}
}
return xr;
}
/**
* 该方法用于返回当前测试用例被插入到的位置
*/
public static int getInsertRowNum() {
return insertRowNum;
}
/**
* 用于获取并返回从xml文件中读取到的测试用例信息
* @param methodName 方法名
* @param nodeName 节点名称
* @return 模板中读取到的并加以修改后的文本
*/
protected String getContent(String methodName, String nodeName) {
//获取到相应方法的对应数据
Element e = (Element)(dom.selectSingleNode("/cases/case[@function='" + methodName + "']/" + nodeName));
//若传入的是读取前置条件的标签则需要循环读取
if ( nodeName.equals("preconditions") ) {
if ( e.elements().size() != 0 ) {
//用于写入步骤
int step = 0;
//用于存储读取的内容
StringBuilder sb = new StringBuilder();
List<?> childElemenets = e.elements();
//循环添加标签中的内容
for ( Object childElemenet : childElemenets ) {
sb.append(++step + ".");
sb.append(translateContent(((Element)(childElemenet)).attributeValue("value")));
sb.append("\r\n");
}
//删除多余的换行
sb.delete(sb.lastIndexOf("\r\n"), sb.length());
return sb.toString();
} else {
return "";
}
}
return translateContent(e.attributeValue("value"));
}
/**
* 用于获取并返回从xml文件中读取到的测试用例步骤与预期的信息注意返回值中包括步骤和预期的信息其信息使用*符号将其隔开
* @param methodName 方法名称
* @param ids 需要读取的标题id号
* @return 步骤及预期信息使用*符号隔开
*/
protected String[] getStep(String methodName, int... ids) {
StringBuilder st = new StringBuilder();
StringBuilder ex = new StringBuilder();
//用于存储步骤及预期前的序号
int step = 0;
//判断传入的结果中其下标值是否为-1-1则读取所有的步骤和预期标签
if ( ids.length == 1 && ids[0] == -1 ) {
//获取steps标签下所有的step标签
int size = dom.selectNodes("/cases/case[@function='" + methodName + "']/steps/step").size();
ids = new int[size];
//循环存储所有的标签的下标
for ( int i = 1; i < size + 1; i++ ) {
ids[i - 1] = i;
}
}
//循环读取所有需要读取的步骤预期标签
for ( int id : ids ) {
//获取到相应方法对应步骤数据
Element e = (Element)(dom.selectSingleNode("/cases/case[@function='" + methodName + "']/steps/step[@id='" + id + "']"));
st.append(++step + "." + translateContent(e.attributeValue("value")) + "\r\n");
//获取相应方法对应的预期数据先判断是否存在该ID的预期信息若存在则读取若不存在则跳过
if ((e = (Element)(dom.selectSingleNode("/cases/case[@function='" + methodName + "']/expectations/expectation[@id='" + id + "']"))) != null){
ex.append(step + "." + translateContent(e.attributeValue("value")) + "\r\n");
}
}
return new String[]{st.toString(), ex.toString()};
}
/**
* 用于将文本中的变量替换为map中存储的信息
*/
private String translateContent(String content) {
StringBuilder sb = new StringBuilder(content);
//存储替换符的位置
int index = 0;
//循环替换content中所有需要替换的信息
while( (index = sb.indexOf("*{")) != -1 ) {
//存储待替换的变量名
String var = sb.substring(index + "*{".length(), sb.indexOf("}*"));
//判断map中是否存储了该变量名
if ( textMap.containsKey(var) ) {
sb.replace(index, sb.indexOf("}*") + "}*".length(), textMap.get(var));
} else {
sb.replace(index, sb.indexOf("}*") + "}*".length(), "{" + var + "}");
}
}
return sb.toString();
}
/**
* 用于写入单元格信息
*/
private XSSFCell writeCell(XSSFRow xr, ZentaoExcel value, String context) {
XSSFCell xc = xr.createCell(Integer.valueOf(value.getValue()));
// 创建并写入操作系统信息
xc.setCellValue(context);
xc.setCellStyle(textStyle(xr.getSheet().getWorkbook(),
value.getElement().attributeValue("align")));
return xc;
}
/**
* 创建文本样式其按照传入的参数进行选定
*/
private XSSFCellStyle textStyle(XSSFWorkbook xw, String align) {
// 创建样式
XSSFCellStyle xcs = xw.createCellStyle();
// 设置单元格水平居中
if (align.equalsIgnoreCase("center")) {
xcs.setAlignment(HorizontalAlignment.CENTER);
} else {
xcs.setAlignment(HorizontalAlignment.LEFT);
}
// 设置单元格垂直居中
xcs.setVerticalAlignment(VerticalAlignment.CENTER);
// 创建字体样式
XSSFFont xf = xw.createFont();
// 设置字体名称
xf.setFontName("宋体");
// 设置字体大小注意字体大小单位为磅小四字体对应12磅
xf.setFontHeightInPoints((short) 12);
// 设置字体的样式
xcs.setFont(xf);
// 设置单元格自动换行
xcs.setWrapText(true);
// 设置单元格的样式
return xcs;
}
}

View File

@ -1,29 +0,0 @@
package pres.auxiliary.work.old.testcase.writecase;
/**
* 该类定义了常见的文件格式用于添加上传文件时的文件格式限定
*
* @author 彭宇琦
* @version Ver1.0
*/
public class FileType {
// 对文件格式的定义
/** 限制图片格式为jpg */
public static final char JPG = '1';
/** 限制图片格式为gif */
public static final char GIF = '2';
/** 限制图片格式为png */
public static final char PNG = '3';
/** 限制图片格式为bmp */
public static final char BMP = '4';
/** 限制文件格式为doc */
public static final char DOC = '5';
/** 限制文件格式为docx */
public static final char DOCX = '6';
/** 限制文件格式为txt */
public static final char TXT = '7';
/** 限制文件格式为xls */
public static final char XLS = '8';
/** 限制文件格式为xlsx */
public static final char XLSX = '9';
}

View File

@ -1,27 +0,0 @@
package pres.auxiliary.work.old.testcase.writecase;
/**
* 该类定义了在添加测试用例时的一些输入限定
*
* @author 彭宇琦
* @version Ver1.0
*/
public class InputType {
/**
* 设定文本框可输入数字
*/
public static final char NUM = '1';
/**
* 设定文本框可输入英文
*/
public static final char EN = '2';
/**
* 设定文本框可输入中文
*/
public static final char CH = '3';
/**
* 设定文本框可输入特殊字符
*/
public static final char SPE = '4';
}

View File

@ -1,165 +0,0 @@
package pres.auxiliary.work.old.testcase.writecase;
import java.io.File;
import java.io.IOException;
import pres.auxiliary.work.old.testcase.change.Tab;
public class Map extends Case {
/**
* 在创建了模版后可调用该构造方法该构造会检测模版类中存储的模板文件保存路径及文件名若模板文件保存路径及文件名的其中一项为空
* 则抛出UndefinedDirectoryException异常此时请使用带参构造
*/
public Map() {
super();
}
/**
* 用于指定模板文件对象
*
* @param excel
* 模板文件对象
* @throws IOException
*/
public Map(File excel) throws IOException {
super(excel);
}
/**
* 用于编写地图测距的测试用例
*
* @return
* @throws IOException
*/
public Tab addRangeFindingCase() throws IOException {
//存储方法名
String methodName = "addRangeFindingCase";
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 用于生成地图上单一定位点的测试用例
*
* @param pointName
* 定位点的名称
* @return
* @throws IOException
*/
public Tab addMapPointCase(String pointName) throws IOException {
//存储方法名
String methodName = "addMapPointCase";
//存储变量信息
textMap.put("pointName", pointName);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 用于添加对地图定位点搜索的测试用例
*
* @param condition
* 搜索条件
* @param name
* 搜索的信息
* @return
* @throws IOException
*/
public Tab addMapSearchInformationCase(String condition, String name)
throws IOException {
//存储方法名
String methodName = "addMapSearchInformationCase";
//存储变量信息
textMap.put("condition", condition);
textMap.put("name", name);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 用于添加与车辆轨迹回放相关的测试用例
* @return
* @throws IOException
*/
public Tab addCarLocusPlaybackCase() throws IOException {
//存储方法名
String methodName = "addCarLocusPlaybackCase";
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 该方法用于生成显示车辆轨迹的测试用例
* @param name 轨迹名称
* @param names 轨迹名称该变量为可变参数与name的作用一致可不传入参数
* @return
* @throws IOException
*/
public Tab addShowLocusCase(String name, String... names) throws IOException {
//存储方法名
String methodName = "addShowLocusCase";
String pointType = name + "";
for ( String s : names ) {
pointType += (s + "");
}
textMap.put("pointType", pointType.substring(0, pointType.lastIndexOf("")));
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
}

View File

@ -1,214 +0,0 @@
package pres.auxiliary.work.old.testcase.writecase;
import java.io.File;
import java.io.IOException;
import pres.auxiliary.work.old.testcase.change.CaseTab;
import pres.auxiliary.work.old.testcase.change.Tab;
/**
* 该类用于简单的编写一条测试用例
*
* @author 彭宇琦
* @version Ver1.1
*/
public class MyCase extends Case {
// 定义测试用例基本的信息
// 用于存储标题信息
private StringBuilder title = new StringBuilder("");
// 用于存储步骤信息
private StringBuilder step = new StringBuilder("");
// 用于存储预期信息
private StringBuilder expectation = new StringBuilder("");
// 用于存储关键词信息
private StringBuilder keyword = new StringBuilder("");
// 用于存储优先级信息
private int rank = 2;
// 用于存储前置条件
private StringBuilder precondition = new StringBuilder("");
/**
* 在创建了模版后可调用该构造方法该构造会检测模版类中存储的模板文件保存路径及文件名若模板文件保存路径及文件名的其中一项为空
* 则抛出UndefinedDirectoryException异常此时请使用带参构造
*/
public MyCase() {
super();
}
/**
* 用于指定模板文件对象
*
* @param excel
* 模板文件对象
* @throws IOException
*/
public MyCase(File excel) throws IOException {
super(excel);
}
/**
* 该方法可分步写入前置条件写入多条时可不带序号以及换行符<br/>
* setPrecondition("已在添加信息界面", "所有信息均正确填写");<br/>
* 则调用getPrecondition()方法后输出<br/>
* 1.已在添加信息界面<br/>
* 2.所有信息均正确填写<br/>
*
* @param preconditions
* 写入的多条前置条件
*/
public MyCase addPrecondition(String... preconditions) {
// 清除原存储的信息
this.precondition.delete(0, this.precondition.length());
// 循环分解preconditions并拼接前置条件存储precondition中
for (int i = 0; i < preconditions.length; i++) {
// 添加序号
precondition.append((i + 1) + ".");
// 添加传入的条件
precondition.append(preconditions[i]);
// 判断是否正在添加最后一个条件若不是则添加空行(\r\n)
if (i != preconditions.length - 1) {
precondition.append("\r\n");
}
}
return this;
}
/**
* 该方法可分步写入预期写入多条时可不带序号以及换行符<br/>
* setExpectation("已在添加信息界面", "所有信息均正确填写");<br/>
* 则调用getExpectation()方法后输出<br/>
* 1.已在添加信息界面<br/>
* 2.所有信息均正确填写<br/>
*
* @param expectations
* 写入的多条预期
* @return 类本身
*/
public MyCase addExpectation(String... expectations) {
// 清除原存储的信息
this.expectation.delete(0, this.expectation.length());
// 循环分解Expectations并拼接预期存储Expectation中
for (int i = 0; i < expectations.length; i++) {
// 添加序号
expectation.append((i + 1) + ".");
// 添加传入的条件
expectation.append(expectations[i]);
// 判断是否正在添加最后一个条件若不是则添加空行(\r\n)
if (i != expectations.length - 1) {
expectation.append("\r\n");
}
}
return this;
}
/**
* 该方法可分步写入步骤写入多条时可不带序号以及换行符<br/>
* setStep("已在添加信息界面", "所有信息均正确填写");<br/>
* 则调用getStep()方法后输出<br/>
* 1.已在添加信息界面<br/>
* 2.所有信息均正确填写<br/>
*
* @param steps
* 写入的多条步骤
*/
public MyCase addStep(String... steps) {
// 清除原存储的信息
this.step.delete(0, this.step.length());
// 循环分解steps并拼接步骤存储step中
for (int i = 0; i < steps.length; i++) {
// 添加序号
step.append((i + 1) + ".");
// 添加传入的条件
step.append(steps[i]);
// 判断是否正在添加最后一个条件若不是则添加空行(\r\n)
if (i != steps.length - 1) {
step.append("\r\n");
}
}
return this;
}
/**
* 该方法用于添加标题
*
* @param title
* 待添加的标题
* @return 类本身
*/
public MyCase addTitle(String title) {
this.title.delete(0, this.title.length());
this.title.append(title);
return this;
}
/**
* 该方法用于添加关键词
*
* @param keyword
* 待添加的关键词
* @return 类本身
*/
public MyCase addKeyword(String... keywords) {
// 清除原存储的信息
this.keyword.delete(0, this.keyword.length());
// 循环分解steps并拼接步骤存储step中
for (int i = 0; i < keywords.length; i++) {
// 添加传入的条件
keyword.append(keywords[i]);
// 判断是否正在添加最后一个条件若不是则添加空行(\r\n)
if (i != keywords.length - 1) {
keyword.append(",");
}
}
return this;
}
/**
* 该方法用于添加优先级
*
* @param rank
* 待添加的优先级
* @return 类本身
*/
public MyCase addRank(int rank) {
// 判断传入的优先级是否在1~4之间若不在则按默认的数据进行添加
if (0 < rank && 5 > rank) {
this.rank = rank;
}
return this;
}
/**
* 该方法用于在编写用例结束时调用的方法其作用是将编写的测试用例写入到文件中<br/>
* <b><i>NOTE若在测试用例编写结束后不调用该方法则测试用例无法被写入到文件中</i></b>
*
* @return 标记类对象用于标记该行的测试用例
* @throws IOException
*/
public Tab end() throws IOException {
//调用PresetCase类中的写入测试用例的方法
after(title.toString(), step, expectation, keyword.toString(), rank, precondition.toString());
//清除存储在类中的数据
this.title.delete(0, this.title.length());
this.step.delete(0, this.step.length());
this.expectation.delete(0, this.expectation.length());
this.keyword.delete(0, this.keyword.length());
this.precondition.delete(0, this.precondition.length());
//返回标记类对象
return CaseTab.newInstence(new File(getSavePath() + getFileName()));
}
/**
* 该方法用于将类中存储的数据转存入xml文件中以作为模版使用
*/
/*
public void caseToXml() {
//TODO 编写将用例存储在xml模版的方法
}
*/
}

View File

@ -1,40 +0,0 @@
package pres.auxiliary.work.old.testcase.writecase;
import java.io.File;
import java.io.IOException;
public class Operate extends Case {
/**
* 在创建了模版后可调用该构造方法该构造会检测模版类中存储的模板文件保存路径及文件名若模板文件保存路径及文件名的其中一项为空
* 则抛出UndefinedDirectoryException异常此时请使用带参构造
*/
public Operate() {
super();
}
/**
* 用于指定模板文件对象
*
* @param excel
* 模板文件对象
* @throws IOException
*/
public Operate(File excel) throws IOException {
super(excel);
}
/**
* 该方法用于生成编辑信息的测试用例
* @param name
*/
public void addEditCase(String name) {
}
/**
* 用于生成预览信息的测试用例
*/
public void addPreviewCase() {
}
}

View File

@ -1,18 +0,0 @@
package pres.auxiliary.work.old.testcase.writecase;
/**
* 该枚举定义了固定电话与移动电话类型用于添加针对号码类型的测试用例
*
* @author 彭宇琦
* @version Ver1.0
*/
public enum PhoneType {
/**
* 设置类型为移动电话手机
*/
MOBLE,
/**
* 设置类型为固定电话座机
*/
FIXED;
}

View File

@ -1,137 +0,0 @@
package pres.auxiliary.work.old.testcase.writecase;
import java.io.File;
import java.io.IOException;
/**
* 该类是测试用例对象调用的整合可通过该类中的get方法来调用所有测试用例生成类
*
* @author 彭宇琦
* @version Ver1.0
*/
public class PresetCase extends Case {
// 定义所有与生成预设用例相关的类
// TODO 当测试用例模版类增加时此处也必须继续添加
private AddInformation ai;
private BrowseList bl;
private Username us;
private Map ma;
private Operate oi;
private MyCase ca;
private Video vi;
public PresetCase() {
super();
}
/**
* 该构造用于当未通过ZentaoTemplet类创造模版创造测试用例文件时调用可用于续写测试用例
*
* @param excelTempletFile
* 测试用例文件对象
* @throws IOException
*/
public PresetCase(File excelTempletFile) throws IOException {
super(excelTempletFile);
}
//为每一个测试用例生成对象添加一个get方法
//TODO 当测试用例模版类增加时也得新增相应的get方法
/**
* 该方法用于返回生成新增信息的测试用例模版类
* @return AddInformation对象
* @throws IOException
*/
public AddInformation getAddInformation() throws IOException {
//判断对象是否为空再判断对象指向的文件是否与最新的测试用例文件excel对象一致若为空或者不一致则构造对象
if ( ai == null ) {
ai = new AddInformation(getTempletFile());
}
return ai;
}
/**
* 该方法用于返回登录相关的测试用例模版类
* @return Login对象
* @throws IOException
*/
public Username getUsername() throws IOException {
//判断对象是否为空再判断对象指向的文件是否与最新的测试用例文件excel对象一致若为空或者不一致则构造对象
if ( us == null ) {
us = new Username(getTempletFile());
}
return us;
}
/**
* 该方法用于返回浏览列表的测试用例模版类
* @return BrowseList对象
* @throws IOException
*/
public BrowseList getBrowseList() throws IOException {
//判断对象是否为空再判断对象指向的文件是否与最新的测试用例文件excel对象一致若为空或者不一致则构造对象
if ( bl == null ) {
bl = new BrowseList(getTempletFile());
}
return bl;
}
/**
* 该方法用于返回地图相关的测试用例模版类
* @return Map对象
* @throws IOException
*/
public Map getMap() throws IOException {
//判断对象是否为空再判断对象指向的文件是否与最新的测试用例文件excel对象一致若为空或者不一致则构造对象
if ( ma == null ) {
ma = new Map(getTempletFile());
}
return ma;
}
/**
* 该方法用于返回修改信息的测试用例模版类
* @return OperateInformation对象
* @throws IOException
*/
public Operate getOperateInformation() throws IOException {
//判断对象是否为空再判断对象指向的文件是否与最新的测试用例文件excel对象一致若为空或者不一致则构造对象
if ( oi == null ) {
oi = new Operate(getTempletFile());
}
return oi;
}
/**
* 该方法用于返回自定义编写测试用例类
* @return MyCase对象
* @throws IOException
*/
public MyCase getMyCase() throws IOException {
//判断对象是否为空再判断对象指向的文件是否与最新的测试用例文件excel对象一致若为空或者不一致则构造对象
if ( ca == null ) {
ca = new MyCase(getTempletFile());
}
return ca;
}
/**
* 该方法用于返回视频相关测试用例类
* @return Video对象
* @throws IOException
*/
public Video getVideo() throws IOException {
//判断对象是否为空再判断对象指向的文件是否与最新的测试用例文件excel对象一致若为空或者不一致则构造对象
if ( vi == null ) {
vi = new Video(getTempletFile());
}
return vi;
}
}

View File

@ -1,28 +0,0 @@
package pres.auxiliary.work.old.testcase.writecase;
public class UndefinedDirectoryException extends RuntimeException {
private static final long serialVersionUID = 1L;
public UndefinedDirectoryException() {
super();
}
public UndefinedDirectoryException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public UndefinedDirectoryException(String message, Throwable cause) {
super(message, cause);
}
public UndefinedDirectoryException(String message) {
super(message);
}
public UndefinedDirectoryException(Throwable cause) {
super(cause);
}
}

View File

@ -1,265 +0,0 @@
package pres.auxiliary.work.old.testcase.writecase;
import java.io.File;
import java.io.IOException;
import pres.auxiliary.work.old.testcase.change.Tab;
/**
* FileName: Username.java
*
* 用于生成与用户名及密码相关的测试用例如登录注册修改密码忘记密码等操作
*
* @author 彭宇琦
* @Deta 2018年6月13日 下午3:39:24
* @version ver1.0
*/
public class Username extends Case {
public Username() {
super();
}
public Username(File excel) throws IOException {
super(excel);
}
/**
* 该方法用于添加通过正确的用户名与密码进行登录的测试用例
*
* @return Tab对象
* @throws IOException
*/
public Tab addRightLoginCase() throws IOException {
//存储方法名
String methodName = "addRightLoginCase";
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 该方法用于添加通过非常规的用户名与密码进行登录的测试用例
*
* @return Tab对象
* @throws IOException
*/
public Tab addErrorLoginCase() throws IOException {
//存储方法名
String methodName = "addErrorLoginCase";
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 该方法用于添加通过输入不同的验证码进行登录的测试用例
*
* @return Tab对象
* @throws IOException
*/
public Tab addCaptchaCase() throws IOException {
//存储方法名
String methodName = "addCaptchaCase";
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 该方法用于添加通过不同权限的用户名与密码进行登录的测试用例
*
* @param isSparateLogin
* 是否需要分页分开登录
* @return Tab对象
* @throws IOException
*/
public Tab addLoginAuthorityCase(boolean isSparateLogin)
throws IOException {
//存储方法名
String methodName = "addLoginAuthorityCase";
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = null;
if ( isSparateLogin ) {
contents = getStep(methodName, -1);
}
else {
contents = getStep(methodName, 1);
}
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 用于生成注册不同用户名的测试用例
* @param isPhone 是否为手机号码注册
* @return
* @throws IOException
*/
public Tab addUsernameRegisterCase(boolean isPhone) throws IOException {
//存储方法名
String methodName = "addUsernameRegisterCase";
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = null;
if ( isPhone ) {
contents = getStep(methodName, 1, 2, 3, 4, 5, 7);
}
else {
contents = getStep(methodName, 1, 2, 6, 7);
}
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 用于生成通过不同用户名进行忘记密码操作的测试用例
* @return
* @throws IOException
*/
public Tab addUsernameForgetCase() throws IOException {
//存储方法名
String methodName = "addUsernameForgetCase";
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 用于生成注册不同密码的测试用例
* @param operation 操作的类型
* @return
* @throws IOException
*/
public Tab addPasswordRegisterOrForgetCase(String operation) throws IOException {
//存储方法名
String methodName = "addPasswordRegisterOrForgetCase";
//存储变量
textMap.put("operation", operation);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 用于生成通过不同验证码来注册的测试用例
* @param operation 操作的类型
* @param isPast 是否有过期时间
* @return
* @throws IOException
*/
public Tab addCodeRegisterOrForgetCase(String operation, boolean isPast) throws IOException {
//存储方法名
String methodName = "addCodeRegisterOrForgetCase";
//存储变量
textMap.put("operation", operation);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = null;
//判断是否有过期时间
if ( isPast ) {
contents = getStep(methodName, -1);
} else {
contents = getStep(methodName, 1, 2, 3, 4, 5);
}
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
/**
* 用于生成修改密码的测试用例
* @return
* @throws IOException
*/
public Tab addAlterPasswordCase() throws IOException {
//存储方法名
String methodName = "addAlterPasswordCase";
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
//添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank, precondition);
}
}

View File

@ -1,237 +0,0 @@
package pres.auxiliary.work.old.testcase.writecase;
import java.io.File;
import java.io.IOException;
import pres.auxiliary.work.old.testcase.change.Tab;
/**
* FileName: Video.java
*
* 用于生成与视频播放相关的测试用例
*
* @author 彭宇琦
* @Deta 2018年6月13日 上午9:14:30
* @version ver1.0
*/
public class Video extends Case {
private String videoType = "视频";
public Video() {
super();
}
public Video(File excel) throws IOException {
super(excel);
}
/**
* 用于返回当前设置的视频类型的名称
*
* @return
*/
public String getVideoType() {
return videoType;
}
/**
* 用于设置当前视频类型的名称
*
* @param videoType
*/
public void setVideoType(String videoType) {
this.videoType = videoType;
}
/**
* 该方法用于生成视频播放相关的测试用例
*
* @param isSpace
* 是否允许按下空格
* @return
* @throws IOException
*/
public Tab addPlayVideoCase(boolean isSpace) throws IOException {
// 存储方法名
String methodName = "addPlayVideoCase";
// 存储变量
textMap.put("videoType", videoType);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
// 添加步骤与预期
String[] contents = null;
// 判断是否有过期时间
if (isSpace) {
contents = getStep(methodName, -1);
} else {
contents = getStep(methodName, 1, 2, 3, 4, 6);
}
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank,
precondition);
}
/**
* 用于生成对视频进行截图的测试用例
*
* @return
* @throws IOException
*/
public Tab addVideoScreenshotCase() throws IOException {
// 存储方法名
String methodName = "addVideoScreenshotCase";
// 存储变量
textMap.put("videoType", videoType);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
// 添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank,
precondition);
}
/**
* 用于生成对视频快进快退的测试用例
*
* @param isDirection
* 是否允许按下键盘的方向键
* @param isInputSec
* 是否允许修改秒数
* @return
* @throws IOException
*/
public Tab addVideoAdvanceCase(boolean isDirection, boolean isInputSec) throws IOException {
// 存储方法名
String methodName = "addVideoAdvanceCase";
// 存储变量
textMap.put("videoType", videoType);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
// 判断是否允许按下键盘来快进快退
// 添加步骤与预期
String[] contents = null;
if (isDirection && isInputSec) {
contents = getStep(methodName, -1);
} else if (isDirection && !isInputSec) {
contents = getStep(methodName, 1, 2, 3, 4, 5, 6);
} else if (!isDirection && isInputSec) {
contents = getStep(methodName, 1, 2, 3, 4, 5, 7, 8, 9, 10);
} else {
contents = getStep(methodName, 1, 2, 3, 4, 5);
}
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank,
precondition);
}
/**
* 用于生成视频快放慢放的测试用例
*
* @param isSelect
* 是否允许用户选择倍率
* @return
* @throws IOException
*/
public Tab addVideoSpeedCase(boolean isSelect) throws IOException {
// 存储方法名
String methodName = "addVideoSpeedCase";
// 存储变量
textMap.put("videoType", videoType);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
// 添加步骤与预期
String[] contents = null;
if (isSelect) {
contents = getStep(methodName, -1);
} else {
contents = getStep(methodName, 1, 2, 3);
}
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank,
precondition);
}
/**
* 用于生成对视频进度条操作的测试用例
*
* @return
* @throws IOException
*/
public Tab addVideoProgressBarCase() throws IOException {
// 存储方法名
String methodName = "addVideoProgressBarCase";
// 存储变量
textMap.put("videoType", videoType);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
// 添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank,
precondition);
}
/**
* 用于生成视频全屏播放和退出全屏播放的操作测试用例
* @return
* @throws IOException
*/
public Tab addFullScreenPlayCase() throws IOException {
// 存储方法名
String methodName = "addFullScreenPlayCase";
// 存储变量
textMap.put("videoType", videoType);
// 添加标题信息
String title = getContent(methodName, "title");
// 添加关键词
String keyword = getContent(methodName, "keyword");
// 添加优先级
int rank = Integer.valueOf(getContent(methodName, "rank"));
// 添加前置条件
String precondition = getContent(methodName, "preconditions");
// 添加步骤与预期
String[] contents = getStep(methodName, -1);
return after(title, new StringBuilder(contents[0]), new StringBuilder(contents[1]), keyword, rank,
precondition);
}
}

View File

@ -20,10 +20,23 @@ import pres.auxiliary.work.testcase.file.IncorrectFileException;
* <p><b>修改时间</b>2020年3月4日 07:39:23</p>
* @author 彭宇琦
* @version Ver1.0
* @since JDK 12
* @since JDK 1.8
*
*/
public abstract class Case {
/**
* 用于指向用例标签中的name属性
*/
public static final String ATTRIBUTE_NAME = "name";
/**
* 用于指向用例标签中的value属性
*/
public static final String ATTRIBUTE_VALUE = "value";
/**
* 用于指向用例标签中的id属性
*/
public static final String ATTRIBUTE_ID = "id";
/**
* 用于标记获取标签下所有的文本
*/
@ -41,7 +54,7 @@ public abstract class Case {
/**
* 用于存储传入到正则表达式中的开始标记
*/
final String START_SIGN_REGIX = "\\*\\{";
protected final String START_SIGN_REGIX = "\\*\\{";
/**
* 用于指向测试用例xml文件的Document对象
@ -137,18 +150,11 @@ public abstract class Case {
* @return 标签中存储的文本并进行处理
*/
protected String getLabelText(String caseName, String labelName, String id) {
//定位case标签的名称属性名
String caseLabelNameAttribute = "name";
//定位标签中能指向调用用例的属性id
String labelIdAttribute = "id";
//定位相应标签中存储用例内容的属性
String labelValueAttribute = "value";
//拼接xpath规则"//case[@name='caseName']//标签名称[@id='id']"
String xpath = "//" + LabelType.CASE.getName() +
"[@" + caseLabelNameAttribute + "='" +
"[@" + ATTRIBUTE_NAME + "='" +
caseName + "']//" + labelName +
"[@" + labelIdAttribute + "='" + id +"']";
"[@" + ATTRIBUTE_ID + "='" + id +"']";
//获取相应的文本内容
Element textElement = (Element)(configXml.selectSingleNode(xpath));
@ -156,31 +162,26 @@ public abstract class Case {
//判断集合是否存在元素若不存在元素则抛出异常
if (textElement == null) {
throw new LabelNotFoundException("不存在的标签:<" + labelName + " " + labelIdAttribute + "='" + id +"'...>");
throw new LabelNotFoundException("用例集“" + caseName + "”中不存在id为“" + id + "”的“" + labelName + "”标签");
}
//返回处理替换的单词后相应的文本
return replaceText(textElement.attributeValue(labelValueAttribute));
return replaceText(textElement.attributeValue(ATTRIBUTE_VALUE));
}
/**
* 用于获取用例xml中对应用例的标签内所有的文本并返回替换词语后的文本
* @param caseName 用例名称
* @param label 标签枚举
* @param labelType 标签枚举
* @return 标签中存储的文本并进行处理
*/
@SuppressWarnings("unchecked")
protected ArrayList<String> getAllLabelText(String caseName, LabelType label) {
//定位case标签的名称属性名
String caseLabelNameAttribute = "name";
//定位相应标签中存储用例内容的属性
String labelValueAttribute = "value";
protected ArrayList<String> getAllLabelText(String caseName, LabelType labelType) {
//拼接xpath规则"//case[@name='caseName']//标签名称[@id='id']"
String xpath = "//" + LabelType.CASE.getName() +
"[@" + caseLabelNameAttribute + "='" +
caseName + "']//" + label.getName();
"[@" + ATTRIBUTE_NAME + "='" +
caseName + "']//" + labelType.getName();
//获取所有的节点
List<Element> textElements = configXml.selectNodes(xpath);
@ -188,7 +189,7 @@ public abstract class Case {
ArrayList<String> texts = new ArrayList<String>();
//存储节点值
for (int i = 0; i < textElements.size(); i++) {
texts.add(replaceText(textElements.get(i).attributeValue(labelValueAttribute)));
texts.add(replaceText(textElements.get(i).attributeValue(ATTRIBUTE_VALUE)));
}
return texts;
@ -199,14 +200,11 @@ public abstract class Case {
*/
@SuppressWarnings("unchecked")
private void saveWord() {
//定义能获取到文本的属性以便于后续的调整
String textAttribute = "value";
//获取xml中包含value的元素并将其中包含需要替换的词语存储至wordMap
List<Element> textElement = configXml.selectNodes("//*[@" + textAttribute + "]");
List<Element> textElement = configXml.selectNodes("//*[@" + ATTRIBUTE_VALUE + "]");
textElement.stream().
//获取元素的value属性将其转换为文本对象
map(e -> e.attributeValue(textAttribute)).
map(e -> e.attributeValue(ATTRIBUTE_VALUE)).
//筛选包含*{的文本
filter(e -> e.indexOf(START_SIGN) > -1).forEach(e -> {
//对文本按照*{切割并筛选包含}*的文本
@ -235,11 +233,11 @@ public abstract class Case {
/**
* 用于添加一行文本
* @param label 标签名称枚举
* @param labelType 标签名称枚举
* @param text 相应内容
*/
protected void addFieldText(LabelType label, String text) {
fieldTextMap.get(label.getName()).add(text);
protected void addFieldText(LabelType labelType, String text) {
fieldTextMap.get(labelType.getName()).add(text);
}
/**

View File

@ -0,0 +1,153 @@
package pres.auxiliary.work.testcase.templet;
import java.io.File;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import pres.auxiliary.tool.file.excel.CreateExcelFile;
import pres.auxiliary.work.testcase.file.JiraTestCaseWrite;
import pres.auxiliary.work.testcase.templet.UserCase.OprateType;
public class UserCaseTest {
/**
* 指向生成的测试用例文件
*/
File testCaseFile = new File("src/test/java/pres/auxiliary/work/testcase/templet/测试用例.xlsx");
/**
* 指向测试用例文件字段配置文件
*/
File templetXml = new File("ConfigurationFiles/CaseConfigurationFile/FileTemplet/JiraCaseFileTemplet/jira测试用例导入模板.xml");
/**
* 指向与InformationCase使用到的预设测试用例配置文件
*/
File browseListCase = new File("ConfigurationFiles/CaseConfigurationFile/CaseTemplet/Username.xml");
UserCase test = new UserCase(browseListCase);
/**
* 用于写入用例到文件中
*/
JiraTestCaseWrite tcw;
@BeforeClass
public void start() throws Exception {
CreateExcelFile tct = new CreateExcelFile(templetXml, testCaseFile);
//为方便演示则允许覆盖用例文件
tct.setCoverFile(true);
//生成用例文件
tct.create();
//初始化
tcw = new JiraTestCaseWrite(templetXml, testCaseFile);
//设置每条测试用例中值都一样的字段
tcw.setFieldValue("设计者", "彭宇琦");
tcw.setFieldValue("状态", "2");
}
@AfterClass
public void outputInformation() throws Exception {
//写入用例
tcw.writeFile();
//打开用例文件夹
java.awt.Desktop.getDesktop().open(testCaseFile.getParentFile());
java.awt.Desktop.getDesktop().open(testCaseFile);
}
@AfterMethod
public void endCase() {
tcw.end();
}
/**
* 用于测试{@link UserCase#rightLoginCase()}方法<br>
* 预期<br>
*
*/
@Test
public void rightLoginCaseTest() {
tcw.addCase(test.rightLoginCase());
}
/**
* 用于测试{@link UserCase#errorLoginCase()}方法<br>
* 预期<br>
*
*/
@Test
public void errorLoginCaseTest() {
tcw.addCase(test.errorLoginCase());
}
/**
* 用于测试{@link UserCase#captchaLoginCase()}方法<br>
* 预期<br>
*
*/
@Test
public void captchaLoginCaseTest() {
tcw.addCase(test.captchaLoginCase());
}
/**
* 用于测试{@link UserCase#loginAuthorityCase(boolean)}方法<br>
* 预期<br>
*
*/
@Test
public void loginAuthorityCaseTest() {
tcw.addCase(test.loginAuthorityCase(true));
}
/**
* 用于测试{@link UserCase#usernameRegisterCase}方法<br>
* 预期<br>
*
*/
@Test
public void usernameRegisterCaseTest() {
tcw.addCase(test.usernameRegisterCase(true));
}
/**
* 用于测试{@link UserCase#usernameForgetCase}方法<br>
* 预期<br>
*
*/
@Test
public void usernameForgetCaseTest() {
tcw.addCase(test.usernameForgetCase());
}
/**
* 用于测试{@link UserCase#passwordRegisterOrForgetCase(pres.auxiliary.work.testcase.templet.UserCase.OprateType)}方法<br>
* 预期<br>
*
*/
@Test
public void passwordRegisterOrForgetCaseTest() {
tcw.addCase(test.passwordRegisterOrForgetCase(OprateType.FORGET_PASSWORD));
}
/**
* 用于测试{@link UserCase#captchaOprateCase}方法<br>
* 预期<br>
*
*/
@Test
public void captchaOprateCaseTest() {
tcw.addCase(test.captchaOprateCase(OprateType.FORGET_PASSWORD, true));
}
/**
* 用于测试{@link UserCase#amendPasswordCase()}方法<br>
* 预期<br>
*
*/
@Test
public void amendPasswordCaseTest() {
tcw.addCase(test.amendPasswordCase());
}
}

View File

@ -0,0 +1,124 @@
package pres.auxiliary.work.testcase.templet;
import java.io.File;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import pres.auxiliary.tool.file.excel.CreateExcelFile;
import pres.auxiliary.work.testcase.file.JiraTestCaseWrite;
public class VideoCaseTest {
/**
* 指向生成的测试用例文件
*/
File testCaseFile = new File("src/test/java/pres/auxiliary/work/testcase/templet/测试用例.xlsx");
/**
* 指向测试用例文件字段配置文件
*/
File templetXml = new File("ConfigurationFiles/CaseConfigurationFile/FileTemplet/JiraCaseFileTemplet/jira测试用例导入模板.xml");
/**
* 指向与InformationCase使用到的预设测试用例配置文件
*/
File browseListCase = new File("ConfigurationFiles/CaseConfigurationFile/CaseTemplet/Video.xml");
VideoCase test = new VideoCase(browseListCase);
/**
* 用于写入用例到文件中
*/
JiraTestCaseWrite tcw;
@BeforeClass
public void start() throws Exception {
CreateExcelFile tct = new CreateExcelFile(templetXml, testCaseFile);
//为方便演示则允许覆盖用例文件
tct.setCoverFile(true);
//生成用例文件
tct.create();
//初始化
tcw = new JiraTestCaseWrite(templetXml, testCaseFile);
//设置每条测试用例中值都一样的字段
tcw.setFieldValue("设计者", "彭宇琦");
tcw.setFieldValue("状态", "2");
test.setReplaceWord(VideoCase.VIDEO_TYPE, "培训教育");
}
@AfterClass
public void outputInformation() throws Exception {
//写入用例
tcw.writeFile();
//打开用例文件夹
java.awt.Desktop.getDesktop().open(testCaseFile.getParentFile());
java.awt.Desktop.getDesktop().open(testCaseFile);
}
@AfterMethod
public void endCase() {
tcw.end();
}
/**
* 用于测试{@link VideoCase#playVideoCase(boolean)}方法<br>
* 预期<br>
*
*/
@Test
public void playVideoCaseTest() {
tcw.addCase(test.playVideoCase(true));
}
/**
* 用于测试{@link VideoCase#videoScreenshotCase()}方法<br>
* 预期<br>
*
*/
@Test
public void videoScreenshotCaseTest() {
tcw.addCase(test.videoScreenshotCase());
}
/**
* 用于测试{@link VideoCase#videoAdvanceCase(boolean, boolean)}方法<br>
* 预期<br>
*
*/
@Test
public void videoAdvanceCaseTest() {
tcw.addCase(test.videoAdvanceCase(true, true));
}
/**
* 用于测试{@link VideoCase#videoSpeedCase(boolean)}方法<br>
* 预期<br>
*
*/
@Test
public void videoSpeedCaseTest() {
tcw.addCase(test.videoSpeedCase(true));
}
/**
* 用于测试{@link VideoCase#videoProgressBarCase()}方法<br>
* 预期<br>
*
*/
@Test
public void videoProgressBarCaseTest() {
tcw.addCase(test.videoProgressBarCase());
}
/**
* 用于测试{@link VideoCase#videoFullScreenPlayCase()}方法<br>
* 预期<br>
*
*/
@Test
public void videoFullScreenPlayCaseTest() {
tcw.addCase(test.videoFullScreenPlayCase());
}
}

File diff suppressed because one or more lines are too long