• 接口测试中Groovy引擎的接入实现


    在这里插入图片描述
    接口测试中Groovy可以作为上下游接口参数化传递的前置脚本和后置脚本使用,无缝衔接Java语法,groovy的引入可以作为接口测试前后置脚本自由Coding,这样对于一些签名的加密处理、动态参数化等提供一种能力。

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

    pom文件groovy核心依赖

    
                org.codehaus.groovy
                groovy
                3.0.7
            
            
                org.kohsuke
                groovy-sandbox
                1.19
            
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    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();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    设置缓存容量&过期时间

    {
        lruCache = CacheBuilder.newBuilder()
                .maximumSize(1000) //最大容量
                .expireAfterAccess(12, TimeUnit.HOURS) //缓存过期时长
                .concurrencyLevel(Runtime.getRuntime().availableProcessors())// 设置并发级别为cpu核心数
                .build();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    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 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);
        }
    
    • 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

    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 outParams = new LinkedHashMap<>();
            context.setVariable("outParams",outParams);
            ScriptContext ret = engine.runScript(req,context);
            System.out.println(JsonUtils.obj2json(ret));
            System.out.println(outParams);
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    控制台打印结果

    图片

    前端页面效果

    图片

    关于groovy在接口测试平台中的落地后续不断补偿,欢迎关注!

    现在我邀请你进入我们的软件测试学习交流群:746506216】,备注“入群”, 大家可以一起探讨交流软件测试,共同学习软件测试技术、面试等软件测试方方面面,还会有免费直播课,收获更多测试技巧,我们一起进阶Python自动化测试/测试开发,走向高薪之路。

    喜欢软件测试的小伙伴们,如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一 键三连哦!
    在这里插入图片描述

  • 相关阅读:
    C#访问修饰符
    python爬虫实战-京东商品数据
    STM32F103C8T6 + 0.96“ I2C OLED显示3D_Cube
    DocuWare 庆祝文档管理云解决方案推出10 周年
    【Paper】2022_切换拓扑下动态事件触发多智能体系统固定时间一致性
    微信小程序仿苹果负一屏由弱到强的高斯模糊
    Linux 基础篇(CentOS)
    堆排序(算法实现)
    Linux关闭终端保留程序
    《运营商劫持, 中间人攻击, 黑客入侵怎么办?》- HTTPS 技术反制
  • 原文地址:https://blog.csdn.net/wx17343624830/article/details/126869998