準備:
- java環(huán)境
- 下載與瀏覽器版本符合的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用例吧
用例一般包括:標題纹烹、前置條件邑蒋、測試步驟鞠眉、測試數(shù)據(jù)遗契、預期結果片酝、實際結果
這次實現(xiàn)用例模板如下:
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表中的數(shù)據(jù),并創(chuàng)建一個case的list返回(caseType創(chuàng)建的一個枚舉绘闷,根據(jù)這個來決定獲取excel中那一頁的數(shù)據(jù))
@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);
// 獲取行數(shù)较坛;因已空行作為記號所以+1
int lastRow = sheet.getLastRowNum() + 1;
// 獲取列數(shù)
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);
}
// 根據(jù)cellIndex添加對應的參數(shù)
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;
}
到這里實現(xiàn)了將excel變成了我們想要的數(shù)據(jù)形式
接下來丑勤,將獲取到的數(shù)據(jù)翻譯,告訴代碼應該去做什么
用例表中有一個元素吧趣、方式字段是用來定位元素的信息
于是就有了下面的方法
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();
}
}
//等待元素出現(xiàn)
wait.until(ExpectedConditions.visibilityOf(webElement));
return webElement;
}
還有三個字段是對象法竞、動作和參數(shù)(測試數(shù)據(jù))
如果對象為element那么執(zhí)行的動作對象為element:則執(zhí)行下面的方法
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("在這里輸出了狀態(tài):"+wait.until(ExpectedConditions.cl));
// wait.until(ExpectedConditions.elementToBeClickable(getWebElement(type, element)));
actions.click(getWebElement(type, element)).perform();
}
return type;//目前沒有用强挫,預留返回字段
}
如果對象為driver岔霸,則執(zhí)行以下方法
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("不是寫錯了,就是還沒寫");
}
}
理論上可對以上兩個動作方法俯渤,根據(jù)所需擴充完善所需要的動作
漏了個東西關于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;
}
最最最后就是執(zhí)行用例了
理論上應重寫testng相關方法(根據(jù)獲取到的excel表自動生成相應Test)
先走出第一步吧
public class NewTest {
static List<CaseModel> publicCaseList;
@Test(dataProvider = "dp")
public void f(CaseModel caseModel) {
System.out.println("執(zhí)行了用例" + 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;
}
//根據(jù)casel模型執(zhí)行用例
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) {
//執(zhí)行前置條件
for (CaseModel caseModel2 : publicCaseList) {
if (stepModel.precondition.equals(caseModel2.caseName)) {
//根據(jù)casename查找到說要執(zhí)行的公共用例
doCase(caseModel2);
break;
}
}
}
if (object.equals("driver")) {
Driver.action(stepModel);
} else {
//懶得寫elseif呆细。這里假裝判斷了是element
WebElementZ.ElementAction(stepModel);
}
}
}
}
待完善
- 根據(jù)獲取到的excel表自動生成相應Test
- 增加配置項(如:可選擇瀏覽器、配置瀏覽器選項等)
- 完善動作方法(這理論上是個無底洞)
總結一下三點
...