简介
原创文章,转载请注明出处
这个框架的名字叫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();
- // 只处理Element的子类
- 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的实现类即可