soapui 自动化教程(四)

article/2025/10/19 18:30:13

上一节介绍到了使用groovy实现接口自动化测试的基本功能。
本节将介绍groovy执行用例动态参数、参数回传、参数加密、soapui引入第三方jar包、生成随机参数(绕过业务逻辑中的一些唯一校验阻碍自动化),以适应更真实、复杂的场景。

soapui引入第三方jar包

现在JAVA的优势在于JVM平台和累积起来的丰富的第三方资源了,这也是groovy类JVM语言的优势。
将第三方jar包拷贝只<soapui安装目录>/bin/ext 目录下即可。
然后代码中使用import引入:例import customer.RSAUtils

加密

本例使用RSA加密,groovy需要使用java的第三方包,从网上找了个工具类打包到custom.jar,拷贝到soapui扩展目录。

1.生成公私密钥到d盘RSAUtils.generateKeyPair('d:/')
2.文本编辑器打开生成的publicKey.keystore文件,将三行合并成一行用\n分隔。例:

PUBLIC_KEY_BASE64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCC4d0q2qR7G21TmObv5l0fxpMHcD34pqCjJoIl\nvU/Oa+0rsNkkZljvQAenY8ZNpOPzcfUL/F+qwTpuJh5ny6zl9gPloQRd6PcWob1Z+cuSoEAwBZx4\n+Yw/2QAARjxs5e8GeF0IdY/HK/HmpTCKbmKbUxNaftmeRwfgaG/TGZ93CwIDAQAB"

3.修改任务文件,对账号密码进行加密。

{"comment": "登录接口 status=1 登录成功。reqName格式为:TestCaseName-TestStepName;expect为期望值;extParams的属性可以动态设置值并覆盖用例的默认参数","reqName": "TestSuite-login","extParams": {"account": "rsaEncrypt{lj745280746}","password": "rsaEncrypt{123456}"},"expect": {"status": "1"}
}

4.修改代码。任务文件新增了rsaEncrypt{<content>}语法,需要在代码中解析。

//新增方法----------------------------
//rsa 加密内容
def rsaEncrypt(value) {return RSAUtils.encrypt(RSAUtils.getPublicKey(PUBLIC_KEY_BASE64), value)
}
//添加扩展参数
def addExtParams(params, testStep) {if (!params || params.size() == 0) returnparams.each {k, v ->testStep.setPropertyValue(k, interpreter(v))}
}
//解析替换字符串中的自定义语法
def interpreter(v) {def rsaParamPattern = ~/rsaEncrypt\{\s*(.*?)\s*\}/def rs = vdef sb = new StringBuffer() //rsa加密 替换  例:"rsaEncrypt{18600000000}"def mR = rsaParamPattern.matcher(rs)sb.delete(0, sb.length())while(mR.find()) {mR.appendReplacement(sb, rsaEncrypt(mR.group(1)))}mR.appendTail(sb)rs = sb.toString()
}
//······
//执行任务发送请求前覆盖默认参数
({ //加载任务def taskFile = new File(CURRENT_TESTCASE.properties.task_file.value)def tasks = JSON.parseText(taskFile.getText()) //执行任务tasks.each {def caseName = it.reqName.split("-")[0]def stepName = it.reqName.split("-")[1]def testStep = TEST_SUITE.getTestCaseByName(caseName).getTestStepByName(stepName) //发送请求前覆盖默认参数addExtParams(it.extParams, testStep)def testStepContext = new WsdlTestRunContext(testStep)def result = testStep.run(testRunner, testStepContext)log.info "【${caseName}-${stepName} result data】" + result.responseContentdef rsJson = JSON.parseText(result.responseContent)if (verifyExcept(rsJson, it.expect)) {log.info "【${it.reqName}】success!"assert true} else {log.error "【${it.reqName}】fail!"assert false}}
}())

后台查看请求数据,已经过加密:
这里写图片描述

参数回传

常有一些场景,接口B接收的参数依赖接口A返回的数据。典型的如打开一个创建页面调用A接口生成唯一的单号No,录入信息后调用B接口保存数据。此时No是动态的,必须临时存起来。
本教程举例:testA接口依赖login接口返回的token。修改任务文件,新增cache属性,表示从返回值中获取cache属性中的变量名,临时缓存起来,在后续请求中使用cache{<用例名>-<变量名>} 拿到缓存的值。代码中扩展interpreter函数,使其支持该语法。(此处不贴代码了,在本节结尾提供完整代码。)

生成随机参数

实现该功能是为了解决一些场景会对输入信息做唯一性校验(如手机号),测试数据中如果写死手机号,第一次脚本执行成功,第二次校验接口将返回失败,因为同一个手机在第一次已经存进数据库。
例如testA接口的参数a需要唯一校验,按如下修改,然后扩展interpreter函数,使其支持该语法(查看本节结尾提供完整代码)。


groovy完整代码及任务文件

现在已基本够用了(我够用了…),如上节所说还有些功能未实现,有兴趣请自行扩展。也许还有些bug。。。
后台接口代码、custom.jar、soapui项目文件,点击下载。
以下是groovy完整代码:

import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext
import groovy.json.JsonSlurper
import customer.RSAUtilsJSON = new JsonSlurper()CURRENT_TESTCASE = testRunner.testCase
TEST_SUITE = CURRENT_TESTCASE.parent

//使用JAVA加密 必须导入customer.RSAUtils。customer.jar文件拷贝至目录:<soapui安装目录>\bin\ext 后重启soapui
PUBLIC_KEY_BASE64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCC4d0q2qR7G21TmObv5l0fxpMHcD34pqCjJoIl\nvU/Oa+0rsNkkZljvQAenY8ZNpOPzcfUL/F+qwTpuJh5ny6zl9gPloQRd6PcWob1Z+cuSoEAwBZx4\n+Yw/2QAARjxs5e8GeF0IdY/HK/HmpTCKbmKbUxNaftmeRwfgaG/TGZ93CwIDAQAB"

//缓存 后续需要回传的值
CACHE = [:]

//============================================= UTILS =======================================================
//递归    深度比较返回值与期望是否匹配
def verifyExcept(actual, expect) {def rs = true //类型判断  java Collection 与 Map 不同的遍历方式if (expect instanceof Collection) {expect.eachWithIndex {it, i -> //log.info "i:" + i + "  it:" + itif (it instanceof Map || it instanceof Collection) {return rs = verifyExcept(actual[i], it)} else {def actualValue = actual != null ? actual[i] : nullif (actualValue != it) {log.error "expect: $index:${i}=${it}    actual:${actualValue}"return rs = false}}}} else if (expect instanceof Map) {expect.each {k, v -> //log.info "k:" + k + "  v:" + vif (v instanceof Map || v instanceof Collection) {return rs = verifyExcept(actual[k], v)} else {def actualValue = actual != null ? actual[k] : nullif (actualValue != v) {log.error "expect: ${k}=${v}    actual:${actualValue}"return rs = false}}}} else {log.error "expect is not Object!"rs = false}return rs
}
//rsa 加密内容
def rsaEncrypt(value) {return RSAUtils.encrypt(RSAUtils.getPublicKey(PUBLIC_KEY_BASE64), value)
}
//添加扩展参数
def addExtParams(params, testStep) {if (!params || params.size() == 0) returnparams.each {k, v ->testStep.setPropertyValue(k, interpreter(v))}
}
//解析替换字符串中的自定义语法  正则替换有疑问请查java API
def interpreter(v) {def cachePattern = ~/cache\{\s*(.*?)(\[.+\])*\s*\}/def rsaParamPattern = ~/rsaEncrypt\{\s*(.*?)\s*\}/def randomPattern = ~/random\{\s*(.*?)\s*\}/def rs = vdef sb = new StringBuffer()def mC = cachePattern.matcher(v) //从缓存中取值 替换     例:"cache{login-token}"while(mC.find()) {if (mC.group(2)) { //使用Eval可以获取多层级的属性值 login-abc['a']['b']def tmp = Eval.me('CACHE', CACHE, "CACHE['${mC.group(1)}']${mC.group(2)}")mC.appendReplacement(sb, tmp)} else {mC.appendReplacement(sb, CACHE[mC.group(1)])}}mC.appendTail(sb)rs = sb.toString() //rsa加密 替换  例:"rsaEncrypt{18600000000}"def mR = rsaParamPattern.matcher(rs)sb.delete(0, sb.length())while(mR.find()) {mR.appendReplacement(sb, rsaEncrypt(mR.group(1)))}mR.appendTail(sb)rs = sb.toString() //生成随机数 替换  例:"soapui自动化-random{1000}"def mRd = randomPattern.matcher(rs)sb.delete(0, sb.length())while(mRd.find()) {mRd.appendReplacement(sb, Math.round(Math.random() * Integer.valueOf(mRd.group(1))) + "")}mRd.appendTail(sb)rs = sb.toString()return rs
}
//缓存需要的数据
def cacheData(items, rsData, prefix) {if (!items || items.size() == 0) return //默认在请求返回数据中取值 也可先缓存固定值共后续请求使用,使数据保持一致items.each {if (it instanceof Map) {it.each {k, v ->CACHE["${prefix}-${k}"] = v}} else {CACHE["${prefix}-${it}"] = rsData[it]}}
}
//============================================= RUN =======================================================
({ //加载任务def taskFile = new File(CURRENT_TESTCASE.properties.task_file.value)def tasks = JSON.parseText(taskFile.getText()) //执行任务tasks.each {def caseName = it.reqName.split("-")[0]def stepName = it.reqName.split("-")[1]def testStep = TEST_SUITE.getTestCaseByName(caseName).getTestStepByName(stepName) //发送请求前覆盖默认参数addExtParams(it.extParams, testStep)def testStepContext = new WsdlTestRunContext(testStep)def result = testStep.run(testRunner, testStepContext)log.info "【${caseName}-${stepName} result data】" + result.responseContentdef rsJson = JSON.parseText(result.responseContent)if (verifyExcept(rsJson, it.expect)) {cacheData(it.cache, rsJson, stepName)log.info "【${it.reqName}】success!"assert true} else {log.error "【${it.reqName}】fail!"assert false}}
}())return

任务文件:

[{"comment": "登录接口 status=1 登录成功。reqName格式为:TestCaseName-TestStepName;expect为期望值;extParams的属性可以动态设置值并覆盖用例的默认参数","reqName": "TestSuite-login","cache": ["token"],"extParams": {"account": "rsaEncrypt{lj745280746}","password": "rsaEncrypt{123456}"},"expect": {"status": "1"}
},{"comment": "测试接口A","reqName": "TestSuite-testA","extParams": {"token": "cache{login-token}","a": "test-random{10000}"},"expect": {"data": {"status": "1"}}
},{"comment": "测试接口B。未插入token,status=0","reqName": "TestSuite-testB","expect": {"data": {"status": "0"}}
}]

http://chatgpt.dhexx.cn/article/WXY0PxOO.shtml

相关文章

soapUI 5.7.0使用

soapUI 5.7.0使用 公司有接口是webService的&#xff0c;用的是soap协议类型&#xff0c;这时候使用postman就不好使了&#xff0c;所以这边要使用SoapUI来进行测试&#xff0c;以下是SoapUI的使用流程首先&#xff0c;新建一个SOAP项目 将webService的地址填入其中&#xff0c…

soapui 自动化教程(二)

soapui 之 groovy 基础 本教程需要一些groovy基础&#xff0c;不会也没关系&#xff0c;会任意一门编程语言就能看懂代码。 上一节介绍了soapui如何创建测试用例&#xff0c;本节介绍groovy脚本如何执行测试用例。 新建一个script测试用例存放脚本 新增一个step&#xff…

使用SoapUI测试webservice接口详细步骤

如题所示&#xff0c;当我们写好webservice接口以后&#xff0c;在正式发布使用之前总是需要测试下接口是否好用&#xff0c;使用SoapUI这个软件可以很方便地对我们写的接口进行测试。下面我以SoapUI测试一个SOAP类型的接口来举例说明&#xff1a; &#xff08;1&#xff09;S…

【工具】Soap UI注意事项

【工具】Soap UI注意事项 一. 字体大小调整二. 中文乱码 一. 字体大小调整 1.配置里&#xff1a; File->preferences->editor settings->select font 2.使用兼容性格式&#xff0c;高DPI缩放 效果&#xff1a; 二. 中文乱码 找到bin\SoapUI-5.4.0-EB.vmoptions文…

使用SoapUI 测试Web Service

如何测试写好的Webservice&#xff1f;你当然可以写代码来测试&#xff0c;但还是太麻烦&#xff0c;你得花时间去学习各语言的关于Webservice调用的相关API。这里推荐一个Webservice开发的必备工具- SoapUI&#xff0c;无须了解底层细节&#xff0c;就能快速测试你的Webservic…

SoapUI基础使用教程

目录 一、HTTP接口调用 1、创建项目 2、输入http请求地址 3、选择对应项目的request&#xff0c;输入信息发送请求 二、Webservice接口调用 2.1先来看soap风格的webservice接口调用的步骤 2.2再来看rest风格调用webservice接口的步骤 三、报文乱码 一、HTTP接口调用 1…

SoapUI安装教程【Windows】

Installing SoapUI on Windows Once you’ve downloaded the installer, the installation is pretty straightforward. Start it by just double-clicking on it. The installer will start immediately. 一旦下载安装程序&#xff0c;安装非常简单。只需双击它即可启动。安装…

SOAP UI 简单使用

1、SOAP UI 简介&#xff1a;主要用于WebService、WCF的调试以及负载性能测试才是。本次简单介绍一下Soap UI的简单使用以及调试。下次在介绍Soap UI的负载性能测试。 2、Soap UI 下载地址 http://sourceforge.net/projects/soapui/files/soapui/ 3、安装完成后进入Soap UI界面…

如何使用SoapUI - Soap测试工具

soapui提供一个工具通过soap/http来检查&#xff0c;调用&#xff0c;实现web service和web service的功能/负载/符合性测试。该工具既可作为一个桌面应用软件使用&#xff0c;也可利用插件集成到Eclipse&#xff0c;maven2.X&#xff0c;netbeans 和intellij中使用 soapUI pr…

Soapui简介

一、工具介绍 soapui提供一个工具通过soap/http来检查&#xff0c;调用&#xff0c;实现web service的功能/负载测试工具。 二、Webservice接口介绍 web service分两大类架构一种是基于soap协议的&#xff08;wsdl结尾的接口&#xff09;&#xff0c;另外一种就是基于restfu…

SoapUI简介和入门实例解析

SoapUI简介 SoapUI是一个开源测试工具&#xff0c;通过soap/http来检查、调用、实现Web Service的功能/负载/符合性测试。该工具既可作为一个单独的测试软件使用&#xff0c;也可利用插件集成到Eclipse&#xff0c;maven2.X&#xff0c;Netbeans 和intellij中使用。 SoapUI是…

SoapUI简易教程-接口模拟

SoapUI简易教程-接口模拟 一、SoapUI 5.4.0版本安装二、SoapUI使用1.知识补充2.SoapUI模拟http接口3.SoapUI模拟WebServices接口4.SoapUI访问WebServices接口 三、常见问题1.SoapUI返回中文乱码2.SCRIPT脚本运行报错 一、SoapUI 5.4.0版本安装 百度网盘下载地址&#xff1a; 链…

SoapUI简易使用

SoapUI简易使用 一、 什么是soapUI二、简单调用接口三、设置断言四、负载测试五、知识点 一、 什么是soapUI 由于 Web 服务是被程序调用的&#xff0c; 一般不会提供界面让最终用户或测试人员直接使用&#xff0c;soapUI是针对这种情况开发的一个工具&#xff0c;用户可以在 s…

soapui 自动化教程(一)

本教程主要讲述对接口的自动化测试&#xff0c;略过压力测试、安全测试。 最终目标是通过groovy脚本执行一个文件&#xff0c;发送多个任务请求。验证返回值是否符合期望。 教程从soapui入门到groovy实现回传参数、生成随机参数、加密隐私数据等&#xff0c;逐步深入&#xf…

soapUI的使用

首先下载soapUI下载地址在网上可以搜的到 windows下载这个soapUI-x32-3_5.exe(中间的数字是版本号&#xff0c;可以下载最新的&#xff0c;这个已经有了JMS的测试功能) 首先得有一个webservice,我自己简单建了一个&#xff0c;用来算两个数的加减 地址为&#xff1a;http://…

soapui的菜鸟教程

一.这里我安装的是5.2.1这个版本&#xff0c;安装之后按照我的操作步骤即可 二.这里放入后台给你的接口&#xff0c;结尾应该是?wsdl 如果没有你需要手动加上&#xff0c;否则会报错 三&#xff1a;这个是成功界面 四&#xff1a;如图&#xff0c;点开之后是这样的&#xff0c…

soapUI简介、安装使用教程、接口(性能)测试

一、soapUI简介 SOAP&#xff1a; WebService通过Http协议发送请求和接收结果时&#xff0c;发送的请求内容和结果内容都采用XML格式封装&#xff0c;并增加了一些特定的HTTP消息头&#xff0c;以说明HTTP消息头的内容格式&#xff0c;这些特定的HTTP消息头和XML内容格式就是SO…

关于soapUi工具的安装使用教程

在测试的工作中&#xff0c;测试的小伙伴们或多或少了解过soapUi这款工具&#xff0c;就实际使用过程中&#xff0c;简单说说这款工具。 1安装和破译 1.1下载 这里下载的是5.1.2pro版 下载路径&#xff1a; http://dl.eviware.com/list_soapui2.html?_ga1.16http://dl.eviwar…

soapUI工具使用方法、简介、接口测试

简单总结一下步骤&#xff1a; 打开SoapUI5.2.1——新建project——右键 project1——选择 add WSDL——WSDL Location输入地址&#xff08;也就是别人给你的接口地址&#xff0c;可以分为测试地址&#xff0c;正式环境地址等&#xff09;——点击OK按钮——弹出测试报文&…

SoapUI 入门指南

一、SoapUI 入门指南 1.1 什么是 SOAP UI 由于实际项目中&#xff0c;大多数 Web 服务通过接口调用实现&#xff0c;一般不会提供界面让最终用户或测试人员直接使用&#xff0c;因此给测试工作带来了麻烦&#xff0c;测试人员不得不自己编写程序来测试&#xff0c;这就是要求测…