使用SoapUI与API交互时如何测试应用程序

许多人使用SoapUI来测试API本身和访问API的应用程序。 一个相当灵活的工具,例如,它可以导出一个庞大的API文件并基于该文件生成模拟服务。

不久前,在我们公司中,我遇到了类似的问题,但条件不平凡。 初始数据:必须测试接收任务作为输入的服务器应用程序;在执行期间,它引用API;每个后续请求均取决于API响应。 逻辑嵌入在应用程序中。 也就是说,一种黑匣子,当脚本只有一个入口时,您需要在其中测试许多出口。

图片

下面,我提出一个解决方案的示例,在增加场景范围及其复杂性的情况下,可以轻松地将其集成到回归基础结构中,并具有扩展的余量。

首先,在SoapUI中创建一个模拟服务。 只需单击几下即可完成:

图片

现在让我们继续创建查询存根。 由于任务中的脚本只有一个条目,因此我们有以下选择:

  1. 使用脚本的标识符并在每个请求中传递它,并在每个存根中根据此标识符确定响应;
  2. 预先指定每个存根的答案列表,并将其存储在全局变量中,然后再运行测试。

当需要同时从存根接收多个请求的响应时,可以使用第一个选项。 该实现要求客户端应用程序能够在每个API请求中传输特定的标识符。 在我们的情况下,这几乎是不可能的,并且不需要同时测试多个场景,因此选择了第二个选项。

因此,要分配存根响应列表,我们在运行测试之前执行以下查询:

Post: http://mockserver:8080/setscenario Body: ScenarioId=0&Authentication=200_OK&AutoSystemHome=400_TokenIsMissing… 

在Mock服务中,我们添加了请求处理“ SetScenario”。 它只有两个答案:如果正确处理了传入请求,则为“ 200_OK”,如果请求处理不正确,则为“ 400_BadRequest”:

图片

在脚本中,我们为每个存根分配全局存根的响应值:

 def reqBody = mockRequest.getRequestContent() //   def reqBodyParams = [:] reqBody.tokenize("&").each //  ,    { param-> def keyAndValue = param.split("=") reqBodyParams[keyAndValue[0]]=keyAndValue[1] } if (reqBodyParams.containsKey('ScenarioId')) // ID     (    );            { //   ,         , “?:” –          : context.mockService.setPropertyValue("ScenarioId", reqBodyParams["ScenarioId"] ?: "0") context.mockService.setPropertyValue("Authentication", reqBodyParams["Authentication"] ?: "200_OK") context.mockService.setPropertyValue("AutoSystemHome", reqBodyParams["AutoSystemHome"] ?: "200_OK") //       … return "200_OK" } else { return "400_BadRequest" } 

可以在服务设置窗口中看到分配的变量:

图片

因此,我们在此方法中描述了Mock服务的整个逻辑,并在API方法的存根中编写了一个脚本,该脚本从全局变量中读取响应值:

图片

 Authentication = context.mockService.getPropertyValue("Authentication") return "${Authentication}" 

图片

 AutoSystemHome = context.mockService.getPropertyValue("AutoSystemHome") return "${AutoSystemHome}" 

如果您需要添加超时脚本,延迟响应,然后添加延迟变量,例如:

 Post: http://mockserver:8080/setscenario Body: ScenarioId=0&Delay=600&Authentication=200_OK &AutoSystemHome=400_TokenIsMissing… 

然后在存根脚本中添加:

 … Authentication = context.mockService.getPropertyValue("Authentication") Delay = context.mockService.getPropertyValue("Delay").toInteger() sleep(Delay) return "${Authentication}" 

如果有必要支持重复的请求,那么我们将转移答案列表:

 Body: Authentication:400_MissingParametersClientId;400_MissingParametersClientId;200_OK 

在处理脚本中,添加标记化并删除已经发送的响应(如果不是最后一个响应):

 def Authentication = [] Authentication = context.mockService.getPropertyValue("Authentication").tokenize("%3B") if (Authentication.size() > 1) { Authentication.remove(0) Authentication = Authentication.join("%3B") context.mockService.setPropertyValue("Authentication", Authentication) } 

结果,我们获得了一个简单的Mock服务,该服务易于在测试平台和环境之间移动,因为项目文件是xml文件。 该服务在导入后立即启动,没有其他设置(当然,除了更改服务器地址和端口外)。 目前,它可以帮助我们测试应用程序,而无需考虑IPA服务器的稳定性以及其不可访问性的可能时间段。

我们计划添加的内容:在开发API本身之前和之中,集成此解决方案以测试应用程序。 例如,当已经以swagger文件的形式对其进行了描述时,但是服务器正在设置中。 API和客户端应用程序的开发周期并不总是一致的。 此时,测试正在开发的客户端应用程序是否有用是非常有用的,并且Mock服务可以提供很多帮助。

UPD:如果您有任何疑问和有用的意见。

Source: https://habr.com/ru/post/zh-CN429396/


All Articles