在识别和实现动作关键字这篇文章,你一定注意到了,我每个元素操作都写了一个动作关键字的静态方法。这确实是一个很不好的设计,试着想一下,如果我实际项目中,有很多网页元素要操作,那么是不是要写成千上万的动作关键字呢?很显然,我们潜意识里就好对元素对象操作进行分类,例如点击元素,我们就封装一个点击方法,不用在意点击的元素是什么。元素文本框输入也封装一个元素输入方法,这样我们基本上一个点击和一个输入动作关键字就实现了很多页面基本操作。利用面向对象思想,首先我有一个登陆元素,叫login_link,然后这个操作叫点击,写一个点击方法click(),整个元素操作场景就变成了:login_link.click().
所以,接下里的任务就是如何把动作场景中的对象给分离出来。为了实现这个,我们需要使用对象仓库,什么是对象仓库呢,实际上就是把所有对象和对象的属性全部放到一个文件里面,在webdriver自动化中,driver需要去获取不同页面对象的定位方式,从而去定位页面元素。这个场景,我们很容易使用property 文件来实现。通常的,在Java中,properties文件用来保存一些项目的配置数据和设置参数。在这篇文章,我们就学会如何建立对象仓库文件并使用这个文件。
步骤1:场景对象仓库文件
1. 在config包下新建一个文件,名称叫OR.txt
2. 把之前我们定义的动作关键字和元素对象写入到配置文件,就是键值对的形式
3. 这里我们主要写页面元素对象和元素的定位表达式,这里我们暂时都采用元素的xpath表达式来定位元素。
最后你的OR.txt内容大致如下:
# home page
loginLink=.//*[@id='u1']/a[7]
# login page
loginTypeByAccount=.//*[@id='TANGRAM__PSP_10__footerULoginBtn']
loginUsernameInputbox=.//*[@id='TANGRAM__PSP_10__userName']
loginPasswordInputbox=.//*[@id='TANGRAM__PSP_10__password']
loginSubmitBtn=.//*[@id='TANGRAM__PSP_10__submit']
步骤2:在DriverScript.java中加载OR文件
打开DriverScript.java,在Main方法中添加加载OR文件的代码,添加后效果如下。
package executionEngine;
import com.sun.xml.internal.bind.v2.runtime.reflect.opt.Const;
import config.ActionsKeywords;
import config.Constants;
import utility.ExcelUtils;
import java.io.FileInputStream;
import java.lang.reflect.Method;
import java.util.Properties;
/**
* create by Anthony on 2018/1/30
*/
public class DriverScript {
// 声明一个public static的类对象,所以我们可以在main方法范围之外去使用。
public static ActionsKeywords actionsKeywords;
public static String sActionKeyword;
// 下面是返回类型是方法,这里用到反射类
public static Method method[];
// 新建一个Properties对象
public static Properties OR;
public static String sPageObject;
// 这里我们初始化'ActionsKeywords'类的一个对象
public DriverScript() throws NoSuchMethodException, SecurityException{
actionsKeywords = new ActionsKeywords();
method = actionsKeywords.getClass().getMethods();
}
public static void main(String[] args) throws Exception {
// 初始化一下DriverScript类
DriverScript ds = new DriverScript();
String excel_path = Constants.Path_TestData;
// 申明一个对象仓库文件字符串的对象
String Path_OR = Constants.OR_Path;
// 创建一个文件输入流对象
FileInputStream fs = new FileInputStream(Path_OR);
// 创建一个Properties对象
OR = new Properties(System.getProperties());
// 加载全部对象仓库文件
OR.load(fs);
// 加载读取excel文件
ExcelUtils.setExcelFile(excel_path, Constants.Sheet_TestSteps);
for (int iRow = 1; iRow <= 9; iRow++) {
//3表示excel中keyword对应的列的索引,也就是左边数起第4列
sActionKeyword = ExcelUtils.getCellData(iRow, Constants.Col_ActionKeyword);
// 获取对应excel页面对象的名称,返回是一个string对象
sPageObject = ExcelUtils.getCellData(iRow, Constants.Col_PageObject);
//调用'execute_Actions'方法
execute_Actions();
}
}
private static void execute_Actions() throws Exception {
//循环遍历每一个关键字驱动方法(在actionskeywords.java中)
//method variable contain all the method and method.length returns the total number of methods
// 下面methid.length表示方法个数,method变量表示任何一个关键字方法,例如openBrowser()
for(int i = 0;i < method.length;i++){
//开始对比代码中关键字方法名称和excel中关键字这列值是否匹配
if(method[i].getName().equals(sActionKeyword)){
//一点匹配到关键字,并传递页面对象参数和动作关键字参数
method[i].invoke(actionsKeywords,sPageObject);
//一旦任何关键字被执行,利用break语句去跳出for循环。
break;
}
}
}
}
红色字体代码是本篇新加的内容, 上面代码中的span请忽略,本来想添加红色字体突出显示,但是发布之后效果就是很多html样式带上去。步骤3:Constants.java内容修改后如下
package config;
public class Constants {
// 这里定义为public static的类型,方便其他任何类进行访问和调用
public static final String URL = "https://www.baidu.com";
public static final String Path_TestData = ".//src//dataEngine//dataEngine.xlsx";
public static final String File_TestData = "dataEngine.xlsx";
// dataEngine.xlsx中一些单元格的索引值
public static final int Col_TestCaseID = 0;
public static final int Col_TestScenarioID =1;
public static final int Col_PageObject =3 ;
public static final int Col_ActionKeyword =4 ;
// DataEngmine.excel中sheet的名称
public static final String Sheet_TestSteps = "Test Steps";
// OR(对象仓库)文件路径
public static final String OR_Path =".//src//config/OR.txt";
// 测试登录用到的用户数据
public static final String UserName = "xxxxxx";
public static final String Password = "xxxxxxx";
}
上面添加三行代码,数字3和数字4表示excel列的索引,一个表示Page Object列和Action_Keyword列。Page Object列在下面步骤4中介绍。步骤4:修改dataEngine.xlsx文件,分类对象出来
1. 打开dataEngine.xlsx文件,在Action_Keyword列左侧新插入一列
2. 新插入列字段名称叫 Page Obeject
3. 在Page Object列对应单元格添加元素对象名称
4. 从之前的Action_keyword列中去除对象,保留动作关键字
修改之后的excel内容大致如下:
步骤5:修改ActionsKeywords.java类文件
1. 封装一个click()方法(本篇实现的功能)
2. 封装一个input()方法(具体功能本篇运行会出错)
修改之后的ActionsKeywords.java内容如下
package config;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static executionEngine.DriverScript.OR;
import java.util.concurrent.TimeUnit;
public class ActionsKeywords {
public static WebDriver driver;
/*
封装一个click()方法和input()方法,重点是click()的实现过程
这里提一下openUrl和openBrowser方法中为什么也要传入string参数,但是代码没有用到这个参数
这个主要是我们在excel对应单元格不填写,那么获取的string对象就是null,所以这里参数String object不会影响方法执行
*/
public static void openBrowser(String object) {
// 这里,我们暂时都写死用chrome来进行自动化测试
System.setProperty("webdriver.chrome.driver",".\\libs\\chromedriver.exe");
driver = new ChromeDriver();
}
public static void openUrl(String object) {
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.get(Constants.URL);
}
public static void click(String object) {
driver.findElement(By.xpath(OR.getProperty(object))).click();
}
public static void input(String object) {
driver.findElement(By.id(OR.getProperty(object))).sendKeys(Constants.UserName);
}
public static void waitFor() throws Exception{
Thread.sleep(3000);
}
// 关闭浏览器并退出
public static void closeBrowser() {
driver.quit();
}
}
当前项目结构图如下
以上如何你运行DriverSript.java里面的main方法,发现运行到输入用户名地方就报错,这个问题,由于我们封装input()方法不够准确造成,关于输入部分,我们后面章节介绍数据驱动来解决这个问题。