一.关于自动测试机
1.什么是自动测试机?
对类中的指定方法进行批量测试的工具
2.自动测试机又什么用?
a.避免了冗长的测试代码
当类中的成员方法很多时,对应的测试代码可能会很长,使用测试能够让测试代码非常简洁
b.降低了类与测试代码之间的耦合性
以防万一,测试时应该对类中所有方法进行测试。当我们对类中的一个方法做改动时,很可能我们的测试代码也要做相应改动(如改变了方法名,返回值类型等等),使用测试机能降低类与测试代码之间的耦合性,大大降低不必要的工作量。
c.增加了测试的灵活性
测试类与待测试类往往是分开的,设置测试参数时可能往往需要查看具体的方法体(寻找边界参数),这样很不方便。使用测试机的话,测试参数就在对应方法声明的位置(给方法添加相应注解),易于灵活修改参数。
3.测试机的原理
利用注解与反射就可以实现测试机了,原理非常简单,之前以为注解就是一种类型,没想过往这方面来应用...具体原理是:
根据待测试方法参数类型声明自定义注解 --> 为方法添加相应的注解 --> 利用反射机制编写测试机代码
二.参考资料
这么犀利的东西当然不是由我提出的,前辈在很久之前就提出了,链接:http://blog.csdn.net/rj042/article/details/6399965
P.S.建议把链接博文与本文一起看,原文介绍了很多相关的基础知识,本文是在其基础上展开的实践
三.实践
1.原文提出了自动测试机的问题:
-------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 |
//定义一个类Methods,要求有三个方法Method1、2、3 //方法的参数、返回值类型均为String类型,返回值为传入的参数 //使用自定义的注解来注释Method1、3,并对属性参数赋值 public class Methods { /** * @param args */ @Annotation ( "Param_1" ) //对Method1进行注解,表示自动测试机会对Method1感兴趣 public
String Method1 (String s) { //do something...like s += "_X" ; return
s; } //不对Method2进行注解,自动测试机将滤去Method2 public
String Method2 (String s) { //do something...like s += "_XX" ; return
s; } @Annotation ( "Param3" ) //同Method1 public
String Method3 (String s) { //do something...like s += "_XXX" ; return
s; } } |
[自定义注解类 Annotation.java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14 |
import java.lang.annotation.*; //定义一个单值注解Annotation,使其可以注解方法,并且可以被保留到程序运行时 //注解的属性类型为String,要求可以使用简写方式为属性赋值 @Target ({ElementType.METHOD}) //声明该注解的作用对象,可以是多个Type值 @Retention
(RetentionPolicy.RUNTIME) //声明该注解可以被保留到程序运行时 public @interface Annotation { //此处定义的value既是属性也是方法,相当于"value", value这样的键值对 String value(); //没有成员的注解叫标记注解 //只有一个成员的注解叫单值注解 //有多个成员的注解叫多值注解 } |
[测试类(自动测试机) TestAnnotation.java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 |
import java.lang.reflect.*; //定义一个测试类TestAnnotation,要求使用反射来测试Methods中所有的被Annotation注解的方法 //并将注解的属性值作为参数,调用相应方法来返回测试结果 public class TestAnnotation { /* * 这就是所谓的自动测试机 * 即用注解给定的值作为待测试方法的参数,对指定类中的所有方法进行批量测试 * 避免了冗长的测试代码 * * */ @SuppressWarnings ( "rawtypes" ) public
static void main(String [] args) throws
InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException { //利用反射机制根据类名获取类的实例,不同于一般的引用 //Class类的对象(实例、引用...)是普通对象的工厂 //也就是说对一个类A而言,A的class对象只有唯一的一个,而A的普通对象a1, a2, a3...可以有很多个 //new A() --> 判断是否存在A的Class对象,不存在则创建之,存在则继续 --> 根据Class对象创建普通对象 Class c = Class.forName( "Methods" ); //利用反射获取类中声明的所有方法 Method [] ms = c.getDeclaredMethods(); System.out.println( "<自动测试机已启动...>\n" ); for
(Method m : ms) { System.out.println( "start{" ); String name = m.getName(); //判断方法是否被注解了指定注解 if (m.isAnnotationPresent(Annotation. class )) { System.out.println( "正在测试 "
+ name + " 方法" ); //获取注解对象 Annotation anno = m.getAnnotation(Annotation. class ); //获取注解的值,因为Annotation是单值注解,直接取值 String s = anno.value(); //获取类的实例 Object obj = c.newInstance(); System.out.println( "传入参数为 "
+ s); //调用m方法 Object returnObj = m.invoke(obj, s); System.out.println( "返回值为 "
+ returnObj); System.out.println(name + " 方法测试完毕" ); } else System.out.println(m.getName() + " 方法没有被注解,测试机跳过该方法" ); System.out.println( "}end\n" ); } System.out.println( "<...自动测试机已关闭>" ); } } |
4.运行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 |
<自动测试机已启动...> start{ 正在测试 Method1 方法 传入参数为 Param_1 返回值为 Param_1_X Method1 方法测试完毕 }end start{ Method2 方法没有被注解,测试机跳过该方法 }end start{ 正在测试 Method3 方法 传入参数为 Param3 返回值为 Param3_XXX Method3 方法测试完毕 }end <...自动测试机已关闭> |
四.总结
例程序中只是为了说明测试机的原理,只能对特定类的特定方法进行测试,不过不用担心。
反射机制被誉为Java最让人兴奋的东西之一,绝对不是吹的。
反射机制允许通过子类来获取父类,并以此展开,最终可以得到清晰的类层次结构。
对多个类进行测试也很简单,我们只需要创建一个类名数组即可,循环什么的,计算机最喜欢做了。
当然,利用[反射 + 注解]来进行自动测试还有一个优点就是可以测试一个类的家族成员,父亲,爷爷...这一点是单纯的测试代码所无法想象的。
Java反射reflection与注解annotation的应用(自动测试机),布布扣,bubuko.com
Java反射reflection与注解annotation的应用(自动测试机)
原文:http://www.cnblogs.com/ayqy/p/3751113.html