在UI自動化測試中,相信很多人都喜歡用所謂的PO模式,其中的P,也就是page的意思,於是乎,在腳本里,或者在其它的page里,會要new很多的page對象,這樣很麻煩,前面我們也講到了注解的使用,很方便,那么我們可不可以用注解來代替這個new的過程呢?只有想不到,沒有辦不到的,因為springMVC就是用了這個方式來IOC,當然我們也可以直接用springMVC,但這無異於用牛刀來切豆腐,還不如我們自已實現一下,順便增加一下對注解的使用的認識,代碼如下:
1.先定義一個LoadPage的注解:
package com.test.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoadPage {
String value();
}
2.再來實現一下這個注解:
package com.test.annotation;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.openqa.selenium.WebDriver;
public class LoadAllPage {
public final String basePath = "com.test";
private final String binPath = "bin";
private List<String> allClass = new ArrayList<String>();
private WebDriver driver;
public void setDriver(WebDriver driver) {
this.driver = driver;
}
public void loadAllPage(){
this.listAllFiles(binPath+File.separator+basePath.replace(".","/"));
this.getPageInstance();
}
private void listAllFiles(String path){
path = path.replace("\\", "/");
File file = new File(path);
if(file.isFile() && file.getName().endsWith(".class")){
String filePath = file.getPath().replace("\\", "/");
int startIndex = 4;
int endIndex = filePath.lastIndexOf(".class");
allClass.add(filePath.substring(startIndex, endIndex).replace("/", "."));
}else if(file.isDirectory()){
File[] files = file.listFiles();
for (File f : files) {
this.listAllFiles(f.getPath());
}
}
}
private void getPageInstance(){
for (String clazz : allClass) {
try {
Class<?> c = Class.forName(clazz);
if(c.isAnnotationPresent(LoadPage.class)){
LoadPage lp = c.getAnnotation(LoadPage.class);
Constructor<?> cons = c.getConstructor(WebDriver.class);
InitialManger.allInstance.put(lp.value(), cons.newInstance(driver));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
LoadAllPage lap = new LoadAllPage();
lap.loadAllPage();
}
}
3.再定義一個Page注解:
package com.test.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Page {
public String name() default "";
}
4.同樣的,需要實現下Page注解
package com.test.annotation;
import java.lang.reflect.Field;
import java.util.Iterator;
public class AutoPage {
public void setPageAnnotation(){
Iterator<String> it = InitialManger.allInstance.keySet().iterator();
while(it.hasNext()){
String key = it.next();
try {
Class<?> c = InitialManger.allInstance.get(key).getClass();
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
if(field.isAnnotationPresent(Page.class)){
field.set(InitialManger.allInstance.get(key), InitialManger.allInstance.get(field.getAnnotation(Page.class).name()));
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
}
public void setTestAnnotation(Object o) {
try {
Class<?> c = o.getClass();
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
if(field.isAnnotationPresent(Page.class)){
field.set(o, InitialManger.allInstance.get(field.getAnnotation(Page.class).name()));
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
}
5.增加一個所有page實例化后的對象管理類:
package com.test.annotation;
import java.util.HashMap;
import java.util.Map;
public class InitialManger {
public static Map<String, Object> allInstance = new HashMap<String, Object>();
}
6.再來初始化一下實現注解類:
package com.test.annotation;
import org.openqa.selenium.WebDriver;
public class InitialAnnotation {
private WebDriver driver;
public InitialAnnotation(WebDriver driver) {
this.driver = driver;
}
public void initialAnnotation(){
LoadAllPage lap = new LoadAllPage();
lap.setDriver(driver);
lap.loadAllPage();
AutoPage ap = new AutoPage();
ap.setPageAnnotation();
}
}
7.接下來就是使用了:在一個Page中加上這個@LoadPage注解:
package com.test.page;
import org.openqa.selenium.WebDriver;
import com.test.annotation.LoadPage;
import com.test.base.Page;
@LoadPage("firstPage")
public class FirstPage extends Page{
public FirstPage(WebDriver driver) {
super(driver);
}
public void linkToMobileList(){
driver.navigate().to("http://www.baidu.com");
}
}
8.為了使@Page注解在case中能用到,所以得在TestBase的@BeforeClass中添加如下代碼:
if(InitialManger.allInstance.isEmpty()){
InitialAnnotation init = new InitialAnnotation(driver);
init.initialAnnotation();
}
AutoPage ap = new AutoPage();
ap.setTestAnnotation(this);
9.在CASE中這樣用即可:
package com.test.testcases;
import java.util.Map;
import org.testng.annotations.Test;
import com.test.annotation.Page;
import com.test.base.TestBase;
import com.test.page.FirstPage;
public class Test2 extends TestBase{
@Page(name="firstPage")
private FirstPage firstPage;
@Test(dataProvider="providerMethod")
public void testLogin(Map<String, String> param){
firstPage.linkToMobileList();
}
}
整個過程就是這樣的,可能有人會說這樣也不方便,等等等等,總是有人能接受,有人不能接受的,如果能接受,可以找我共同討論一下。QQ:408129370
