• 基于Java+HttpClient+TestNG的接口自动化测试框架(七)------ 测试函数的读取实现


      之前一篇,我们说了一些测试用函数的接口类与实现类,这样相当于我们已经构造了我们想使用的函数。那么,如何让程序知道我们使用的是函数,并调用接口实现类进行处理后将结果放入我们想要的地方呢?

    在这里,我们需要整理一下我们的思路。

      首先,我们可以通过正则表达式来匹配到我们的函数名称。其次,在得知函数名称的情况下,调用对应函数的接口实现类的方法去执行。最后,将值传递回我们需要填入的地方。

      在这里,我们先看看如何使用正则表达式来实现匹配函数名称。(我们使用函数的样式为“__funcName(args)”)("注意:这里是两个下划线(有人已经提醒我了。)")

    protected Pattern funPattern = Pattern
                .compile("__(\w*?)\((([\w\\\/:\.\$]*,?)*)\)");

      可以使用这个正则表达式来匹配【_funcName(args)】的形式。有关正则这里不再详细说明。

      关于正则表达式,这里再推荐一个网站。以便各位学习何使用:https://www.w3cschool.cn/regexp/x9hf1pq9.html

      在知道了函数名称之后,怎样调用对应函数的接口实现类的方法去执行呢?这里我们还是整理一下思路。

    ----->先找到当前项目路径下所有的类,然后过滤获取这个路径下所有子类或接口实现类。通过一个集合,将函数名与测试函数接口对应起来,存入集合。最后,通过调用接口实现类来获取值。

    首先,我们来看一下classFinder的查找类。

    public class classFinder {
    
        static ClassLoader classloader = Thread.currentThread().getContextClassLoader();  
        /** 
         * 获取同一路径下所有子类或接口实现类 
         *  
         * @param intf 
         * @return 
         * @throws IOException 
         * @throws ClassNotFoundException 
         */  
        public static List<Class<?>> getAllAssignedClass(Class<?> cls) {  
            List<Class<?>> classes = new ArrayList<Class<?>>();  
            for (Class<?> c : getClasses(cls)) {  
                if (cls.isAssignableFrom(c) && !cls.equals(c)) {  
                    classes.add(c);  
                }  
            }  
            return classes;  
        }  
      
        /** 
         * 取得当前类路径下的所有类 
         *  
         * @param cls 
         * @return 
         * @throws IOException 
         * @throws ClassNotFoundException 
         */  
        public static List<Class<?>> getClasses(Class<?> cls) {  
            String pk = cls.getPackage().getName();  
            String path = pk.replace('.', '/');  
            try {
                String dirPath = URLDecoder.decode(classloader.getResource(path).getPath(),"utf-8");
                return getClasses(new File(dirPath), pk);
             } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
             }
          return new ArrayList<Class<?>>();
        }  
      
        /** 
         * 迭代查找 
         *  
         * @param dir 
         * @param pk 
         * @return 
         * @throws ClassNotFoundException 
         */  
        private static List<Class<?>> getClasses(File dir, String pk) {  
            List<Class<?>> classes = new ArrayList<Class<?>>();  
            if (!dir.exists()) {  
                return classes;  
            }  
            for (File f : dir.listFiles()) {  
                if (f.isDirectory()) {  
                    classes.addAll(getClasses(f, pk + "." + f.getName()));  
                }  
                String name = f.getName();  
                if (name.endsWith(".class")) {  
                    try{
                    classes.add(Class.forName(pk + "." + name.substring(0, name.length() - 6)));
                    }catch(Exception ex){
                        //TODO console warn
                    }
                }  
            }  
            return classes;  
        }  
    }

           通过上面的查找类,我们可以获取到指定路径下的所有子类和接口实现类。

    public class functionUtil {
    
        private static final Map<String, Class<? extends functionInterface>> functionsMap = new HashMap<String, Class<? extends functionInterface>>();
        static {
            //bodyfile 特殊处理,这个bodyfile主要是应对POST有上传文件的情况。
            functionsMap.put("bodyfile", null);
            List<Class<?>> clazzes = classFinder.getAllAssignedClass(functionInterface.class);
            clazzes.forEach((clazz) -> {
                try {
                    // function
                    functionInterface tempFunc = (functionInterface) clazz.newInstance();
                    String referenceKey = tempFunc.getReferenceKey();
                    if (referenceKey.length() > 0) { // ignore self
                        functionsMap.put(referenceKey, tempFunc.getClass());
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                    //TODO 
                }
            });
        }
        
        public static boolean isFunction(String functionName){
            return functionsMap.containsKey(functionName);
        }
        
        public static String getValue(String functionName,String[] args){
            try {
                return functionsMap.get(functionName).newInstance().execute(args);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return "";
            }
        }
    }

      在这个functionUtil里面我们实现了将找到的接口实现类存入Map,并根据函数名来调用相应的函数执行,并返回执行后的结果。

     

  • 相关阅读:
    java 面向对象(六):类结构 方法(三) java的值传递机制
    java 面向对象(五):类结构 方法(二) 关键字:return;方法的重载;可变个数形参的方法
    java 面向对象(四):类结构 方法(一)
    java 面向对象(三):类结构 属性
    java 面向对象(二):JVM内存结构
    java 面向对象(一):类与对象
    java 基本语法(十三) 数组(六)数组的常见异常
    java 基本语法(十二) 数组(五)Arrays工具类的使用
    java 基本语法(十一) 数组(四)数组的常见算法
    java 基本语法(十) 数组(三) 二维数组
  • 原文地址:https://www.cnblogs.com/generalli2019/p/12221258.html
Copyright © 2020-2023  润新知