UI自动化测试框架之Selenium关键字驱动

一、原理及特点

  1. 关键字驱动测试是数据驱动测试的一种改进类型
  2. 主要关键字包括三类:被操作对象(Item)、操作(Operation)和值(value),用面向对象形式可将其表现为Item.Operation(Value)
  3. 将测试逻辑按照这些关键字进行分解,形成数据文件。
  4. 用关键字的形式将测试逻辑封装在数据文件中,测试工具只要能够解释这些关键字即可对其应用自动化

二、准备

使用工具:eclipse

用到的第三方jar包:poi.jar(操作excel);selenium.jar

理解难点:java反射机制;逐步分层

三、框架构思

1、编写脚本

首先我们来写一个登陆开源中国的脚本

public class Login_Script {
            public static WebDriver driver=null;
            public static void main(String []agrs) throws InterruptedException{
//                启动火狐浏览器
                driver= new FirefoxDriver();
//                最大化
                driver.manage().window().maximize();
//                打开开源中国网址
                driver.get("http://www.oschina.net/");
//                点击登录
                driver.findElement(By.xpath("//*[@id='OSC_Userbar']/a[1]")).click();
//                输入用户名
                driver.findElement(By.xpath("//*[@id='f_email']")).sendKeys("XXXXXXB");
//                输入密码
                driver.findElement(By.xpath("//*[@id='f_pwd']")).sendKeys("XXXXXXXA");
//                点击登录按钮
//                driver.findElement(By.xpath("//*[@id='login_osc']/table/tbody/tr[7]/td/input")).click();
//                Thread.sleep(30);
//                点击退出按钮
                driver.findElement(By.xpath("//*[@id='OSC_Userbar']/a[3]")).click();
//                关闭浏览器
                driver.quit();
                }
}

2、脚本分析

这是登陆的场景

操作步骤

第一步:启动浏览器

第二步:输入网址

第四步:点击登录

第五步:输入用户名

第六步:输入密码

第七步:点击登录按钮

第八步:点击退出

第九步:关闭浏览器

3、使用excel

建立一个excel

在java中创建一个操作excel的类 ,主要实现是对excel的读和写,主要代码如下:

public class ExcelUtils {
        public static HSSFSheet ExcelSheet;
        public static HSSFWorkbook    ExcelBook;
        public static HSSFRow Row;
        public static HSSFCell    Cell;
        public static void setExcelFile(String Path,String    SheetName) throws Exception{
            FileInputStream    ExcelFile=new FileInputStream(Path);
            ExcelBook=new HSSFWorkbook(ExcelFile);
            ExcelSheet=ExcelBook.getSheet(SheetName);
        }
        public static void setCellData(String Result,  int RowNum, int ColNum,String Path) throws Exception{
              Row  = ExcelSheet.getRow(RowNum);
            Cell = Row.getCell(ColNum, Row.RETURN_BLANK_AS_NULL);
            if (Cell == null) {
                Cell = Row.createCell(ColNum);
                Cell.setCellValue(Result);
                } else {
                    Cell.setCellValue(Result);
                }
            FileOutputStream fileOut = new FileOutputStream(Path);
            ExcelBook.write(fileOut);
            fileOut.flush();
            fileOut.close();
        }
        public static String getCellDate(int RowNum,int CloNum){
            Cell=ExcelSheet.getRow(RowNum).getCell(CloNum);
            String cellData=Cell.getStringCellValue();
            return cellData;
        }
}

4、新建一个ActionKeyWords类

public class ActionKeyWords {
    public static WebDriver driver=null;
//    启动浏览器并最大化
    public static void OpenBrowser (){
        driver= new FirefoxDriver();
        driver.manage().window().maximize();
    }
//    打开开源中国网址
    public static void Navigate (){
        driver.get("http://www.oschina.net/");
    }
//    点击登录
    public static void Login_Click (){
        driver.findElement(By.xpath("//*[@id='OSC_Userbar']/a[1]")).click();
    }
//    输入用户名
    public static void Input_Name (){
        driver.findElement(By.xpath("//*[@id='f_email']")).sendKeys("XXXXXXA");
    }
//    输入密码
    public static void Input_Password (){
        driver.findElement(By.xpath("//*[@id='f_pwd']")).sendKeys("XXXXXXB");
    }
//    点击登录按钮
    public static void Login_Button (){
        driver.findElement(By.xpath("//*[@id='login_osc']/table/tbody/tr[7]/td/input")).click();
    }
    //    点击退出按钮
    public static void Logout_Click (){
        driver.findElement(By.xpath("//*[@id='OSC_Userbar']/a[3]")).click();
    }
//    关闭浏览器
    public static void CloseBrowser (){
        driver.quit();
    }
}

5、修改Login_Script脚本.

public class Login_Script {
            public static void main(String []agrs) throws Exception{
                ExcelUtils.setExcelFile("D:\\data\\TestData.xls", "steps");
                ActionKeyWords actionKeyWords= new ActionKeyWords();
                String Keywords=null;
                for(int RowNum=1;RowNum<=ExcelUtils.getLastRowNums();RowNum++){
                    Keywords=ExcelUtils.getCellDate(RowNum, 3);
                    if(Keywords.trim().equals("OpenBrowser")){
                        actionKeyWords.OpenBrowser();
                    }else if(Keywords.trim().equals("Navigate")){
                        actionKeyWords.Navigate();
                    }else if(Keywords.trim().equals("Login_Click")){
                        actionKeyWords.Login_Click();
                    }else if(Keywords.trim().equals("Input_Name")){
                        actionKeyWords.Input_Name();
                    }else if(Keywords.trim().equals("Input_Password")){
                        actionKeyWords.Input_Password();
                    }else if(Keywords.trim().equals("Login_Button")){
                        actionKeyWords.Login_Button();
                    }else if(Keywords.trim().equals("Logout_Click")){
                        actionKeyWords.Logout_Click();
                    }else if(Keywords.trim().equals("CloseBrowser")){
                        actionKeyWords.CloseBrowser();
                    }
                }
            }
}

这样代码的框架就基本已经搭建起来了,代码结构如下:

四、结构优化

1、优化Login_Script 类中的代码

注:这里用到了反射机制

 public class Login_Script {
            public static ActionKeyWords actionKeyWords;
            public static String Keywords=null;
            public static Method[] method;
            public Login_Script(){
                actionKeyWords= new ActionKeyWords();
                method=actionKeyWords.getClass().getMethods();
            }
            public static void main(String []agrs) throws Exception{
                ExcelUtils.setExcelFile("D:\\data\\TestData.xls", "steps");
                new Login_Script();
                for(int RowNum=1;RowNum<=ExcelUtils.getLastRowNums();RowNum++){
                    Keywords=ExcelUtils.getCellDate(RowNum, 3);
                    login_action();
                }
            }
            public static void login_action(){
                for(int i=0;i<method.length;i++){
//                    System.out.println(method[i].getName()+"     "+actionKeyWords+Keywords);
                    if(method[i].getName().trim().equals(Keywords)){
                        try {
                            method[i].invoke(actionKeyWords);
                        } catch (IllegalAccessException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IllegalArgumentException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
}

2、将程序中的常量统一管理

例如:网页的地址,账户、密码,excel路径,这里我们在文件下面建立一个

public class Contants {
    public static  String url="http://www.oschina.net/";
    public static String excelFile="D:\\data\\";
    public static String excelName="TestData.xls";
    public static String excelSheet="steps";
    public static int excelKWCloNum=3;
    public static String userName="XXXXXXXA";
    public static String userPassword="XXXXXB";
}

3、增加对象库

下面我们看一下ActionKeyWords类中定位元素的路径 是在代码里面的,如果每次去修改的定位路径的是时候都要修改代码,为了便于维护,我们将这些元素的对象放在一个文件中,同时我们在Excel增加一列 Page Objects,这样程序根据Excel中的Page Objects,去文件中读取相应的元素,这里我们增加一个类OrpUtil,读取元素的对象

# Home Page Objects
Userbar_login=//*[@id='OSC_Userbar']/a[1]
Userbar_logout=//div[@id='OSC_Userbar']/a[3]
#Login Page Objects
Input_name=//*[@id='f_email']
Input_password=//*[@id='f_pwd']
Login_button=//*[@id='login_osc']/table/tbody/tr[7]/td/input
//OrpUtil类
public class OrpUtil {
    public static String  readValue(String a){
        Properties pro=new Properties();
        String popath=Contants.ObjectReUrl;
        String value=null;
        try {
            InputStream in =new BufferedInputStream(new FileInputStream(popath));
            pro.load(in);
            value=pro.getProperty(a);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return value;
    }
}

优化后的ActionKeyWords类

public class ActionKeyWords {
    public static WebDriver driver=null;
//    启动浏览器并最大化
    public static void OpenBrowser (String OR){
        System.setProperty("webdriver.chrome.driver", ".//server//chromedriver.exe");
        driver= new ChromeDriver();
        driver.manage().window().maximize();
    }
//    打开开源中国网址
    public static void Navigate (String OR){
        driver.get(Contants.url);
    }
//    点击登录
    public static void Login_Click (String OR){
        driver.findElement(By.xpath(OrpUtil.readValue(OR))).click();
    }
//    输入用户名
    public static void Input_Name (String OR){
        driver.findElement(By.xpath(OrpUtil.readValue(OR))).clear();
        driver.findElement(By.xpath(OrpUtil.readValue(OR))).sendKeys(Contants.userName);
    }
//    输入密码
    public static void Input_Password (String OR){
        driver.findElement(By.xpath(OrpUtil.readValue(OR))).click();
        driver.findElement(By.xpath(OrpUtil.readValue(OR))).sendKeys(Contants.userPassword);
    }
//    点击登录按钮
    public static void Login_Button (String OR){
        driver.findElement(By.xpath(OrpUtil.readValue(OR))).click();
    }
    //    点击退出按钮
    public static void Logout_Click (String OR){
        try {
            Thread.sleep(300);
            driver.findElement(By.xpath(OrpUtil.readValue(OR))).click();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
//    关闭浏览器
    public static void CloseBrowser (String OR){
        driver.quit();
    }
}

这个OR的值是从Excel中读取的

4、增加测试场景

从Excel中我们可以看到,这操作是对应的用例编写中的我们的操作步骤,在用例设计的时候还有测试场景和结果,这里

我们先增加个场景在EXCEL中增加一个名称为Suite的Sheet页

我们程序的运行逻辑是循环读取Suite页中的Runmode,当为YES时根据对应的TestSuiteID去读取对应的Steps页中的操作在步骤,进行运行

public static void main(String []agrs) throws Exception{
                ExcelUtils.setExcelFile(Contants.excelFile+Contants.excelName );
                new Login_Script();
                bResult = true;
//              循环读取suitSheet里面的值,找出运行的场景
                for(int j=1;j<=ExcelUtils.getLastRowNums(Contants.suitSheet);j++){

                    String Runmode=ExcelUtils.getCellDate(j, Contants.suitRunmode,Contants.suitSheet);
                    String suitTestSuiteId=ExcelUtils.getCellDate(j, Contants.suitTestSuiteId,Contants.suitSheet);
                    int sRowNum;

                    if(Runmode.equals("YES")){
//                      根据stepTestSuiteId在caseSheet中循环查找相对应的执行步骤
                        for(sRowNum=1;sRowNum<=ExcelUtils.getLastRowNums(Contants.caseSheet);sRowNum++){
                            String stepTestSuiteId=ExcelUtils.getCellDate(sRowNum, Contants.stepTestSuiteId,Contants.caseSheet);
                            System.out.println(ExcelUtils.getCellDate(sRowNum, Contants.excelKWCloNum,Contants.caseSheet));
                            if(stepTestSuiteId.trim().equals(suitTestSuiteId)){
                                Keywords=ExcelUtils.getCellDate(sRowNum, Contants.excelKWCloNum,Contants.caseSheet);
                                r=ExcelUtils.getCellDate(sRowNum, Contants.excelPOCloNum,Contants.caseSheet);
                                login_action(sRowNum);
                                if(bResult == false){
                                    ExcelUtils.setCellData(Contants.fail, j, Contants.suitResult,Contants.excelFile+Contants.excelName, Contants.suitSheet);

                                }
                            }
                        }
                        if(bResult == true){
                            ExcelUtils.setCellData(Contants.pass, j, Contants.suitResult,Contants.excelFile+Contants.excelName, Contants.suitSheet);
                        }

                    }else{

                        System.out.println("没有要执行的用例");
                        break;
                    }

                }

            }

5、增加测试结果

在Excel中新增一列Resut

在Login_Script中定义一个boolean类型的变量bResult,默认是true在各个地方try,,cacth,当出现异常的时候在bResult赋值为false,在Excel工具类中增加一个写入excel值得方法

五、小结

这样我们的关键字驱动框架就初步搭好了,下面我们回归一下基本思路:

代码地址:http://git.oschina.net/hellotester/SeleniumKeywordDrive

文章转载自 开源中国社区[https://www.oschina.net]

时间: 2024-11-01 04:48:03

UI自动化测试框架之Selenium关键字驱动的相关文章

搭建 WPF 上的 UI 自动化测试框架

   OEA 1.0-2.0 框架中,界面都是以 WPF 技术作为基础平台开发的.我们需要对开发出来的系统进行自动化测试,而 .NET 平台的自动化测试平台在公司内部还没有其它部门完成,所以我们在 2010 年的时候使用 Ruby + VS UIUnitTest 开发了一个 UI 自动化(UI Automation,以下简称为UIA)框架,估且称其为 UIA 1.0.UIA 1.0 完全由周金根搭建,相关的内容,大家可以参考他写的这几篇文章: <使用VS2010的CodedUI来做自己的自动化测

Android App开发的自动化测试框架UI Automator使用教程_Android

Android的自动化测试有很多框架,其中ui automator是google官方提供的黑盒UI相关的自动化测试工具,(GitHub主页:case使用java写,今天实践了一下官方文档中样例程序,其中还是有一些小问题需要总结一下的. 环境准备: 1.JDK(是的,你没看错,基础的android开发环境必备),以及对应的环境变量配置,不会的可以自己百度下下 2.Android Studio(IDE尊崇个人意愿) 3.android SDK以及配置 4.ANT(主要用于build我们的脚本,生成j

谈 Dojo 应用的 UI 自动化测试

本文首先列举了 Dojo 应用 UI 自动化测试所面临的挑战,进而引出设计 Dojo 应用 UI 自动化测试的框架时应考虑的一些原则.对于正从事 Web UI 自动化测试工作的读者(即便所测试的应用不是 Dojo 应用)或者对这方面感兴趣的读者,本文都有一定的参考价值. 随着富 Internet 应用(RIA)的不断兴起,各种 JavaScript 开发工具包的功能也在不断增强,Dojo 正是其中的佼佼者.Dojo 提供了一套完整的开发解决方案,包括核心的 JavaScript 库.简单易用的小

借鉴ASP.NET的控件模型辅助UI自动化测试

概述 在敏捷测试中UI的自动化测试(一般我们也称这层测试为功能测试或验收测试,本文单指Web UI的自动化测试)虽然没有单元测试那么广为提及,但因为其与最终用户最近,所以基于用户场景的UI自动化测试还是有其重要的意义的.使用UI自动化测试对产品的关键功能路径进行验证及回归,比起传统的QA手工执行Test case可以更快地得到反馈,也让发布变得更有信心. 理想状况下,我们应该将所有可以固化下来的Test case都自动化起来,而让我们的测试人员进行更有挑战性的探索性测试活动.让机器做已知领域的事

《精通自动化测试框架设计》目录—导读

作者简介 精通自动化测试框架设计 陈冬严,浙江大学硕士,具有10年软件测试和团队管理的工作经验,先后服务于ITSM.PLM软件研发企业,现就职于某金融行业核心机构IT规划部门.业余时间喜欢园艺. 邵杰明,热爱测试工作,10多年的测试行业经验,曾先后供职于多家世界一流软件公司担任测试开发和测试管理工作,积累了丰富的行业工作经验,拥有PMP认证,目前担任测试架构师的工作,致力于自动化测试设计.持续交付等方面的工作. 王东刚,常用网名fastpoint,资深测试专家,<软件测试与Junit实践>作者

《精通自动化测试框架设计》—第1章 1.1节奥运年的新挑战

你多吃点饭,到东吴的路很长,很费体力. --<赤壁> 第1部分 构建UI自动化框架在本书的这一部分,将介绍数据管理.底层公共框架构建等主题,并借助TestLink Web UI自动化测试框架构建的实践案例来展示如何从底层框架开始,搭建一个具有良好可维护性以及后续可扩展性的Web UI自动化框架. 1.1 奥运年的新挑战2008年的夏天是一个举国欢腾的日子.An君在办公室里正对着"厨房三件套"的Office开始一段全新的奇妙旅程. An君加入的团队是P公司上海研发中心组建的第

开发基于XML的Selenium自动化测试框架

为解决该群体的困扰,本文将介绍如何让不熟悉编程的业务http://www.aliyun.com/zixun/aggregation/9621.html">测试人员也能编写出类似传统功能测试用例的自动化测试用例,从而扫除自动化测试的技术障碍. 本文适用于需要为测试团队开发自动化回归测试框架的测试设计开发人员.目前业内主流的商业自动化测试工具和开放源代码测试工具,都需要测试人员熟悉开发编程语言.但是过高的编程门槛让很多测试人员只能对自动化测试驻足遥望.为解决该群体的困扰,本文将介绍一种基于 X

自动化测试框架Selenium 入门

1.什么是selenium selenium是ThoughtWork的一款开源测试框架. 下载selenium2.0lib包,点击http://code.google.com/p/selenium/downloads/list 这是官方文档:http://seleniumhq.org/docs/ 2.为什么选择selenium 自动化测试工具有很多了,QTP作为商业软件功能强大.但是要把QTP整合到已有的测试平台上面非常困难,selenium非常容易的可以整合到已有的测试平台上面去.如果你是一个

《精通自动化测试框架设计》—第2章 2.5节使用Exce

2.5 使用Excel2.5.1 经典的DataTable 在图2.2所示的调查中,Excel作为排名第一的数据源是情理之中的.甚至可以说,应该找不出来没有使用过Excel表格进行数据处理的读者.Excel的易用性.强大的数据处理功能,也能让即使不会编程的使用者可以快速解决一些常用的数据统计.计算的问题.在早期的商业自动化测试工具中,数据驱动或者关键字驱动是作为一个卖点被广为宣传的亮点.接触过这些工具的读者估计都对DataTable之类的概念印象深刻.在那个假设"系统测试工程师不懂代码"