简介
原创文章,转载请注明出处
这个框架的名字叫OAT,全称Object-Oriented ?Automation Test.这个框架的思想借助于Tellurium框架.他的主要功能是将页面信息及行为存储在Java 对象中,然后在脚本中引用页面的行为.自动化程序最终由许多的页面行为组成.这个框架默认使用Selenium1驱动,并且可以通过编程使用其他驱动,因为OAT是面向接口的.
?
以下以google home page的demo为例,介绍这个基于Annoation和反射的框架基本运行原理.
?
page对象
?
//存储页面URL @OatPage("webhp") public class GooglePage extends Page{ @Element("q") // 搜索输入框的定位符 private TextField textField; @Element("btnG") // 搜索按钮的定位符 private Button searchButton; // TextField和Button有共同的祖先类Element public TextField getTextField() { return textField; } public Button getSearchButton() { return searchButton; } //进行一次搜索 public void doSearch(String q){ this.textField.type(q); this.searchButton.click(); } }
?TextField和button类
?
// Element子类,有自己独特的行为 public class TextField extends Element { public void type(String value) { vendor.type(locator, value); } public boolean idEditable(){ return vendor.isEditable(locator); } public String getValue() { return vendor.getAttribute(locator); } } // 同样是Element的子类,有自己行为 public class Button extends Element { public void click() { vendor.click(locator); } public void clickAndWaitToLoad(Page page){ click(); page.waitToLoad(); } public void clickAndWaitToLoad(Page page, long timeout) { click(); page.waitToLoad(timeout); } public void clickAndWaitToLoad(Element element, long timeout) { click(); element.waitToLoad(timeout); } public void clickAndWaitToLoad(Element element) { clickAndWaitToLoad(element, ELEMENT_DEFAULT_TIMEOUT); } }?
?
自动化测试脚本代码
?
import junit.framework.Assert; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.thoughtworks.selenium.DefaultSelenium; import com.thoughtworks.selenium.Selenium; public class GoogleSearchTestExample1 { private String serverUrl = "localhost"; private int serverPort = 4444; private String browserCommand = "googlechrome"; private String url = "http://www.google.com.hk"; private GooglePage page; private GoogleResultPage resultPage; private Selenium selenium; private Oat oat; @Before public void setUp() throws Exception { // 初始化selenium selenium = new DefaultSelenium(serverUrl,serverPort,browserCommand, url); // Oat类是框架总的控制器,设置Selenium为背后的驱动 oat = Oat.getInstance(selenium); oat.start(); oat.open("/webhp"); // 初始化被测试页面 page = (GooglePage) oat.getPage(GooglePage.class); resultPage = (GoogleResultPage) oat.getPage(GoogleResultPage.class); } @Test public void testSearch() throws InterruptedException { // 在google页面收入"oat"进行搜索 page.doSearch("oat"); page.waitToLoad(2000); // 在结构页面进行验证 boolean result = resultPage.isTextPresent("oat"); Assert.assertTrue("Text oat is present", result); } @After public void tearDown() throws Exception { oat.stop(); oat = null; page = null; selenium = null; } }
?
Oat.getInstance(Object engine):用于获取真正的Driver:
//可以根据传入的不同engine,实例化不同的Vendor public static Oat getInstance(Object engine) { if(instance == null) { synchronized(Oat.class) { if(instance == null) { String vendorTypeStr = getVendorTypeStr(); try { Class<?> vendorType = Class.forName(vendorTypeStr); Vendor vendor = getVendor(vendorType, engine); instance = new Oat(); instance.vendor = vendor; } catch (ClassNotFoundException e) { throw new RuntimeException("Not Found vendor " + vendorTypeStr, e); } } } } return instance; }
?
Oat.getPage()方法详解
public Page getPage(Class<? extends Page> pageType) { Page page = null; page = initialize(pageType); page.setVendor(vendor); } private Page initialize(Class<? extends Page> pageType) { //读取page类中的annotation OatPage anno = pageType.getAnnotation(OatPage.class); if(anno == null) { throw new RuntimeException("Please add com.perficient.oat.component.annotaion.OatPage annotation in Page class!"); } Page page = null; try { page = pageType.newInstance(); } catch (Exception e) { throw new RuntimeException("Page Class must have a non-parameter constructor.", e); } Class<?> tempType = pageType; while(tempType != null) { Field[] fields = tempType.getDeclaredFields(); for(Field field : fields ) { com.perficient.oat.component.annotaion.Element annotation = field.getAnnotation(com.perficient.oat.component.annotaion.Element.class); if(annotation == null) { continue; } Class<?> fieldClazz = field.getType(); Class<? extends Element> elementClazz = fieldClazz.asSubclass(Element.class); String locator = annotation.value(); field.setAccessible(true); //使用反射初始化Page类的各个Element子类,并赋予Locator值 try { field.set(page, getElement(elementClazz, locator)); } catch (Exception e) { throw new RuntimeException("set Element " + field.getName() + " error", e); } } tempType = tempType.getSuperclass(); } return page; } //用于初始化Page类中的各个Element子类 private Element getElement(Class<? extends Element> elementType, String locator) { Element element = null; try { element = elementType.newInstance(); element.setLocator(locator); element.setVendor(vendor); } catch (Exception e) { throw new RuntimeException(e); } return element; }
?
?
?
以上就是一个完整的基于Selenium driver的框架实现.以下是我们的Vendor接口:
public interface Vendor { public void start(); public void stop(); public void open(String url); public void openWindow(String url, String windowId); public void type(String locator, String value); public void check(String locator); public void uncheck(String locator); public boolean isChecked(String locator); public boolean isEditable(String locator); public void select(String selectLocator, String optionLocator); public String getSelectedLabel(String locator); public String[] getSelectedLabels(String locator); public boolean isSelected(String label); public void submit(String formLocator); public void click(String locator); public boolean isTextPresent(String pattern); public boolean isElementPresent(String locator); public void waitForPageToLoad(String timeout); public void windowFocus(String windowId); public String getAttribute(String attributeLocator); public String getTableCellValue(String locator, int row, int col); public void waitForElementToLoad(String locator, String timeout); public String getLocation(); }
?以下是seleniumVendor的实现:
public class SeleniumVendor extends VendorTemplate<Selenium> { @Override protected Selenium createEngine(VendorAttribute attribute) { return new DefaultSelenium( attribute.getHost(), attribute.getPort(), attribute.getBrowser(), attribute.getUrl()); } @Override public boolean isTextPresent(String pattern) { return engine.isTextPresent(pattern); } @Override public void open(String url) { engine.open(url); } @Override public void select(String selectLocator, String optionLocator) { engine.select(selectLocator, optionLocator); } @Override public void start() { engine.start(); } @Override public void stop() { engine.stop(); } @Override public void submit(String formLocator) { engine.submit(formLocator); } @Override public void type(String locator, String value) { engine.type(locator, value); } @Override public void click(String locator) { engine.click(locator); } @Override public void waitForPageToLoad(String timeout) { engine.waitForPageToLoad(timeout); } @Override public void windowFocus(String windowId) { engine.selectWindow(windowId); engine.windowFocus(); } @Override public void openWindow(String url, String windowId) { engine.openWindow(url, windowId); } @Override public void check(String locator) { engine.check(locator); } @Override public String getAttribute(String attributeLocator) { return engine.getAttribute(attributeLocator); } @Override public boolean isElementPresent(String locator) { return engine.isElementPresent(locator); } @Override public void uncheck(String locator) { engine.uncheck(locator); } @Override public boolean isChecked(String locator) { return engine.isChecked(locator); } @Override public String getSelectedLabel(String locator) { return engine.getSelectedLabel(locator); } @Override public String[] getSelectedLabels(String locator) { return engine.getSelectedLabels(locator); } @Override public boolean isSelected(String label) { return engine.isSomethingSelected(label); } @Override public boolean isEditable(String locator) { return engine.isEditable(locator); } @Override public String getTableCellValue(String locator, int row, int col) { return engine.getTable(locator + "." + String.valueOf(row)+ "." +String.valueOf(col)); } @Override public void waitForElementToLoad(String locator, String timeout) { String script = "selenium.isElementPresent(\"" + locator + "\")"; engine.waitForCondition(script, timeout); } @Override public String getLocation() { return engine.getLocation(); } }
?
如果我们需要改成其他Dirver,新建立一个Vendor的实现类即可