• 一个简单的Web UI自动化测试框架Java实现


    简介

    原创文章,转载请注明出处

    这个框架的名字叫OAT,全称Object-Oriented  Automation Test.这个框架的思想借助于Tellurium框架.他的主要功能是将页面信息及行为存储在Java 对象中,然后在脚本中引用页面的行为.自动化程序最终由许多的页面行为组成.这个框架默认使用Selenium1驱动,并且可以通过编程使用其他驱动,因 为OAT是面向接口的.

     

    以下以google home page的demo为例,介绍这个基于Annoation和反射的框架基本运行原理.

     

    page对象

     

    Java代码  收藏代码
    1. //存储页面URL  
    2. @OatPage("webhp")   
    3. public class GooglePage extends Page{  
    4.     @Element("q") // 搜索输入框的定位符  
    5.     private TextField textField;  
    6.     @Element("btnG") // 搜索按钮的定位符  
    7.     private Button searchButton;  
    8.       
    9.     // TextField和Button有共同的祖先类Element  
    10.     public TextField getTextField() {  
    11.         return textField;  
    12.     }  
    13.     public Button getSearchButton() {  
    14.         return searchButton;  
    15.     }  
    16.     //进行一次搜索  
    17.     public void doSearch(String q){  
    18.         this.textField.type(q);  
    19.         this.searchButton.click();  
    20.     }     
    21.   
    22. }  

     TextField和button类

     

    Java代码  收藏代码
    1. // Element子类,有自己独特的行为  
    2. public class TextField extends Element {  
    3.       
    4.     public void type(String value) {  
    5.         vendor.type(locator, value);  
    6.     }  
    7.       
    8.     public boolean idEditable(){  
    9.         return vendor.isEditable(locator);        
    10.     }  
    11.       
    12.     public String getValue() {  
    13.         return vendor.getAttribute(locator);  
    14.     }  
    15.   
    16. }  
    17. // 同样是Element的子类,有自己行为  
    18. public class Button extends Element {  
    19.       
    20.       
    21.     public void click() {  
    22.         vendor.click(locator);  
    23.     }  
    24.       
    25.     public void clickAndWaitToLoad(Page page){  
    26.         click();  
    27.         page.waitToLoad();  
    28.     }  
    29.       
    30.     public void clickAndWaitToLoad(Page page, long timeout) {  
    31.         click();  
    32.         page.waitToLoad(timeout);  
    33.     }  
    34.       
    35.     public void clickAndWaitToLoad(Element element, long timeout) {  
    36.         click();  
    37.         element.waitToLoad(timeout);  
    38.     }  
    39.       
    40.     public void clickAndWaitToLoad(Element element) {  
    41.         clickAndWaitToLoad(element, ELEMENT_DEFAULT_TIMEOUT);  
    42.     }  
    43.       
    44. }  
     

     

    自动化测试脚本代码

     

    Java代码  收藏代码
    1. import junit.framework.Assert;  
    2.   
    3. import org.junit.After;  
    4. import org.junit.Before;  
    5. import org.junit.Test;  
    6.   
    7. import com.thoughtworks.selenium.DefaultSelenium;  
    8. import com.thoughtworks.selenium.Selenium;  
    9.   
    10. public class GoogleSearchTestExample1 {  
    11.       
    12.     private String serverUrl = "localhost";  
    13.     private int serverPort = 4444;  
    14.     private String browserCommand = "googlechrome";  
    15.     private String url = "http://www.google.com.hk";  
    16.       
    17.     private GooglePage page;  
    18.     private GoogleResultPage resultPage;  
    19.     private Selenium selenium;  
    20.     private Oat oat;  
    21.   
    22.     @Before  
    23.     public void setUp() throws Exception {  
    24.         // 初始化selenium  
    25.         selenium = new DefaultSelenium(serverUrl,serverPort,browserCommand, url);  
    26.         // Oat类是框架总的控制器,设置Selenium为背后的驱动  
    27.         oat = Oat.getInstance(selenium);  
    28.         oat.start();  
    29.         oat.open("/webhp");  
    30.         // 初始化被测试页面  
    31.         page = (GooglePage) oat.getPage(GooglePage.class);  
    32.         resultPage = (GoogleResultPage) oat.getPage(GoogleResultPage.class);  
    33.   
    34.     }  
    35.       
    36.     @Test  
    37.     public void testSearch() throws InterruptedException {  
    38.         // 在google页面收入"oat"进行搜索  
    39.                 page.doSearch("oat");         
    40.         page.waitToLoad(2000);  
    41.         // 在结构页面进行验证  
    42.         boolean result = resultPage.isTextPresent("oat");  
    43.         Assert.assertTrue("Text oat is present", result);  
    44.     }  
    45.   
    46.     @After  
    47.     public void tearDown() throws Exception {  
    48.         oat.stop();  
    49.         oat = null;  
    50.         page = null;  
    51.         selenium = null;  
    52.     }  
    53.   
    54. }  

     

    Oat.getInstance(Object engine):用于获取真正的Driver:

    Java代码  收藏代码
    1. //可以根据传入的不同engine,实例化不同的Vendor  
    2. public static Oat getInstance(Object engine) {  
    3.         if(instance == null) {  
    4.             synchronized(Oat.class) {  
    5.                 if(instance == null) {  
    6.                       
    7.                     String vendorTypeStr = getVendorTypeStr();  
    8.                       
    9.                     try {  
    10.                         Class<?> vendorType = Class.forName(vendorTypeStr);  
    11.                         Vendor vendor = getVendor(vendorType, engine);                
    12.                         instance = new Oat();  
    13.                         instance.vendor = vendor;  
    14.                           
    15.                     } catch (ClassNotFoundException e) {  
    16.                         throw new RuntimeException("Not Found vendor " + vendorTypeStr, e);  
    17.                     }   
    18.                 }  
    19.             }  
    20.         }  
    21.           
    22.         return instance;  
    23.     }  

     

    Oat.getPage()方法详解

    Java代码  收藏代码
    1. public Page getPage(Class<? extends Page> pageType) {  
    2.         Page page = null;  
    3.           
    4.         page = initialize(pageType);  
    5.         page.setVendor(vendor);  
    6.           
    7.     }  
    8.   
    9. private Page initialize(Class<? extends Page> pageType) {  
    10.                 //读取page类中的annotation  
    11.         OatPage anno = pageType.getAnnotation(OatPage.class);  
    12.           
    13.         if(anno == null) {  
    14.             throw new RuntimeException("Please add com.perficient.oat.component.annotaion.OatPage annotation in Page class!");  
    15.         }  
    16.           
    17.         Page page = null;  
    18.         try {  
    19.             page = pageType.newInstance();  
    20.         } catch (Exception e) {  
    21.             throw new RuntimeException("Page Class must have a non-parameter constructor.", e);  
    22.         }   
    23.           
    24.         Class<?> tempType = pageType;  
    25.           
    26.         while(tempType != null) {  
    27.             Field[] fields = tempType.getDeclaredFields();  
    28.               
    29.             for(Field field : fields ) {  
    30.                   
    31.                 com.perficient.oat.component.annotaion.Element annotation =   
    32.                     field.getAnnotation(com.perficient.oat.component.annotaion.Element.class);  
    33.                   
    34.                 if(annotation == null) {  
    35.                     continue;  
    36.                 }  
    37.                   
    38.                 Class<?> fieldClazz = field.getType();  
    39.                 // 只处理Element的子类  
    40.                 Class<? extends Element> elementClazz = fieldClazz.asSubclass(Element.class);  
    41.                   
    42.                 String locator = annotation.value();  
    43.                   
    44.                 field.setAccessible(true);  
    45.                                 //使用反射初始化Page类的各个Element子类,并赋予Locator值  
    46.                   
    47.                 try {  
    48.                     field.set(page, getElement(elementClazz, locator));  
    49.                 } catch (Exception e) {  
    50.                     throw new RuntimeException("set Element " + field.getName() + " error", e);  
    51.                 }  
    52.             }  
    53.               
    54.             tempType = tempType.getSuperclass();  
    55.         }  
    56.           
    57.         return page;  
    58.           
    59.     }  
    60. //用于初始化Page类中的各个Element子类  
    61. private Element getElement(Class<? extends Element> elementType, String locator) {  
    62.         Element element = null;  
    63.         try {  
    64.             element = elementType.newInstance();  
    65.             element.setLocator(locator);  
    66.             element.setVendor(vendor);  
    67.         } catch (Exception e) {  
    68.             throw new RuntimeException(e);  
    69.         }   
    70.         return element;  
    71.     }  

     

     

     

    以上就是一个完整的基于Selenium driver的框架实现.以下是我们的Vendor接口:

    Java代码  收藏代码
    1. public interface Vendor {  
    2.       
    3.     public void start();  
    4.     public void stop();  
    5.     public void open(String url);  
    6.     public void openWindow(String url, String windowId);  
    7.     public void type(String locator, String value);  
    8.     public void check(String locator);  
    9.     public void uncheck(String locator);  
    10.     public boolean isChecked(String locator);  
    11.     public boolean isEditable(String locator);  
    12.     public void select(String selectLocator, String optionLocator);  
    13.     public String getSelectedLabel(String locator);  
    14.     public String[] getSelectedLabels(String locator);  
    15.     public boolean isSelected(String label);  
    16.     public void submit(String formLocator);  
    17.     public void click(String locator);  
    18.     public boolean isTextPresent(String pattern);  
    19.     public boolean isElementPresent(String locator);  
    20.     public void waitForPageToLoad(String timeout);  
    21.     public void windowFocus(String windowId);  
    22.     public String getAttribute(String attributeLocator);  
    23.     public String getTableCellValue(String locator, int row, int col);  
    24.     public void waitForElementToLoad(String locator, String timeout);  
    25.     public String getLocation();  
    26. }  

     以下是seleniumVendor的实现:

    Java代码  收藏代码
    1. public class SeleniumVendor extends VendorTemplate<Selenium> {  
    2.   
    3.     @Override  
    4.     protected Selenium createEngine(VendorAttribute attribute) {  
    5.         return new DefaultSelenium(  
    6.                 attribute.getHost(),   
    7.                 attribute.getPort(),  
    8.                 attribute.getBrowser(),  
    9.                 attribute.getUrl());  
    10.     }  
    11.       
    12.     @Override  
    13.     public boolean isTextPresent(String pattern) {  
    14.         return engine.isTextPresent(pattern);  
    15.     }  
    16.   
    17.     @Override  
    18.     public void open(String url) {  
    19.         engine.open(url);  
    20.           
    21.     }  
    22.   
    23.     @Override  
    24.     public void select(String selectLocator, String optionLocator) {  
    25.         engine.select(selectLocator, optionLocator);  
    26.     }  
    27.   
    28.     @Override  
    29.     public void start() {  
    30.         engine.start();  
    31.     }  
    32.   
    33.     @Override  
    34.     public void stop() {  
    35.         engine.stop();  
    36.     }  
    37.   
    38.     @Override  
    39.     public void submit(String formLocator) {  
    40.         engine.submit(formLocator);  
    41.           
    42.     }  
    43.   
    44.     @Override  
    45.     public void type(String locator, String value) {  
    46.         engine.type(locator, value);  
    47.     }  
    48.   
    49.     @Override  
    50.     public void click(String locator) {  
    51.         engine.click(locator);  
    52.           
    53.     }  
    54.   
    55.     @Override  
    56.     public void waitForPageToLoad(String timeout) {  
    57.         engine.waitForPageToLoad(timeout);  
    58.           
    59.     }  
    60.   
    61.     @Override  
    62.     public void windowFocus(String windowId) {  
    63.         engine.selectWindow(windowId);  
    64.         engine.windowFocus();  
    65.     }  
    66.   
    67.     @Override  
    68.     public void openWindow(String url, String windowId) {  
    69.         engine.openWindow(url, windowId);  
    70.     }  
    71.   
    72.     @Override  
    73.     public void check(String locator) {  
    74.         engine.check(locator);  
    75.           
    76.     }  
    77.   
    78.     @Override  
    79.     public String getAttribute(String attributeLocator) {  
    80.         return engine.getAttribute(attributeLocator);  
    81.     }  
    82.   
    83.     @Override  
    84.     public boolean isElementPresent(String locator) {  
    85.         return engine.isElementPresent(locator);  
    86.     }  
    87.   
    88.     @Override  
    89.     public void uncheck(String locator) {  
    90.         engine.uncheck(locator);  
    91.           
    92.     }  
    93.   
    94.     @Override  
    95.     public boolean isChecked(String locator) {  
    96.         return engine.isChecked(locator);  
    97.     }  
    98.   
    99.     @Override  
    100.     public String getSelectedLabel(String locator) {  
    101.         return engine.getSelectedLabel(locator);  
    102.     }  
    103.   
    104.     @Override  
    105.     public String[] getSelectedLabels(String locator) {  
    106.         return engine.getSelectedLabels(locator);  
    107.     }  
    108.   
    109.     @Override  
    110.     public boolean isSelected(String label) {  
    111.         return engine.isSomethingSelected(label);  
    112.     }  
    113.   
    114.     @Override  
    115.     public boolean isEditable(String locator) {  
    116.         return engine.isEditable(locator);  
    117.     }  
    118.   
    119.     @Override  
    120.     public String getTableCellValue(String locator, int row, int col) {  
    121.         return engine.getTable(locator + "." + String.valueOf(row)+ "." +String.valueOf(col));  
    122.     }  
    123.   
    124.     @Override  
    125.     public void waitForElementToLoad(String locator, String timeout) {  
    126.         String script = "selenium.isElementPresent("" + locator + "")";  
    127.         engine.waitForCondition(script, timeout);  
    128.     }  
    129.   
    130.     @Override  
    131.     public String getLocation() {  
    132.         return engine.getLocation();  
    133.     }  
    134.   
    135.   
    136. }  

     

    如果我们需要改成其他Dirver,新建立一个Vendor的实现类即可

  • 相关阅读:
    【springboot】处理【跨域】请求
    【JPA】【概念】JPA概念解析:CascadeType(各种级联操作)详解
    【JPA】关于SpringBoot使用JPA的更新操作(save方法和原生SQL方法)
    jpa @query上使用if判断
    【Jpa】动态多表if多条件联合查询,并对查询结果进行分页
    phpstorm2020.1 免注册
    uniapp实现多语言切换
    vue进页面input自动获取焦点
    vue-cli4使用less全局变量
    用js实现隐藏手机号中间四位
  • 原文地址:https://www.cnblogs.com/hua-an/p/5029643.html
Copyright © 2020-2023  润新知