摘要

自动化测试框架demo,用关键字的形式将测试逻辑封装在数据文件中,测试工具解释这些关键字即可对其应用自动化

一、原理及特点

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://my.oschina.net/hellotest/blog/531932

UI自动化测试框架之Selenium关键字驱动 (转)的更多相关文章

  1. 【转】UI自动化测试框架之Selenium关键字驱动

    原网址:https://my.oschina.net/hellotest/blog/531932#comment-list 摘要: 自动化测试框架demo,用关键字的形式将测试逻辑封装在数据文件中,测 ...

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

    一.原理及特点 1. 关键字驱动测试是数据驱动测试的一种改进类型 2. 主要关键字包括三类:被操作对象(Item).操作(Operation)和值(value),用面向对象形式可将其表现为Item.O ...

  3. 数据驱动 vs 关键字驱动:对搭建UI自动化测试框架的探索

    UI自动化测试用例剖析 让我们先从分析一端自动化测试案例的代码开始我们的旅程.以下是我之前写的一个自动化测试的小Demo.这个Demo基于Selenium与Java.由于现在Selenium在自动化测 ...

  4. UI自动化测试框架(项目实战)python、Selenium(日志、邮件、pageobject)

    其实百度UI自动化测试框架,会出来很多相关的信息,不过就没有找到纯项目的,无法拿来使用的:所以我最近就写了一个简单,不过可以拿来在真正项目中可以使用的测试框架. 项目的地址:https://githu ...

  5. Selenium关键字驱动测试框架Demo(Java版)

    Selenium关键字驱动测试框架Demo(Java版)http://www.docin.com/p-803493675.html

  6. 基于selenium+Python3.7+yaml+Robot Framework的UI自动化测试框架

    前端自动化测试框架 项目说明 本框架是一套基于selenium+Python3.7+yaml+Robot Framework而设计的数据驱动UI自动化测试框架,Robot Framework 作为执行 ...

  7. 自动化测试中级篇——LazyAndroid UI自动化测试框架使用指南

    原文地址https://blog.csdn.net/iamhuanggua/article/details/53104345 简介   一直以来,安卓UI自动化测试都存在以下两个障碍,一是测试工具Mo ...

  8. 简单Web UI 自动化测试框架 pyse

    WebUI automation testing framework based on Selenium and unittest. 基于 selenium 和 unittest 的 Web UI自动 ...

  9. Ui自动化测试框架

    为了提高我们的UI测试效率,我们引用Ui自动化测试框架,这里简单先描述一下,后续会详细补充: 了解一个测试框架,我们就需要了解一下源码,能看懂源码即可: 1.稳定先封装wait EC,电脑性能配置较好 ...

随机推荐

  1. node 下好用的工具

    1. supervisor Node Supervisor is used to restart programs when they crash. Node Supervisor 是用来当程序崩溃时 ...

  2. XE10 塔建 Android 开发环境 (已测试通过)

    XE10 塔建 Android 开发环境 1. E:\DevCSS\Android\adt-bundle-windows-x86-20131030\adt-bundle-windows-x86-201 ...

  3. MemSQL start[c]up Round 1.E

    完全的乱搞题啊... 被坑的要死. 拿到题目就觉得是规律题加构造题, 然后找了了几个小时无果,只知道n为奇数的时候是一定无解的,然后当n为偶数的时候可能有很多解,但是如果乱选择的话,很有可能形成无解的 ...

  4. Arduino开发版学习计划--直流电机

    代码来源:http://www.cnblogs.com/starsnow/p/4579547.html // --------------------------------------------- ...

  5. 常用 Git 操作

    最新博客链接:https://feiffy.cc/Git 日常用到的GIT的一些操作,记下来,以备参考. 删除文件 git rm filename git commit -m "remove ...

  6. CodeForces 651 A Joysticks

    A. Joysticks time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  7. Abp Uow 设计

    初始化入口 在AbpKernelModule类中,通过UnitOfWorkRegistrar.Initialize(IocManager) 方法去初始化 /// <summary> /// ...

  8. flume jetty 进程关系 flume jetty 跨域问题 jetty 源码分析

    flume  jetty  跨域问题 13481 httpSource的端口进程号 = flume 启动后的进程号 [root@c log]# netstat -atp Active Internet ...

  9. hotspot的简单介绍

    慢慢开始深入了解java,才知道java虚拟机有很多种,其中最为知名的应该就是hotspot了,接下来是hotspot的一点简单介绍. 没错,Java是解释语言,但并不意味着它一定被解释执行.早期 的 ...

  10. python基础-第五篇-5.3装饰器

    小白发呆的看着窗外,同事们陆陆续续的地来到公司,想起算法,小白就飘飘然了.突然后面传来一声呼唤,原来是小刘! 小刘:不好意思啊!堵车了,就来晚了点,不耽误你的时间,咱们就开启的今天的培训内容吧! 小白 ...