Java+Selenium+TestNG混合驱动测试框架

在关键字驱动测试框架的基础上,部分使用数据驱动测试框架,例如:
如果在测试用例中有使用数据驱动,即在测试用例的“测试数据”列填写其数据源Sheet名称,如Templates。
在这里插入图片描述
在Templates中,邮件主题列是测试数据,其对应的是A列。
在这里插入图片描述
在测试用例VerifyCards的测试步骤中,将使用数据驱动的步骤的操作值用A表示
在这里插入图片描述
接下来更改ExcelUtil.java

package cn.summer.util;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import cn.summer.testScripts.TestSuiteByExcel;

//本类主要实现扩展名为“.xlsx”的Excel文件操作
public class ExcelUtil {
	private static XSSFSheet ExcelWSheet;
	private static XSSFWorkbook ExcelWBook;
	private static XSSFCell Cell;
	private static XSSFRow Row;
	
	//设定要操作的Excel文件的路径
	//在读/写Excel文件的时候,需要先设定要操作的Excel文件路径
	public static void setExcelFile(String Path)
	{
		
		FileInputStream ExcelFile;
		try {
			//实例化Excel文件的FileInputStream对象
			ExcelFile = new FileInputStream(Path);
			//实例化Excel文件的XSSFWorkbook对象
			ExcelWBook = new XSSFWorkbook(ExcelFile);
			
		}catch(Exception e) {
			TestSuiteByExcel.testResult = false;
			System.out.println("Excel路径设定失败");
			e.printStackTrace();			
		}
	}
	//设定要操作的Excel文件的路径和Excel文件中的Sheet名称
	//在读/写Excel文件的时候,设定要操作的Excel文件路径和要操作的Sheet名称
	public static void setExcelFile(String Path, String SheetName)
	{
		FileInputStream ExcelFile;
		try {
			//实例化Excel文件的FileInputStream对象
			ExcelFile = new FileInputStream(Path);
			//实例化Excel文件的XSSFWorkbook对象
			ExcelWBook = new XSSFWorkbook(ExcelFile);
			//实例化Sheet对象,指定Excel文件的Sheet名称,后续用于对Sheet中行、列和单元格的操作
			ExcelWSheet = ExcelWBook.getSheet(SheetName);
			
		}catch(Exception e) {
			TestSuiteByExcel.testResult = false;
			System.out.println("Excel路径设定失败");
			e.printStackTrace();
		}
	}
	//读取Excel文件,通过列字母获取列索引
	public static int excelColStrToNum(String colStr) {
		int num = 0;
		int result = 0;
		char ch = colStr.charAt(0);
		num = (int)(ch-'A');
		result += num;
		return result;
	}
	
	//读取Excel文件指定单元格的函数,此函数只支持扩展名为“.xlsx”的Excel文件
	public static String getCellData(String SheetName, int RowNum, int ColNum){
		ExcelWSheet = ExcelWBook.getSheet(SheetName);
		try {
			//通过函数参数指定单元格的行号和列号,获取指定的单元格对象
			Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);
			//如果单元格的内容为字符串类型,则使用getStringCellValue方法
			//如果单元格的内容为数字类型,则使用getNumericCellValue方法
			String CellData = Cell.getCellType()==XSSFCell.CELL_TYPE_STRING ? 
					Cell.getStringCellValue() + ""
					:String.valueOf(Math.round(Cell.getNumericCellValue()));
			//函数返回指定单元格的字符串内容
			return CellData;
			
		}catch(Exception e) {
			TestSuiteByExcel.testResult = false;
			e.printStackTrace();
			//如果读取遇到异常,则返回空字符串
			return "";
		}
	}
	//获取Excel文件中最后一行的列号
	//public static int getlastColumnNum() {
		//函数返回Sheet中最后一行的列号
		//return ExcelWSheet.getRow(0).getLastCellNum()-1;
	//}
	
	//获取Excel文件中最后一行的行号
	public static int getLastRowNum() {
		//函数返回Sheet中最后一行的行号
		return ExcelWSheet.getLastRowNum();
	}
	//获取指定Sheet中的数据总行数
	public static int getRowCount(String SheetName) {
		ExcelWSheet = ExcelWBook.getSheet(SheetName);
		int number = ExcelWSheet.getLastRowNum();
		return number;
	}
	//在Excel的指定Sheet中,获取第一次包含指定测试用例序号的行号
	public static int getFirstRowContainsTestCaseID(String sheetName, 
			String testCaseName, int colNum){
		int i;
		try {		
			ExcelWSheet = ExcelWBook.getSheet(sheetName);		
			int rowCount = ExcelUtil.getRowCount(sheetName);	
			//使用循环的方法遍历测试用例序号列的所有行,判断是否包含某个测试用例序号关键字
			for(i = 0; i<rowCount; i++) {	
				//如果包含,则退出for循环,并返回包含测试用例序号关键字的行号
				if(ExcelUtil.getCellData(sheetName, i, colNum).equalsIgnoreCase
						(testCaseName)) {				
					
					break;			
				}		
			}		
			return i;	
		}catch(Exception e) {
			TestSuiteByExcel.testResult = false;
			return 0;
		}
	}
	//获取指定Sheet中某个测试用例步骤的个数
	public static int getTestCaseLastStepRow(String SheetName, 
			String testCaseID, int testCaseStartRowNumber){
		try {		
			ExcelWSheet = ExcelWBook.getSheet(SheetName);	
			/*从包含的测试用例序号的第一行开始逐行遍历,知道某一行不出现指定测试用例序号
			*此时的遍历次数就是次测试用例步骤的个数
			*/
			for(int i = testCaseStartRowNumber; i<=ExcelUtil.
					getRowCount(SheetName)-1; i++) {			
				if(!testCaseID.equals(ExcelUtil.getCellData(SheetName,i, 
						Constant.Col_TestCase_ID))) {				
					int number = i;				
					return number;			
				}		
			}		
			int number = ExcelWSheet.getLastRowNum()+1;		
			return number;	
		}catch(Exception e) {		
			TestSuiteByExcel.testResult = false;		
			return 0;
		}
	}
	//在Excel文件的执行单元格中写入数据,此函数只支持扩展名为".xlsx"的Excel文件
	@SuppressWarnings("static-access")
	public static void setCellData(String SheetName, int RowNum, int ColNum, 
			String Result){
		ExcelWSheet = ExcelWBook.getSheet(SheetName);
		try {
			//获取Excel文件中的行对象
			Row = ExcelWSheet.getRow(RowNum);
			//如果单元格为空,则返回Null
			Cell = Row.getCell(ColNum, Row.RETURN_BLANK_AS_NULL);
			
			if(Cell == null) {
				/*当单元格对象是Null的时候,则创建单元格,如果单元格为空,
				 * 无法直接调用单元格对象的setCellValue方法设定单元格的值
				 */
				Cell = Row.createCell(ColNum);
				//创建单元格后,可以调用单元格对象的setCellValue方法设定单元格的值
				Cell.setCellValue(Result);
				
			}else {
				/*如果单元格中有内容,则可以直接调用单元格对象的setCellValue
				 * 方法设定单元格的值
				 */
				Cell.setCellValue(Result);
			}
			//实例化写入Excel文件的文件输出流对象
			FileOutputStream fileOut = new FileOutputStream(Constant
					.Excel_FilePath);
			//将内容写入Excel文件
			ExcelWBook.write(fileOut);
			//调用flush方法强制刷新写入文件
			fileOut.flush();
			//关闭文件输出流对象
			fileOut.close();			
		}catch(Exception e) {
			TestSuiteByExcel.testResult = false;
			e.printStackTrace();			
		}
	}	
}

更改Constant.java

package cn.summer.util;

public class Constant {
	//工程包、包名、上一级包名
	public static String projectDir;
	public static String packageName;
	public static String packageParentDir;
	
	//获取当前文件所在目录的父目录的绝对路径
	public static String parentDirPath = getParentPath();
	
	//测试用例及数据相关常量设定
	//Excel文件路径
	public static String Excel_FilePath = parentDirPath+"\\data\\混合驱动测试用例.xlsx";
	//objectMap.properties配置文件所在路径
	public static String ObjectMap_FilePath = parentDirPath+"\\data\\objectMap.properties";
	
	//"TestSuite" sheet中的列号常量设定
	//"TestSuite" Sheet名称
	public static final String Sheet_TestSuite_Name = "TestSuite";
	//第1列用0表示,为测试用例名称列
	public static final int Col_TestCase_ID = 0;
	//第4列用3表示,为是否运行列
	public static final int Col_TestCase_RunFlag = 3;
	//第5列用4表示,为测试数据列
	public static final int Col_DateSource_SheetName = 4;
	//第6列用5表示,为测试结果列
	public static final int Col_TestCase_TestResult = 5;
	
	//测试步骤Sheet的列号常量设定
	//第4列用3表示,为关键字列
	public static final int Col_KeyWordsAction = 3;
	//第5列用4表示,为操作元素的定位表达式列
	public static final int Col_LocatorExpression = 4;
	//第6列用5表示,为操作值列
	public static final int Col_OperateVaule = 5;
	//第7列用6表示,为是否运行列
	public static final int Col_TestStep_RunFlag = 6;	
	//第8列用7表示,为测试结果列
	public static final int Col_TestStep_TestResult = 7;
	
	//数据驱动Sheet中的列号常量设定
	
	//第2列用1表示,为是否执行
	public static final int Col_DataSource_RunFlag = 1;
	//第3列用2表示,为测试执行结果列
	public static final int Col_DataSource_TestResult = 2;
			
	//获取所在目录的父目录的绝对路径方法
	public static String getParentPath() {
		//获取工程路径
		projectDir = System.getProperty("user.dir")+"\\src";
		//获取类所在包名
		packageName = Constant.class.getPackage().getName();
		//获取类所在包的上一级包名
		packageParentDir = packageName.substring(0,packageName.lastIndexOf("."));
		//格式化包名为路径名
		packageParentDir = String.format("/%s/",packageParentDir.contains(".")?
				packageParentDir.replaceAll("\\.","/"):packageParentDir);
		return projectDir+packageParentDir;

	}		
    public static final String ChromeDriverPath = "D:\\CODE\\Java\\TestFramework\\Driver\\chromedriver.exe";
    public static final String FirefoxDriverPath = "";
    public static final String EdgeDriverPath = "";
    public static final String IEDriverPath = "";
    
    public static final String ScreenshotPath = "D:\\CODE\\Java\\TestFramework\\Screenshot\\";
}

更改TestSuiteByExcel.java

package cn.summer.testScripts;

import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.junit.BeforeClass;
import org.apache.log4j.xml.DOMConfigurator;
import org.testng.Assert;
import org.testng.annotations.Test;


import cn.summer.configuration.KeyWordsAction;
import cn.summer.util.*;


public class TestSuiteByExcel {
	public static Method method[];
	public static String keyword;
	public static String locatorExpression;
	public static String value;
	public static KeyWordsAction keyWordsaction;
	public static int testStep;
	public static String testData;
	public static int testLastStep;
	public static String testCaseID;
	public static String testDataRunFlag;
	public static String testCaseRunFlag;
	public static String testStepRunFlag;
	public static boolean testResult;
	
	
	@Test
	public void testTestSuite() throws Exception{
		//声明一个关键动作类的实例		
		keyWordsaction = new KeyWordsAction();
		//使用Java的反射机制获取KeyWordsAction类的所有方法对象
		method = keyWordsaction.getClass().getMethods();
		//定义Excel文件的路径
		String excelFilePath = Constant.Excel_FilePath;
		//设定读取Excel文件的"ReadEmail"Sheet为操作目标
		ExcelUtil.setExcelFile(excelFilePath);
		//读取“TestSuite”Sheet中的测试用例总数
		int testCasesCount = ExcelUtil.getRowCount(Constant.Sheet_TestSuite_Name);
		System.out.println("TestSuite表格中有 "+testCasesCount+" 行数据");
		//使用for循环,执行“TestSuite”Sheet中所有标记为“y”的测试用例
		for(int testCaseNo = 1; testCaseNo <= testCasesCount; testCaseNo++) {
			//读取“TestSuite”Sheet中每行的测试用例序号
			testCaseID = ExcelUtil.getCellData(Constant.Sheet_TestSuite_Name, testCaseNo, 
					Constant.Col_TestCase_ID);
			//读取“TestSuite”Sheet中每行的“是否运行”列中的值
			testCaseRunFlag = ExcelUtil.getCellData(Constant.Sheet_TestSuite_Name, testCaseNo, 
					Constant.Col_TestCase_RunFlag);
			//如果“是否运行”列中的值为“y”,则执行测试用例的所有步骤
			if(testCaseRunFlag.trim().equals("y")) {
				//在日志中打印测试用例开始执行的信息
				Log.startTestCase(testCaseID);
				//设定测试用例的当前结果为“true”,表明测试用例执行成功
				testResult = true;
				//在测试步骤Sheet(如“ReadMail01”)中,
				//获取当前要执行测试用例的第一个步骤所在行的行号
				testStep = ExcelUtil.getFirstRowContainsTestCaseID(
						testCaseID, testCaseID, Constant.Col_TestCase_ID);
			    //在“ReadMail01”Sheet中,获得当前要执行测试用例的最后一个步骤,所在行的行号
				testLastStep = ExcelUtil.getTestCaseLastStepRow(
						testCaseID, testCaseID, testStep);
				//读取“TestSuite”Sheet中的测试数据列内容
				testData = ExcelUtil.getCellData(Constant.Sheet_TestSuite_Name, 
						testCaseNo, Constant.Col_DateSource_SheetName);
			    //如果“TestSuite”Sheet中测试数据不为空,则运行数据驱动
				if(testData.trim().equals("无")) {
					Log.info("执行关键字驱动测试用例开始,Sheet表名为:"+testData);
					//testResult = true;
					//遍历测试步骤Sheet中的所在测试步骤
					for(; testStep < testLastStep; testStep++) {
						testStepRunFlag = ExcelUtil.getCellData(testCaseID, 
								testStep, Constant.Col_TestStep_RunFlag);
						if(testStepRunFlag.trim().equals("y")) {
						
							//从测试步骤的Sheet中读取关键字和操作值,并调用executeAction方法执行
					    	keyword = ExcelUtil.getCellData(testCaseID, 
					    			testStep, Constant.Col_KeyWordsAction);
					    	//在日志中打印关键字信息
					    	Log.info("从Excel文件读取到的关键字是: "+keyword);
					    	
					    	locatorExpression = ExcelUtil.getCellData(testCaseID,
					    			testStep, Constant.Col_LocatorExpression);
					    	//在日志中打印定位表达式信息
					    	Log.info("从Excel文件读取的表达式是: "+locatorExpression);
					    	
					    	value = ExcelUtil.getCellData(testCaseID, 
					    			testStep, Constant.Col_OperateVaule);
					    	//在日志中打印操作值信息
					    	Log.info("从Excel文件读取的操作值是: "+value);
					    	
					    	executeActions(testCaseID);
					    	
					    	if(testResult == false) {
					    		/*如果测试用例的任何一个测试步骤执行失败,则"TestSuite"Sheet中的当前
					    		 * 执行测试用例的执行结果设定为“测试执行失败”
					    		 */
					    		ExcelUtil.setCellData(Constant.Sheet_TestSuite_Name, 
					    				testCaseNo, Constant.Col_TestCase_TestResult, "测试执行失败");
					    		//在日志中打印测试用例执行完毕的信息
					    		Log.endTestCase(testCaseID);
					    		/*如果当前测试用例出现执行失败的情况,则将整个测试用例设定为失败状态,
					    		 * 利用break语句跳出当前的for循环,继续执行TestSuite中的下一个测试用例
					    		 */
					    		break;
					    	}
					    	if(testResult==true) {
					    		/*
					    		 * 如果测试用例的所有步骤执行成功,则将在“TestSuite”Sheet中的当前
					    		 * 执行测试用例的执行结果设定为“测试执行成功”
					    		 */
					    		ExcelUtil.setCellData(Constant.Sheet_TestSuite_Name, 
					    				testCaseNo, Constant.Col_TestCase_TestResult, "测试执行成功");
					    	}
						}
				    }
				}else {
					//读取“测试数据”Sheet中的测试数据总行
					int testDataCount = ExcelUtil.getRowCount(testData);
					//使用for循环,执行所有标记为“y”的测试数据
					for(int testDataNo = 1; testDataNo <= testDataCount; testDataNo++) {
						//读取测试数据(如“OrginalEmails”)Sheet中每行的“是否运行”列中的值
						testDataRunFlag = ExcelUtil.getCellData(testData, testDataNo, 
								Constant.Col_DataSource_RunFlag);
						//如果“是否运行”列中的值为“y”,则执行该测试数据
						if(testDataRunFlag.trim().equals("y")) {
							
							Log.info("开始数据驱动用例执行...");
							//testResult = true;
							//遍历测试用例中的所有测试步骤
							for(; testStep < testLastStep; testStep++) {
								testStepRunFlag = ExcelUtil.getCellData(testCaseID, 
										testStep, Constant.Col_TestStep_RunFlag);
								if(testStepRunFlag.trim().equals("y")) {
									//从测试步骤“ReadMail01”Sheet中读取关键字和操作值,并调用executeAction方法执行
									keyword = ExcelUtil.getCellData(testCaseID,
											testStep,Constant.Col_KeyWordsAction);
									//在日志文件中打印关键字信息
							    	Log.info("从Excel文件读取到的关键字是: "+keyword);
							    	
							    	locatorExpression = ExcelUtil.getCellData(testCaseID,
							    			testStep, Constant.Col_LocatorExpression);
							    	//在日志中打印表达式信息
							    	Log.info("从Excel文件读取的表达式是: "+locatorExpression);
							    	
							    	value = ExcelUtil.getCellData(testCaseID, 
							    			testStep, Constant.Col_OperateVaule);
							    	//在日志中打印操作值信息
							    	Log.info("从Excel文件读取的操作值是: "+value);
							    	
							    	value = value.trim();
							    	
							    	//若value值为“A-Z”,则替换为测试数据Sheet中的数据
							    	if(null!=value && value.length()==1 && TestSuiteByExcel.
							    			judgeContainsStr(value)) {
							    	
							    		
							    		//通过Excel文件中的列字母得到索引
							    		int conlumnNo = ExcelUtil.excelColStrToNum(value);
							    		value = ExcelUtil.getCellData(testData,testDataNo,conlumnNo);
							    		Log.info("Excel文件中列值为:"+value);						    								    		
							    	}
							    	//执行用例
							    	executeActions(testCaseID);
							    	if(testResult==true) {
							    		/*
							    		 * 如果当前测试步骤执行成功,在“测试数据”Sheet中,会将当前执行的
							    		 * 测试数据结果设定为“测试数据执行成功”
							    		 */
							    		ExcelUtil.setCellData(testData, testDataNo, 
							    				Constant.Col_DataSource_TestResult, "测试数据执行成功");
							    	}else {
							    		/*
							    		 * 当前测试步骤执行失败,在测试数据Sheet中,会将当前执行的测试数据
							    		 * 结果设定为“测试数据执行失败”
							    		 */
							    		ExcelUtil.setCellData(testData, testDataNo, 
							    				Constant.Col_DataSource_TestResult, "测试数据执行失败");
							    		//测试步骤执行失败,则直接关闭浏览器,不再执行后续的测试
							    		KeyWordsAction.close_browser("", "");
							    		break;
							    	}
								}
						    	
							}
							/*
							 * 在测试步骤Sheet中,获取当前要执行测试用例
							 * 的第一个步骤所在行的行号
							 */
							testStep = ExcelUtil.getFirstRowContainsTestCaseID(
									testCaseID, testCaseID, Constant.Col_TestCase_ID);
							if(testResult == false) {
								/*
								 * 如果测试用例的任何一个测试步骤执行失败,则将“TestSuite”测试用例集合
								 * Sheet中的当前执行测试用例的执行结果设定为“测试执行失败”
								 */
								ExcelUtil.setCellData(Constant.Sheet_TestSuite_Name, testCaseNo, 
										Constant.Col_TestCase_TestResult, "测试执行失败");
								//在日志中打印测试用例执行完毕的信息
								Log.endTestCase(testCaseID);
								/*
								 * 如果当前测试用例出现执行失败的步骤,则将整个测试用例设定为失败状态,
								 * break语句跳出当前的for循环,继续执行TestSuite中的下一个测试用例
								 */
								break;
							}
							if(testResult == true) {
								/*
								 * 如果当前测试用例的所有步骤执行成功,则将“TestSuite”Sheet中
								 * 的当前执行测试用例的执行结果设定为“测试执行成功”
								 */
								ExcelUtil.setCellData(Constant.Sheet_TestSuite_Name, testCaseNo,Constant.Col_TestCase_TestResult, "测试执行成功");
								
							}
						}
					}
				}
					
			}
		}
		
	}
	private static void executeActions(String testCaseID) {
		try {
			for(int i = 0;i<method.length;i++) {
				//使用反射的方式,找到关键字对应的测试方法,并将value(操作值)作为测试方法的函数值进行调用
				if(method[i].getName().equals(keyword)) {
					method[i].invoke(keyWordsaction,locatorExpression, value);					
					if(testResult == true) {
						/*
						 * 当前测试步骤执行成功,在所在Sheet中,会将当前执行的
						 * 测试步骤结果设定为“测试步骤执行成功”
						 */
						ExcelUtil.setCellData(testCaseID, 
								testStep, Constant.Col_TestStep_TestResult, "测试步骤执行成功");
						
					}else {
						/*
						 * 当前测试步骤执行失败,在所在Sheet中,会将当前执行的
						 * 测试步骤结果设定为“测试步骤执行失败”
						 */
						ExcelUtil.setCellData(testCaseID,
								testStep, Constant.Col_TestStep_TestResult, "测试步骤执行失败");
						//测试步骤执行失败,则直接关闭浏览器,不再执行后续的测试
						KeyWordsAction.close_browser("","");
						break;
					}					
				}
			}
		}catch(Exception e) {
			//在调用测试方法的过程中,若出现异常,则将测试设定为失败状态,停止执行测试用例
			Log.info("执行出现异常,测试用例执行失败!");
			Assert.fail("执行出现异常,测试用例执行失败!");
		}
	}
	//判断str是否是A~Z之间的字符串
	private static boolean judgeContainsStr(String str) {
		String regex = ".*[A-Z]+.*";
		Matcher matcher = Pattern.compile(regex).matcher(str);
		return matcher.matches();
	}

	@BeforeClass
	public void BeforeClass() {	
		//设定Log4j的配置文件为“log4j.xml"
		DOMConfigurator.configure("log4j.xml");
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Summer@123

不积跬步无以至千里,感谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值