
前面我寫了關(guān)于Java注解和反射的文章:
測試開發(fā)必須掌握的知識(shí)點(diǎn):Spring的核心知識(shí)點(diǎn) -Java反射
測試開發(fā)必須掌握的重要知識(shí)點(diǎn)-Spring的核心知識(shí)點(diǎn) -Java注解@
大家可能會(huì)問,這些高級(jí)的知識(shí)點(diǎn)在實(shí)際工作中有哪些應(yīng)用呢?在這里我們來結(jié)合java注解和反射的知識(shí)做一個(gè)實(shí)際案例的編寫,讓大家對(duì)其有更深刻的理解!直接上實(shí)例!
實(shí)例需求
需求:模擬Junit4中的用例結(jié)構(gòu),自定義一個(gè)標(biāo)簽作為測試用例的標(biāo)識(shí)。
在Junit4中注解@Test表示測試用例,每一個(gè)測試用例的本質(zhì)就是測試類中的一個(gè)方法,即:
@Test
public void test() {
fail("Not yet implemented");
}
具體要求:
測試類是默認(rèn)構(gòu)造方法
通過標(biāo)簽MyTag作為方法是否為用例的標(biāo)識(shí)
作為用例的方法必須是無參的
寫一個(gè)方法runCase(String pkgName),使其能夠完成對(duì)指定類中測試用例的調(diào)用工作
注解設(shè)計(jì)
首先需要定義一個(gè)注解MyTag,代碼如下:
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyTag{
String name();
}
測試用例設(shè)計(jì)
模擬junit4框架,寫一個(gè)測試類,其中l(wèi)ogin、info、logout是無參方法,而test是有參方法
public class TestTag{
@MyTag(name="case1")
public void login(){
System.out.println("login");
}
@MyTag(name="case2")
public void info(){
System.out.println("info");
}
@MyTag(name="case3")
public void logout(){
System.out.println("logout");
}
@MyTag(name="case4")
public void test(String p){
System.out.println("logout");
}
}
運(yùn)行類的設(shè)計(jì)思路
因?yàn)闇y試類是默認(rèn)構(gòu)造方法,所以使用如下API,完成類實(shí)例化
Class<?> clazz = Class.forName(pkgName)
Object obj = clazz.newInstance();
因?yàn)闇y試類中有很多方法,我們需要獲取所有的方法并按照規(guī)則進(jìn)行過濾,代碼如下:
Method[]?methods?=?clazz.getMethods();
for (Method method : methods) {
//過濾規(guī)則
}
判斷方法的標(biāo)簽是否為MyTag,代碼如下:
If(method.getAnnotation(MyTag.class) != null)
判斷方法是否沒有參數(shù),代碼如下:
If(method.getParameterCount()==0)
運(yùn)行方法,代碼如下:
method.invoke(obj)
完整代碼
public static void runCase(String pkgName) throws IllegalAccessException,IllegalArgumentException, InvocationTargetException, InstantiationException,ClassNotFoundException {
Class<?> clazz = Class.forName(pkgName);
Object obj = clazz.newInstance();
Method[] methods = clazz.getMethods();
for (Method method : methods) {
?????? if(method.getAnnotation(MyTag.class) != null&& method.getParameterCount()==0) {?????????????????
????????????? method.invoke(obj);?//調(diào)用方法
????????????? System.out.println("測試用例名稱是:"+method.getName());
}
}
}
運(yùn)行代碼,輸出如下:
logout
測試用例名稱是:logout
login
測試用例名稱是:login
info
測試用例名稱是:info
這個(gè)就是一個(gè)模擬Junit4執(zhí)行用例的demo,當(dāng)我們隨意添加TestTag 中的測試用例時(shí),執(zhí)行runCase方法,都能夠成功執(zhí)行測試用例。相信通過這個(gè)例子大家一定會(huì)注解,和反射的概念有了更為深刻的理解!我們的實(shí)例目前只支持對(duì)于指定某一個(gè)類中的測試方法進(jìn)行調(diào)用,大家可以考慮如何實(shí)現(xiàn)對(duì)于某一個(gè)包下所有類的測試用例都可以進(jìn)行調(diào)用呢?