JAVA 自定义注解在自动化测试中的使用

时间:2021-04-22 20:34:26

在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