How to test an application when interacting with an API using SoapUI

Many use SoapUI to test both the API itself and applications accessing the API. Quite a flexible tool, allowing, for example, to export swagger API file and generate Mock-service based on it.
 
 
Not so long ago, in our company, I was faced with a similar task, but with non-trivial conditions. Initial dаta: it is necessary to test the server application, which receives a task as input, calls the API during execution, each subsequent request depends on the API response. The logic is embedded in the application. That is a kind of black box, where you need to test a lot of exits from a script, when there is only one entrance to a script.
 
 
3r314.
 
 
Below, I offer an example of a solution that made it possible to simply integrate it into the regression infrastructure, as well as having a margin to scale in the event of an increase in the range of scenarios and their complexity.
 
 
To start, create a Mock-service in SoapUI. This is done in a few clicks: 3r3r6206.  
 
How to test an application when interacting with an API using SoapUI
 
 
We now turn to creating stubs for requests. Since the task in the script is one, we have the options: 3r3206.  
 
3r3338.  
use the script identifier and transmit it in each request, and in each stub determine the response depending on this identifier;
 
specify in advance the list of answers for each stub and store them in global variables before running the test.
 
 
The first option can be used in the case when it is necessary to receive a response from the stub simultaneously for several requests. The implementation requires the client application's ability to pass a specific identifier in each request to the API. In our case it was almost impossible, and simultaneous testing of several scenarios was not required, so the second option was chosen.
 
 
So, to assign a list of stub answers, perform the following request before running the test:
 
 
3r3186. 3r3187. Post: http: //mockserver: 8080 /setscenario
Body: ScenarioId = 0 & Authentication = 200_OK & AutoSystemHome = 400_TokenIsMissing
3r3196. 3r3197.
 
In the Mock-service, add the “SetScenario” request. It has only two answers: “200_OK” in the case of correct processing of an incoming request, and “400_BadRequest” if the request was incorrectly made: 3r3206.  
 

 
 
In the script, we distribute the response values ​​for each stub into global variables:
 
 
3r3186. 3r3187. def reqBody = mockRequest.getRequestContent () //read the request body
def reqBodyParams =[:]
reqBody.tokenize ("&"). each //collect the input parameters passed in the
request. {
param->
def keyAndValue = param.split ("=")
reqBodyParams[keyAndValue[0]]= keyAndValue[1]
}
if (reqBodyParams.containsKey ('ScenarioId')) //script ID as a required parameter (necessary to simplify the analysis of logs); here you can add checks for other required parameters for the query
{
//assign global variables in which we will store the transmitted response values ​​for the stubs, “?:” means what default value will be assigned in the absence of the transmitted: 3r321313. context.mockService.setPropertyValue ("ScenarioId", reqBodyParams["ScenarioId"]?: "0")
context.mockService.setPropertyValue ("Authentication", reqBodyParams["Authentication"]?: "200_OK")
context.mockService.setPropertyValue ("AutoSystemHome", reqBodyParams["AutoSystemHome"]?: "200_OK")
//and so on for each method
return "200_OK"
}
else
{
return "400_BadRequest"
}
3r3196. 3r3197.
 
The assigned variables can be seen in the service settings window: 3r3206.  
 
3r31-10.
 
 
Thus, we describe all the logic of the Mock-service in this method, and in the stubs for the API methods, it is enough to write a script that reads the value of the response from the global variable: 3r3206.  
 
3r3119.
 
 
3r3186. 3r3187. Authentication = context.mockService.getPropertyValue ("Authentication")
Return "$ {Authentication}"
3r3196. 3r3197.
 
3r33132.
 
 
3r3186. 3r3187. AutoSystemHome = context.mockService.getPropertyValue ("AutoSystemHome")
return "$ {AutoSystemHome}"
3r3196. 3r3197.
 
If you need to add timeout scripts, delays in responses, then add the delay variable, for example: 3r3206.  
 
3r3186. 3r33150. Post: http: //mockserver: 8080 /setscenario
Body: ScenarioId = 0 & Delay = 600 & Authentication = 200_OK & AutoSystemHome = 400_TokenIsMissing
3r3196. 3r3197.
 
And in the script stub add:
 
 
3r3186. 3r3187.
Authentication = context.mockService.getPropertyValue ("Authentication")
Delay = context.mockService.getPropertyValue ("Delay"). ToInteger ()
sleep (Delay)
Return "$ {Authentication}"
3r3196. 3r3197.
 
If it is necessary to support a repeated request, then we transfer the list of answers:
 
 
3r3186. 3r3187. Body: Authentication: 400_MissingParametersClientId; 400_MissingParametersClientId; 200_OK 3r3197.
 
And in the processing script we add tokenize and delete the already sent response, in case it is not the last:
 
 
3r3186. 3r3187. 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)
}
3r3196. 3r3197.
 
As a result, we got a simple Mock-service, which is easy to move between test benches and environments, because the project file is an xml file. The service starts immediately after importing, without additional settings (except for changing the server address and port, of course). At the moment, he helps us to test the application regardless of the stability of the API server and possible time periods of its inaccessibility.
 
 
What we plan to add: integrate this solution to test applications before and during the development of the API itself. For example, when its description is already ready as a swagger-file, but the server is in the process of configuration. The development cycles of the API and client applications do not always coincide. At this point, it is useful to test the client application under development, and the Mock service can help a lot.
 
 
UPD: if you have questions and useful comments.
+ 0 -

Add comment