准备:
- java环境
- 下载与浏览器版本符合的Driver
- eclipse
- excel
准备好了就可以开干了
- 先建一个maven工程
在pom.xml引入我们所需要的一系列框架:
selenium+testNG+poi
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.2</version>
<scope>test</scope>
</dependency>
<!-- POI EXCEL 文件读写 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-excelant</artifactId>
<version>3.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.14.0</version>
</dependency>
还是先来看看excel用例吧
用例一般包括:标题、前置条件、测试步骤、测试数据、预期结果、实际结果
这次实现用例模板如下:
image.png
excel表中第一页作为公共用例(多次会用到的前置条件),第二页作为普通用例。
每一条用例与用例之间以一行空行作为标识
这里建了两个model一个casemodel、一个stepmodel
public class CaseModel {
String caseName;
List<StepModel> stepModels;
public List<StepModel> getStepModels() {
return stepModels;
}
public void setStepModels(List<StepModel> stepModels) {
this.stepModels = stepModels;
}
public String getCaseName() {
return caseName;
}
public void setCaseName(String caseName) {
this.caseName = caseName;
}
}
public class StepModel {
String step;
String Element;
String precondition;
String type;
String action;
String value;
String expect;
String object;
public String getObject() {
return object;
}
public String getPrecondition() {
return precondition;
}
public void setPrecondition(String precondition) {
this.precondition = precondition;
}
public void setObject(String object) {
this.object = object;
}
public String getExpect() {
return expect;
}
public void setExpect(String expect) {
this.expect = expect;
}
public String getStep() {
return step;
}
public void setStep(String step) {
this.step = step;
}
public String getElement() {
return Element;
}
public void setElement(String element) {
Element = element;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "StepModel [step=" + step + ", Element=" + Element + ", type=" + type + ", action=" + action +"\n"+ ", value="
+ value + ", expect=" + expect + ", object=" + object + "]"+"\n";
}
}
下面是获取excel表中的数据,并创建一个case的list返回(caseType创建的一个枚举,根据这个来决定获取excel中那一页的数据)
@SuppressWarnings("resource")
public static List<CaseModel> getCaseList(String path, CaseType caseType) {
String fileType = path.substring(path.lastIndexOf(".") + 1);
List<CaseModel> caseModels = new ArrayList<CaseModel>();
// 读取excel文件
InputStream is = null;
try {
is = new FileInputStream(path);
// 获取工作薄
Workbook wb = null;
if (fileType.equals("xls")) {
wb = new HSSFWorkbook(is);
} else if (fileType.equals("xlsx")) {
wb = new XSSFWorkbook(is);
} else {
return null;
}
CaseModel caseModel = new CaseModel();
// 设定第一页未公共用例,第二页未普通用例
int sheetIndex = 0;
switch (caseType) {
case publicCase:
sheetIndex = 0;
break;
case ordinaryCase:
sheetIndex = 1;
default:
break;
}
Sheet sheet = wb.getSheetAt(sheetIndex);
// 获取行数;因已空行作为记号所以+1
int lastRow = sheet.getLastRowNum() + 1;
// 获取列数
int lastcell = sheet.getRow(0).getLastCellNum();
// System.out.println(lastRow);
for (int i = 0; i <= lastRow; i++) {
Row row = sheet.getRow(i);
if (i == 0) {
// 第一行是标题
continue;
}
if (row == null) {
// 到了空行,list添加case,并初始化casemodel
caseModels.add(caseModel);
caseModel = new CaseModel();
continue;
}
StepModel stepModel = new StepModel();
for (int j = 0; j < lastcell; j++) {
String valueStr = "";
Cell cell = row.getCell(j);
if (cell == null) {
valueStr = null;
} else {
// 将cell中的内容转化为字符串
cell.setCellType(Cell.CELL_TYPE_STRING);
valueStr = cell.getStringCellValue();
// System.out.println(valueStr);
}
// 根据cellIndex添加对应的参数
switch (j) {
case 0:
if (valueStr != null) {
// System.out.println("到了这里:");
// System.out.println(valueStr);
if (valueStr.length() > 0) {
caseModel.setCaseName(valueStr);
}
}
break;
case 1:
stepModel.setPrecondition(valueStr);
break;
case 2:
stepModel.setStep(valueStr);
break;
case 3:
stepModel.setElement(valueStr);
break;
case 4:
stepModel.setType(valueStr);
break;
case 5:
stepModel.setObject(valueStr);
break;
case 6:
stepModel.setAction(valueStr);
break;
case 7:
stepModel.setValue(valueStr);
break;
case 8:
stepModel.setExpect(valueStr);
default:
break;
}
}
caseModel.stepModels.add(stepModel);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return caseModels;
}
到这里实现了将excel变成了我们想要的数据形式
接下来,将获取到的数据翻译,告诉代码应该去做什么
用例表中有一个元素、方式字段是用来定位元素的信息
于是就有了下面的方法
public static WebElement getWebElement(String type, String element) {
WebElement webElement = null;
WebDriverWait wait = new WebDriverWait(Driver.getChromeDriver(), 10);
if (type.equals("XPath")) {
webElement = Driver.getChromeDriver().findElementByXPath(element);
} else if (type.equals("ClassName")) {
webElement = Driver.getChromeDriver().findElementByClassName(element);
} else if (type.equals("CssSelector")) {
webElement = Driver.getChromeDriver().findElementByCssSelector(element);
} else if (type.equals("TagName")) {
webElement = Driver.getChromeDriver().findElementByTagName(element);
} else if (type.equals("PartialLinkText")) {
webElement = Driver.getChromeDriver().findElementByPartialLinkText(element);
} else if (type.equals("Name")) {
webElement = Driver.getChromeDriver().findElementByName(element);
} else if (type.equals("LinkText")) {
webElement = Driver.getChromeDriver().findElementByLinkText(element);
} else if (type.equals("Id")) {
webElement = Driver.getChromeDriver().findElementById(element);
} else {
try {
// System.out.println(type);
System.err.println("寻找元素方法除了问题type:"+type+" element: "+element);
throw new RemoteException();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//等待元素出现
wait.until(ExpectedConditions.visibilityOf(webElement));
return webElement;
}
还有三个字段是对象、动作和参数(测试数据)
如果对象为element那么执行的动作对象为element:则执行下面的方法
public static String ElementAction(StepModel step) {
WebDriverWait wait = new WebDriverWait(Driver.getChromeDriver(), 10);
String action = step.getAction();
String element = step.getElement();
String type = step.getType();
if (action.equals("click")) {
getWebElement(type, element).click();
} else if (action.equals("sendkeys")) {
String value = step.getValue() == null ? "" : step.getValue();
getWebElement(type, element).clear();
getWebElement(type, element).sendKeys("a");
getWebElement(type, element).sendKeys(Keys.BACK_SPACE);
getWebElement(type, element).sendKeys(value);
} else if (action.equals("submit")) {
getWebElement(type, element).submit();
} else if (action.equals("gettext")) {
String actual = getWebElement(type, element).getText();
//目前默认gettext方法时为校验阶段;需改
assertEquals(step.expect, actual);
} else if (action.equals("movetoelement")) {
Actions actions = new Actions(Driver.getChromeDriver());
actions.moveToElement(getWebElement(type, element)).perform();
}else if (action.equals("movetoelementclick")) {
Actions actions = new Actions(Driver.getChromeDriver());
actions.moveToElement(getWebElement(type, element)).build().perform();
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// System.out.println("在这里输出了状态:"+wait.until(ExpectedConditions.cl));
// wait.until(ExpectedConditions.elementToBeClickable(getWebElement(type, element)));
actions.click(getWebElement(type, element)).perform();
}
return type;//目前没有用,预留返回字段
}
如果对象为driver,则执行以下方法
public static void get(String url) {
getChromeDriver().get(url);
}
public static void refresh() {
getChromeDriver().navigate().refresh();
}
public static void action(StepModel step) {
String action = step.getAction();
if (action.equals("get")) {
get(step.getElement());
}else if (action.equals("refresh")) {
refresh();
}else {
System.err.println("不是写错了,就是还没写");
}
}
理论上可对以上两个动作方法,根据所需扩充完善所需要的动作
漏了个东西关于webdriver
这里做了一个获取driver的单例
并为它加了锁(防止线程安全问题)
static ChromeDriver chromeDriver;
public static synchronized ChromeDriver getChromeDriver() {
if (null==chromeDriver) {
System.setProperty("webdriver.chrome.driver", "D:\\TEST\\chromedriver.exe");
chromeDriver = new ChromeDriver();
chromeDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
// System.out.println("初始化");
}
return chromeDriver;
}
最最最后就是执行用例了
理论上应重写testng相关方法(根据获取到的excel表自动生成相应Test)
先走出第一步吧
public class NewTest {
static List<CaseModel> publicCaseList;
@Test(dataProvider = "dp")
public void f(CaseModel caseModel) {
System.out.println("执行了用例" + caseModel);
doCase(caseModel);
}
@AfterClass
public void AfterClass() {
Driver.getChromeDriver().quit();
}
@BeforeClass
public void BeforeClass() {
//获取公共用例
publicCaseList = CaseModel.getCaseList("C:\\Users\\Administrator\\Desktop\\3.xlsx", CaseType.publicCase);
}
@DataProvider
public Object[] dp() {
//获取用例
List<CaseModel> caseModels = CaseModel.getCaseList("C:\\Users\\Administrator\\Desktop\\3.xlsx",
CaseType.ordinaryCase);
int size = caseModels.size();
Object[] objects = new Object[size];
for (int i = 0; i < objects.length; i++) {
objects[i] = caseModels.get(i);
}
//System.out.println(objects.length + " " + size);
return objects;
}
//根据casel模型执行用例
public void doCase(CaseModel caseModel) {
for (int i = 0; i < caseModel.stepModels.size(); i++) {
StepModel stepModel = caseModel.stepModels.get(i);
String object = stepModel.getObject();
if (stepModel.precondition != null) {
//执行前置条件
for (CaseModel caseModel2 : publicCaseList) {
if (stepModel.precondition.equals(caseModel2.caseName)) {
//根据casename查找到说要执行的公共用例
doCase(caseModel2);
break;
}
}
}
if (object.equals("driver")) {
Driver.action(stepModel);
} else {
//懒得写elseif。这里假装判断了是element
WebElementZ.ElementAction(stepModel);
}
}
}
}
待完善
- 根据获取到的excel表自动生成相应Test
- 增加配置项(如:可选择浏览器、配置浏览器选项等)
- 完善动作方法(这理论上是个无底洞)
总结一下三点
...
网友评论