一、为什么要注解处理器
注解或注释,不读就没有任何意义
二、流程
- 先有注解处理器
- 根据处理的需求,设计几个注解
- 用这些注解,去注释代码
- 用这个注解处理器去自动读有注解的代码
生活场景:
- 保洁阿姨,想自动判断每个人的杯子是要加水、清洗,还是收起来
- 不想一个一个的问人,就设计几个标签:加水、清洗、收纳
- 把标签发给每个人,自己用标签去说明想怎么处理
- 保洁阿姨把所有杯子过一遍,有加水标签的就加水,有清洗标签的就清洗
代码场景:
- 想做一个自动处理代码的注解处理器
- 设计几个注解
- 让写代码的人用注解去标识这些代码要干嘛
- 注解处理器读取代码(Class类),把字段、方法等过一遍,根据标签判断要做什么处理
自定义一个处理器
1. 需求
遇到的问题:
之前做测试,只能用main方法,一次只能有1个,多个测试用例的代码,需要靠注释来指定要不要执行
想要做成什么效果?
把每一个测试用例,做成独立的方法,但是方法是没法直接被执行的,要main方法启动。能不能做一个注解处理器,给几个注解,用注解去注释测试用例方法,有标签的就执行,没标签的就不执行。
2. 设计标签
标签名 | 用途 |
---|---|
BeforeTest | 准备工作 |
Test | 测试用例 |
AfterTest | 收尾工作 |
package com.guoyasoft.testNG.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BeforeTest {
int priority() default 0;
int loop() default 1;
}
package com.guoyasoft.testNG.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
int priority() default 0;
int loop() default 1;
}
package com.guoyasoft.testNG.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AfterTest {
int priority() default 0;
int loop() default 1;
}
注解处理器初版只处理标签名
package com.guoyasoft.testNG.annotations;
import java.lang.reflect.Method;
public class TestNGSvc01 {
public static void dealTestNg(Class c) throws Exception{
//先实例化
Object obj=c.newInstance();
Method[] methods=c.getDeclaredMethods();
//1. 先执行标注了beforetest的方法
for(Method m:methods){
BeforeTest before=m.getAnnotation(BeforeTest.class);
if(before !=null){
m.invoke(obj);
}
}
//2. 先执行标注了test的方法
for(Method m:methods){
Test test=m.getAnnotation(Test.class);
if(test !=null){
m.invoke(obj);
}
}
//3. 先执行标注了after的方法
for(Method m:methods){
AfterTest after=m.getAnnotation(AfterTest.class);
if(after !=null){
m.invoke(obj);
}
}
}
}
实际使用
package com.guoyasoft.testNG.buisiness;
import org.openqa.selenium.WebDriver;
import com.guoyasoft.testNG.annotations.AfterTest;
import com.guoyasoft.testNG.annotations.BeforeTest;
import com.guoyasoft.testNG.annotations.Test;
public class TestWebDriver {
private WebDriver driver;
@BeforeTest
public void startChrome(){
System.out.println("------启动浏览器成功----------");
}
@Test(priority=2)
public void testButton(){
System.out.println("------测试button成功----------");
}
@Test(priority=1,loop=3)
public void testFile(){
System.out.println("------测试file成功----------");
}
//@Test(priority=3)
public void testSelect(){
System.out.println("------测试select成功----------");
}
//@AfterTest
public void shutdownChrome(){
System.out.println("------关闭浏览器成功----------");
}
@Test(loop=10)
public void testRadio(){
System.out.println("------测试radio成功----------");
}
}
测试
package com.guoyasoft.test;
import com.guoyasoft.testNG.annotations.TestNGSvc;
import com.guoyasoft.testNG.buisiness.TestWebDriver;
public class Test {
public static void main(String[] args) throws Exception {
TestNGSvc.dealTestNg(TestWebDriver.class);
}
}
注解处理器第2版加上优先级
package com.guoyasoft.testNG.annotations;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestNGSvc02 {
public static void dealTestNg(Class c) throws Exception{
//先实例化
Object obj=c.newInstance();
Method[] methods=c.getDeclaredMethods();
List beforelist=new ArrayList();
List testlist=new ArrayList();
List afterlist=new ArrayList();
for(Method m:methods){
if(m.getAnnotation(BeforeTest.class)!=null){
beforelist.add(m);
}else if(m.getAnnotation(Test.class)!=null){
testlist.add(m);
}else if(m.getAnnotation(AfterTest.class)!=null){
afterlist.add(m);
}else{
//3个注解都没有,舍弃不要
}
}
//1. 先执行标注了beforetest的方法
Collections.sort(beforelist,new Comparator() {
public int compare(Method m1, Method m2) {
int p1=m1.getAnnotation(BeforeTest.class).priority();
int p2=m2.getAnnotation(BeforeTest.class).priority();
return p1-p2;
}
});
for(Method m:beforelist){
BeforeTest before=m.getAnnotation(BeforeTest.class);
if(before !=null){
m.invoke(obj);
}
}
//2. 先执行标注了test的方法
Collections.sort(testlist,new Comparator() {
public int compare(Method m1, Method m2) {
int p1=m1.getAnnotation(Test.class).priority();
int p2=m1.getAnnotation(Test.class).priority();
return p2-p1;
}
});
for(Method m:testlist){
Test test=m.getAnnotation(Test.class);
if(test !=null){
m.invoke(obj);
}
}
//3. 先执行标注了after的方法
Collections.sort(afterlist,new Comparator() {
public int compare(Method m1, Method m2) {
int p1=m1.getAnnotation(AfterTest.class).priority();
int p2=m1.getAnnotation(AfterTest.class).priority();
return p2-p1;
}
});
for(Method m:afterlist){
AfterTest after=m.getAnnotation(AfterTest.class);
if(after !=null){
m.invoke(obj);
}
}
}
}
注解处理器第3版加上循环
package com.guoyasoft.testNG.annotations;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestNGSvc03 {
public static void dealTestNg(Class c) throws Exception {
// 先实例化
Object obj = c.newInstance();
Method[] methods = c.getDeclaredMethods();
List beforelist = new ArrayList();
List testlist = new ArrayList();
List afterlist = new ArrayList();
for (Method m : methods) {
if (m.getAnnotation(BeforeTest.class) != null) {
beforelist.add(m);
} else if (m.getAnnotation(Test.class) != null) {
testlist.add(m);
} else if (m.getAnnotation(AfterTest.class) != null) {
afterlist.add(m);
} else {
// 3个注解都没有,舍弃不要
}
}
// 1. 先执行标注了beforetest的方法
Collections.sort(beforelist, new Comparator() {
public int compare(Method m1, Method m2) {
int p1 = m1.getAnnotation(BeforeTest.class).priority();
int p2 = m1.getAnnotation(BeforeTest.class).priority();
return p2 - p1;
}
});
for (Method m : beforelist) {
BeforeTest before = m.getAnnotation(BeforeTest.class);
if (before != null) {
// 实现循环
for (int i = 0; i < before.loop(); i++) {
m.invoke(obj);
}
}
}
// 2. 先执行标注了test的方法
Collections.sort(testlist, new Comparator() {
public int compare(Method m1, Method m2) {
int p1 = m1.getAnnotation(Test.class).priority();
int p2 = m1.getAnnotation(Test.class).priority();
return p2 - p1;
}
});
for (Method m : testlist) {
Test test = m.getAnnotation(Test.class);
if (test != null) {
// 实现循环
for (int i = 0; i < test.loop(); i++) {
m.invoke(obj);
}
}
}
// 3. 先执行标注了after的方法
Collections.sort(afterlist, new Comparator() {
public int compare(Method m1, Method m2) {
int p1 = m1.getAnnotation(AfterTest.class).priority();
int p2 = m1.getAnnotation(AfterTest.class).priority();
return p2 - p1;
}
});
for (Method m : afterlist) {
AfterTest after = m.getAnnotation(AfterTest.class);
if (after != null) {
// 实现循环
for (int i = 0; i < after.loop(); i++) {
m.invoke(obj);
}
}
}
}
}
注解处理器第4版加上日志
package com.guoyasoft.testNG.annotations;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestNGSvc04 {
public static void dealTestNg(Class c) throws Exception {
// 先实例化
Object obj = c.newInstance();
Method[] methods = c.getDeclaredMethods();
List beforelist = new ArrayList();
List testlist = new ArrayList();
List afterlist = new ArrayList();
for (Method m : methods) {
if (m.getAnnotation(BeforeTest.class) != null) {
beforelist.add(m);
} else if (m.getAnnotation(Test.class) != null) {
testlist.add(m);
} else if (m.getAnnotation(AfterTest.class) != null) {
afterlist.add(m);
} else {
// 3个注解都没有,舍弃不要
}
}
// 1. 先执行标注了beforetest的方法
Collections.sort(beforelist, new Comparator() {
public int compare(Method m1, Method m2) {
int p1 = m1.getAnnotation(BeforeTest.class).priority();
int p2 = m1.getAnnotation(BeforeTest.class).priority();
return p2 - p1;
}
});
for (Method m : beforelist) {
BeforeTest before = m.getAnnotation(BeforeTest.class);
if (before != null) {
// 实现循环
for (int i = 0; i < before.loop(); i++) {
m.invoke(obj);
System.out.println(c.getName()+"."+m.getName()+"()");
}
}
}
// 2. 先执行标注了test的方法
Collections.sort(testlist, new Comparator() {
public int compare(Method m1, Method m2) {
int p1 = m1.getAnnotation(Test.class).priority();
int p2 = m1.getAnnotation(Test.class).priority();
return p2 - p1;
}
});
for (Method m : testlist) {
Test test = m.getAnnotation(Test.class);
if (test != null) {
// 实现循环
for (int i = 0; i < test.loop(); i++) {
m.invoke(obj);
System.out.println(c.getName()+"."+m.getName()+"()");
}
}
}
// 3. 先执行标注了after的方法
Collections.sort(afterlist, new Comparator() {
public int compare(Method m1, Method m2) {
int p1 = m1.getAnnotation(AfterTest.class).priority();
int p2 = m1.getAnnotation(AfterTest.class).priority();
return p2 - p1;
}
});
for (Method m : afterlist) {
AfterTest after = m.getAnnotation(AfterTest.class);
if (after != null) {
// 实现循环
for (int i = 0; i < after.loop(); i++) {
m.invoke(obj);
System.out.println(c.getName()+"."+m.getName()+"()");
}
}
}
}
}