JAVA 自定义注解在自动化测试中的使用
在 UI 自动化测试中,相信很多人都喜欢用所谓的 PO 模式,其中的 P,也就是 page 的意思,于是乎,在脚本里,或者在其它的 page 里,会要 new 很多的 page 对象,这样很麻烦,前面我们也讲到了注解的使用,很方便,那么我们可不可以用注解来代替这个 new 的过程呢?只有想不到,没有办不到的,因为 springMVC 就是用了这个方式来 IOC,当然我们也可以直接用 springMVC,但这无异于用牛刀来切豆腐,还不如我们自已实现一下,顺便增加一下对注解的使用的认识,代码如下:
1. 先定义一个 LoadPage 的注解:
1 2 3 4 5 6 7 8 9 10 11 12 | 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. 再来实现一下这个注解:
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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | 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 注解:
1 2 3 4 5 6 7 8 9 10 11 12 | 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 注解
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 | 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 实例化后的对象管理类:
1 2 3 4 5 6 7 8 9 10 | 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. 再来初始化一下实现注解类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 注解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 中添加如下代码:
1 2 3 4 5 6 | if (InitialManger.allInstance.isEmpty()){ InitialAnnotation init = new InitialAnnotation(driver); init.initialAnnotation(); } AutoPage ap = new AutoPage(); ap.setTestAnnotation( this ); |
9. 在 CASE 中这样用即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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