zoukankan      html  css  js  c++  java
  • 接口测试中Groovy引擎的接入实现!

    接口测试中Groovy可以作为上下游接口参数化传递的前置脚本和后置脚本使用,无缝衔接Java语法,groovy的引入对于动态参数化的设置方便很多。

    其中核心部分就是接入groovy的引擎,下面介绍groovy引擎的实现逻辑。

    • pom文件groovy核心依赖
    
    <dependency>
                <groupId>org.codehaus.groovy</groupId>
                <artifactId>groovy</artifactId>
                <version>3.0.7</version>
            </dependency>
            <dependency>
                <groupId>org.kohsuke</groupId>
                <artifactId>groovy-sandbox</artifactId>
                <version>1.19</version>
            </dependency>
    

    1、Groovy引擎中添加常用的import
    静态代码块中引入

    一些基础的依赖,比如:JSONObject、JSONArray、JsonPath等工具类

    static {
            config = new CompilerConfiguration();
            // 添加默认import
            config.addCompilationCustomizers(new ImportCustomizer().addImports(
                    "com.taltools.script.exception.StepFailureException",
                    "com.jayway.jsonpath.JsonPath",
                    "com.alibaba.fastjson.JSONObject",
                    "com.alibaba.fastjson.JSONArray",
                    "groovy.json.JsonSlurper",
                    "org.apache.commons.codec.digest.DigestUtils",
                    "org.apache.commons.codec.digest.HmacUtils"));
            // 添加线程中断拦截器
            config.addCompilationCustomizers(new ASTTransformationCustomizer(ThreadInterrupt.class));
            // 添加线程中断拦截器,可中断超时线程,当前定义超时时间为30s
            config.addCompilationCustomizers(new ASTTransformationCustomizer(Collections.singletonMap("value", INTERRUPT_TIME_OUT), TimedInterrupt.class));
            // 沙盒环境
            config.addCompilationCustomizers(new SandboxTransformer());
    
            NO_RUNTIME_SANDBOX = new NoRuntimeSandbox();
            NO_SYSTEM_HARM_SANDBOX = new NoSystemHarmSandbox();
        }
    
    • 设置缓存容量&过期时间
    {
            lruCache = CacheBuilder.newBuilder()
                    .maximumSize(1000) //最大容量
                    .expireAfterAccess(12, TimeUnit.HOURS) //缓存过期时长
                    .concurrencyLevel(Runtime.getRuntime().availableProcessors())// 设置并发级别为cpu核心数
                    .build();
        }
    

    2、Groovy核心实现,上下文参数绑定

    • 上下文参数变量名绑定
    @Override
        public ScriptContext runScript(String scriptContent, ScriptContext context) {
            if (scriptContent == null || scriptContent.isEmpty()) {
                throw new IllegalArgumentException("输入的script内容不能为空");
            }
            log.debug("执行Groovy脚本: {}", scriptContent);
            Binding binding = generateBinding(context);
            parseScript(scriptContent, binding).run();
            ScriptContext retContext = new ScriptContext();
            retContext.setVariables(binding.getVariables());
            return retContext;
        }
    
        public long getCacheCount() {
            return lruCache.size();
        }
    
        protected Script parseScript(String scriptContent, Binding binding) {
            String md5 = DigestUtils.md5Hex(scriptContent);
            String sha1 = DigestUtils.sha1Hex(scriptContent);
            String key = md5 + "-" + sha1;
            Class<? extends Script> scriptClass = lruCache.getIfPresent(key);
            if (scriptClass == null) {
                registerSandbox();
                GroovyShell shell = new GroovyShell(config);
                Script script = shell.parse(scriptContent);
                scriptClass = script.getClass();
                lruCache.put(key, scriptClass);
                log.debug("未命中脚本LRU缓存,创建脚步对象并存入缓存,当前缓存数量: {}", getCacheCount());
            } else {
                log.debug("命中脚本LRU缓存, key: {}, 当前缓存数量: {}", key, getCacheCount());
            }
            return InvokerHelper.createScript(scriptClass, binding);
        }
    

    3、调佣Groovy引擎设置参数名测试

    • 在单元测试中测试接受groovy脚本的返回值
    @Test
        public void testGroovy(){
            String req = "    outParams['name'] = testGroovy();\n" +
                    "    static String testGroovy(){\n" +
                    "        def name = 'java'\n" +
                    "        def greeting = \"Hello ${name}\"\n" +
                    "        return greeting\n" +
                    "    }";
            GroovyEngine engine = new GroovyEngine();
            ScriptContext context = new ScriptContext();
            LinkedHashMap<String, Object> outParams = new LinkedHashMap<>();
            context.setVariable("outParams",outParams);
            ScriptContext ret = engine.runScript(req,context);
            System.out.println(JsonUtils.obj2json(ret));
            System.out.println(outParams);
    
        }
    
    • 控制台打印结果


    更多测试技术分享、学习资源以及一些其他福利可关注公众号:【Coding测试】获取:

    记录工作中使用的CI/CD流程
  • 相关阅读:
    (转)深入理解C语言指针的奥秘
    (转)C语言在哪里?
    [转]12个摄影基本法则
    光圈使用
    ArcIMS 连接器.NET Link 使用方法
    在asp.net中使用xml文件的两种类型及用法
    利用XSL双向转换XML文档
    光圈 暴光 快门对比
    保护眼睛的电脑颜色设置
    vb.net2005动态添加网页控件的事件
  • 原文地址:https://www.cnblogs.com/CodingTest/p/15566016.html
Copyright © 2011-2022 走看看