关键子驱动的框架:关键字驱动框架- 它更多是作为一个开发或者测试开发人员,开发的一个框架或者工具,目的是让不懂代码的黑盒测试人员去快速编写测试脚本。
一:关键字驱动框架介绍
二:搭建关键字驱动框架的步骤
三:识别并设计实现动作关键字
四:搭建数据引擎-用Apache POI去读取数据
五: 用Java反射机制优化
七:对象仓库
八:测试套件执行引擎
一: 什么是关键字驱动框架?
关键字驱动框架(Keyword Driven Framework)是功能自动化测试框架的一种,有时候也叫表格驱动测试(Table-Driver)或者基于动作词语框架(Action Word based)。
基本的实现原理是:在关键字驱动框架中,把测试用例分为4部分:
测试步骤,测试对象,动作,测试数据。上面的4部分,我们可以借助excel来进行组织和管理。
测试步骤:是一个很小的测试步骤的描述,例如点击按钮。
测试对象:一般是web系统上页面上的元素,例如用户名输入框,登录按钮。
动作:例如,点击,输入,打开浏览器
测试数据:用来给测试对象赋值的数据,例如手机号码和邮箱字段。
关键字驱动的背后思想,就是把一个代码编写的自动化测试用例场景拆分成多个很小的测试步骤,特别是给那些不懂代码或者不熟悉写自动化测试的手工测试人员提供了一种方式,去实现自动化测试。手工测试人员,不需要关注内部代码如何实现,他们只需要在数据表,例如execel中按照规则去填写测试数据,就可以实现测试场景的自动化。
我们来举例来介绍这种思想,下面举例登录服务器的场景。下面的测试步骤,不管是自动化还是手工,基本上都是这么去划分。
1. 打开浏览器
2. 输入测试服务器地址
3. 点击登录链接
4. 输入用户名
5. 输入密码
6. 点击登录按钮
7. 点击登出链接
8. 关闭浏览器,退出测试
上面的步骤,用关键字驱动的思想来实现,就是这么去做的:
Excel Sheet: 是我们存放测试用例(Test Case)、测试步骤(Test Step)、测试对象(Test Object)和操作动作(Action),测试对象在执行操作时所需要的数据值的关键字驱动数据表。
对象仓库 Object Repository: 是个属性文件,用来存放HTML应用中的一些元素属性,用一个xml文件或者excel文件,或者一个text格式的文件,本项目采用OR.txt文件,里面把一个软件项目的页面所有需要用到的元素对象的表达式都写到同一个文件,这个文件就叫对象仓库。
关键字方法库 Keyword Function Library: 这是一个方法库文件,定义或者叫封装一些操作方法,供其他地方调用,这些方法尽量都使用一些简单的词汇去描述操作动作,例如点击,输入。它主要存放执行的Action,每一个操作动作都可以从这个文件中调用。
执行引擎 ExecutionEngine: 是唯一的测试脚本,它通过关键字框架从Excel表格、方法库、属性文件中进行推动测试。
整个过程可以用下面这张图来表示,或者说关键字驱动框架的原理就如下图。
关键字驱动框架的优点:
1. 技术门槛低:一旦开发人员设计好了框架,手工测试人员或者没有相关脚本,代码经验的人员都可以按照模板写自动化测试脚本。
2. 容易理解:基本上都是在维护excel表,没有在写代码,所以测试脚本容易读和理解。而且看到那些关键字方法,就很容易想起手动测试场景。
3. 容易上手:和前面两个优点差不多意思,主要是不需要代码知识也能写测试脚本
4. 组件重用:支持模块化复用,具有一定的扩展性。
5. 代码复用:其实调用关键字方法就是在复用代码。包括执行引擎一个用例一个用例执行下去也是在复用代码。
不需要太多的技术:一旦框架建立,手工测试人员和非技术人员都可以很容易的编写自动化测试脚本。
简单易懂:它存在Excel表格中,没有编码,测试脚本容易阅读和理解。关键字和操作行为这样的手工测试用例,使它变得更容易编写和维护。
早期介入:可以在应用未提交测试之前,就可以建立关键字驱动测试用例对象库,从而减少后期工作。使用需求和其它相关文档进行收集信息,关键字数据表可以建立手工测试程序。
组件的重用性:实施关键字驱动的模块化,进一步提高可重用性。
代码的重用性:作为关键字驱动框架中,只有一个执行引擎,它是鼓励极端的代码的复用。
限制和缺点:它没有用代码写自动化测试用例效率高方便和高复用性。
二: 搭建关键字驱动框架的步骤
我把这个过程分成12个步骤:
1.自动化实现一个端对端的流程
2.区分和实现动作关键字
3.设置数据引擎-Excel 表
4.实现java反射类
5.设置Java常量,一些固定数据
6.设置元素对象仓库文件 OR.txt
7.设置测试套件执行引擎
8.设置日志输出模块,例如log4j
9.设置框架中异常处理
10.设置测试结果报告输出
11.设置数据驱动
12.完成框架,交付给手工测试人员
下面我们来介绍如何实现第一个步骤:自动化实现一个端对端的流程
什么是端对端流程呢,这里举例一个电商网站场景,你就明白什么是端对端:
1.登录系统
2.选择商品
3.添加商品到购物车
4.检查支付页面
5.完成支付过程
6.支付完成后检查订单页面
这就是一个用户和网站交互的过程,用户是一段,服务器是另外一端。
Eclipse+ Jave + Selenium:
1) 新建一个SeleniumKeywordDriverFramework的java工程
2) 在src下,点击右键,新建包,包名称为executionEngine
3) 在包executionEngine下新建一个class文件,名称为DriverScript
我的IDEA上项目结构如下图
文件DriverScript.java内容如下,我这里就是百度登录举例,上面步骤是电商网站下单,这个脚本不重要,能模拟点击和输入就行。
package executionEngine;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
public class DriverScript {
private static WebDriver driver = null;
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver",".\\libs\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);
driver.get("https://www.baidu.com");
Thread.sleep(2000);
// 点击登录链接
driver.findElement(By.xpath(".//*[@id='u1']/a[text()='登录']")).click();
// 点击账号密码登录
driver.findElement(By.id("TANGRAM__PSP_10__footerULoginBtn")).click();
driver.findElement(By.id("TANGRAM__PSP_10__userName")).sendKeys("xxxxx");
driver.findElement(By.id("TANGRAM__PSP_10__password")).sendKeys("xxxxx");
driver.findElement(By.id("TANGRAM__PSP_10__submit")).click();
}
}
三,识别并设计实现动作关键字
单独创建一个类来管理这些动作关键字,这样,测试脚本就很容易去调用关键字相关方法
动作关键字就是,利用一个简短的单词(词语)来描述这个动作场景。Action_Keyword:动作的描述关键字,例如openBrowser
识别动作关键字
1)在Eclipse上,当前项目下新建一个包,包名称为dataEngine
2)在dataEngine包下,右键选择新建文件,文件名称为dataEngine.xlsx
3)打开dataEngine.xlsx文件,把sheet1重命名为TestSteps,保存excel文件。
4)在Test Steps中创建以下列字段。
-- TestCase ID: 例如tc_001,auto_001等
-- TestScenario ID:测试场景id,例如TS_001,TS_002等
-- Description: 描述,例如打开浏览器
-- Action_Keyword:动作的描述关键字,例如openBrowser
这里解释一下测试场景ID和测试用例ID的区别,测试用例,例如登录这个功能,在登录功能下有很多测试场景,例如正确用户名和错误密码登录,错误用户名和正确密码登录,这样的就是测试场景,所以上面就给了测试场景ID和测试用例ID区分出来。
在关键字命名这块,建议尽量取一些,有逻辑和有实际意义的单词,让别人一看就明白是描述一个什么的动作场景。例如,打开测试服务器地址,关键字可以写openUrl;在输入框输入文字,可以用type或者sendKeys这样很容易理解的单词组合。
你的dataEngine.xlsx的内容大概是这个样子的。
实现动作关键字
1) 新建一个包,包的名称是config
2) 在config包下新建一个class文件,命名ActionsKeywords
3) 在ActionsKeywords类中创建多个静态方法来实现我们excel中写的这些action_keyword
项目层次结构图如下
上面这个java类文件具体代码如下:
package config;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
public class ActionsKeywords {
public static WebDriver driver;
* 以下方法,我们针对dataEngine.xlsx文件中的action_keyword这列的关键字都进行封装
* 等关键字框架快设计完了,我们再来调整,读取配置文件去启动不同测试浏览器和测试地址
* 这样就不会代码写死这两个参数。
*/
public static void openBrowser() {
// 这里,我们暂时都写死用chrome来进行自动化测试
System.setProperty("webdriver.chrome.driver",".\\libs\\chromedriver.exe");
driver = new ChromeDriver();
}
public static void openUrl() {
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.get("https://www.baidu.com");
}
public static void click_Login_link() {
driver.findElement(By.xpath(".//*[@id='u1']/a[text()='登录']")).click();
driver.findElement(By.id("TANGRAM__PSP_10__footerULoginBtn")).click();
}
public static void input_Username() {
driver.findElement(By.id("TANGRAM__PSP_10__userName")).sendKeys("xxxxx");
}
public static void input_Password() {
driver.findElement(By.id("TANGRAM__PSP_10__password")).sendKeys("xxxxx");
}
public static void click_Submit() {
driver.findElement(By.id("TANGRAM__PSP_10__submit")).click();
}
// 关闭浏览器并退出
public static void closeBrowser() {
driver.quit();
}
}
四:搭建数据引擎-用Apache POI去读取数据
在Selenium自动化测试脚本中需要识别Excel中的关键字和数据,所以需要利用Java去读取excel的数据
使用开源jar包工具— Apache POI来读取Excel文件数据。
搭建Data Engine—利用Apache POI
我们需要一种方式去打开Excel和读取里面的数据,并且拿到Selenium自动化测试脚本中。为了实现这个场景,我这里使用Apache POI 类库,Apache POI是一个允许你使用Java去读取和创建和编辑微软的Excel文件格式的一种强大的工具包。我们下面要用到相关类或者方法去读取Excel数据,这些类或者方法是放在‘org.apache.poi.hssf.usermodel’包下。
从Excel中读取数据
1)下载Apache POIjar包文件,并添加到项目的lib类库.点击这里下载。
2)下载后解压,我们把poi-3.17.jar等添加到项目类库
这些包需要添加到项目的librarys中去。
3)新建一个包,名称为utility。
4)在utility包下,新建一个类文件,名称为ExcelUtils.java
项目代码结构如下图
5)在ExcelUtils.java,输入以下内容
package utility;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
public class ExcelUtils {
private static XSSFSheet ExcelWSheet;
private static XSSFWorkbook ExcelWBook;
private static XSSFCell Cell;
// 设置Excel文件路径,方便读取到文件
public static void setExcelFile(String Path, String SheetName) throws IOException {
FileInputStream ExcelFile = new FileInputStream(Path);
ExcelWBook = new XSSFWorkbook(ExcelFile);
ExcelWSheet = ExcelWBook.getSheet(SheetName);
}
// 读取Excel文件单元格数据
public static String getCellData(int RowNum, int ColNum) throws Exception{
Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);
String CellData = Cell.getStringCellValue();
return CellData;
}
}
下面,我们来修改DriverScript.java文件里面的内容,利用上面写的ExcelUtils类文件,我们在一个一个来读取进行测试。
package executionEngine;
import config.ActionsKeywords;
import utility.ExcelUtils;
public class DriverScript {
public static void main(String[] args) throws Exception {
String excel_path = "C:\\Users\\ydbj0140\\IdeaProjects\\SeleniumKeywordFramework\\src\\dataEngine\\dataEngine.xlsx";
// 加载读取excel文件
ExcelUtils.setExcelFile(excel_path, "Test Steps");
for (int iRow=1;iRow<=9;iRow++){
String sActionKeyword = ExcelUtils.getCellData(iRow, 3);
// 和excel文件中关键字进行对比
if(sActionKeyword.equals("openBrowser")){
// 如果Excel文件中存在openBrowser的关键字就会调用openBrowser()方法,进行相关操作;下面其他关键字同理。
ActionsKeywords.openBrowser();
} else if(sActionKeyword.equals("openUrl")){
ActionsKeywords.openUrl();
} else if(sActionKeyword.equals("click_Login_link")){
ActionsKeywords.click_Login_link();
} else if(sActionKeyword.equals("input_Username")){
ActionsKeywords.input_Username();
} else if(sActionKeyword.equals("input_Password")){
ActionsKeywords.input_Password();
} else if(sActionKeyword.equals("click_Submit")){
ActionsKeywords.click_Submit();
} else if(sActionKeyword.equals("closeBrowser")){
ActionsKeywords.closeBrowser();
}
}
}
}
测试结果:通过,可以看到登录百度的效果(这里登录后提示输入验证码不是本系列解决的重点,这个问题不用管)。
到这里,我们已经实现了一个关键字驱动框架的骨架部分,关键字驱动框架的重点思路就是如何从Excel文件中读取和判断关键字,所以,所有的测试用例都可以写入到Excel文件。但是目前这个框架就是一个草稿,接下来我们要去给这个框架增加一点东西,变得丰满一点。
五:使用Java反射机制
在前面几篇文章,我们发现了,如果要运行任何操作,我们需要利用Apache POI去Excel关键字这列拿数据并和代码中相关静态方法去匹配。到目前,我们就写了6个关键字动作,结果在if-else-if-else中我们需要写好多个判断分支,试想一下,如果按照这个思路,一个项目的自动化,有几百个测试用例,其中一个测试用例有好几个测试场景,那么我们的动作关键字驱动会写几千甚至上万个,难道也需要写上万个if判断吗?这样显然不合理,效率太低,代码可维护太差。
使用Java反射类: 在Java中利用反射类是可以解决上面提到的问题。反射是一种非常有用的方法,可以在运行时处理Java类,因此它可以用来装载Java类、调用它的方法或者在运行时分析类。
反射的作用场景就是:当你添加了新的关键字方法代码,反射类会在运行时间加载所有的方式或者动作关键字的类。
ActionsKeywords.java代码不变和前面文章保持一致。调用selenium的driverScript.java的代码我们修改如下
package executionEngine;
import config.ActionsKeywords;
import utility.ExcelUtils;
import java.lang.reflect.Method;
public class DriverScript {
// 声明一个public static的类对象,所以我们可以在main方法范围之外去使用。
public static ActionsKeywords actionKeywords;
public static String sActionKeyword;
// 下面是返回类型是方法,这里用到反射类
public static Method method[];
// 这里我们初始化'ActionsKeywords'类的一个对象
public DriverScript() throws NoSuchMethodException, SecurityException, ClassNotFoundException {
//actionKeywords = new ActionsKeywords()
// 原文作者是采用上面这个代码,下面的代码是我查找反射资料,是这么获取class对象的
Class> actionKeywords = Class.forName("config.ActionsKeywords");
method = actionKeywords.getMethods();
}
public static void main(String[] args) throws Exception {
// 由于上面初始化反射类写在构造函数,而main方法是第一个被最新,如果不添加
// 下面这个当前类的初始化代码,就会报method.length空指针异常,我这里暂时这里处理
// 原文作者不知道为啥没有报错。
DriverScript ds = new DriverScript();
String excel_path = "C:\\Users\\Administrator\\Desktop\\SeleniumKeywordDriverFramework\\src\\dataEngine\\dataEngine.xlsx";
// 加载读取excel文件
ExcelUtils.setExcelFile(excel_path, "Test Steps");
for (int iRow = 1; iRow <= 6; iRow++) {
//3表示excel中keyword对应的列的索引,也就是左边数起第4列
sActionKeyword = ExcelUtils.getCellData(iRow, 3);
//调用'execute_Actions'方法
execute_Actions();
}
}
private static void execute_Actions() throws Exception {
//循环遍历每一个关键字驱动方法(在actionskeywords.java中)
// 下面method.length表示方法个数,method变量表示任何一个关键字方法,例如openBrowser()
for(int i = 0;i < method.length;i++){
//开始对比代码中关键字方法名称和excel中关键字这列值是否匹配
if(method[i].getName().equals(sActionKeyword)){
//一但匹配到相关关键字方法,就会调用对应的关键字静态方法
method[i].invoke(actionKeywords);
//一旦任何关键字被执行,利用break语句去跳出for循环。
break;
}
}
}
}
上面原作者采用new的方式去得到反射类的对象,我改成了forName,但是在main方法第一行还是需要添加创建一个当前driverScript类的对象,否则由于代码执行顺序,先执行main方法,然后执行构造方法,这样由于actionKeywords没有初始化,所以声明的类对象method得到是null,从而method.length报空指针错误。
在使用了Java反射机制之后,上面的代码要比前面一篇那么多if-else if要简洁,好看多了。这样就不用写很多判断分支语句。下面一篇介绍如何把一些常量放在一个类文件,这样就不用在代码中写死,也就是所谓硬编码问题。
七:对象仓库
在识别和实现动作关键字这篇文章,你一定注意到了,每个元素操作都写了一个动作关键字的静态方法。如input value in username and passward. 这确实是一个很不好的设计,试着想一下,如果我实际项目中,有很多网页元素要操作,那么是不是要写成千上万的动作关键字呢?很显然,我们应该对元素对象操作进行分类,例如点击元素,我们就封装一个点击方法,不用在意点击的元素是什么。元素文本框输入也封装一个元素输入方法,这样我们基本上一个点击和一个输入动作关键字就实现了很多页面基本操作。
利用面向对象思想,首先我有一个登陆元素,叫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;
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;
}
}
}
}
步骤3:Constants.java内容修改后如下
package config;
public class Constants {
// 这里定义为public static的类型,方便其他任何类进行访问和调用, static只能被class访问
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";
}
步骤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();
}
}