I have a REST API project in SOAP UI which contains 20 test cases in a test suite. I want to add some header value and sslkeystore in every test step. Here is my code.
import com.eviware.soapui.support.types.StringToStringMap
testCaseList = testSuite.getTestCases()
testCaseList.each
{
testCase = testSuite.getTestCaseByName(it.key)
restTestSteps = testCase.getTestStepsOfType(com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep)//only RestTestRequest steps
restTestSteps.each
{
it.getRestRequest().setHttpHeader("TEST2")
it.testRequest.setSslKeystore("**************")
}
}
Above code "TEST2" contains the header value that I want to add to every test cases. I have configured TEST2 in ws-security configuration under outgoing ws-security configuration.
But in above code I am getting following error:
groovy.lang.MissingMethodException: No signature of method: com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep.getRestRequest() is applicable for argument types: () values: [] Possible solutions: getTestRequest(), getHttpRequest()
Anybody help me please how can I add header value in every test steps.
If you want to set the header values for each step in a test case, you can create a groovy test step that will do this. Place the groovy step at the beginning of the test case and it will work even if you change or add new steps. I'm sure you could tweak the getAllHttpSteps to include all test cases in the suite as well, and place this as the first test run.
/**
* This script populates all http requests in a test case with headers:
*/
import com.eviware.soapui.support.types.StringToStringMap
// make a list of all http rest requests
getAllHttpSteps=testRunner.testCase.getTestStepsOfType(com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep)
// iterate through the list of requests and populate the request headers
for (step in getAllHttpSteps)
{
def headers = new StringToStringMap()
headers.put("SomeHeader", "SomeHeaderValue")
headers.put("sslKeystore", "keystoreValue")
}
If you want to add header value and sslkeystore in every test step, then add these values as Properties OR Custom Properties in Project. Then assign these values in each step. Are you willing to do this with groovy script?
Related
We have a FastApi application that is hosted behind a reverse proxy.
The proxy authenticates the user using Kerberos and adds a X-Remote-User HTTP header to the request.
This header is required by the FastApi application. Here is an example route:
#app.get("/user/me")
async def get_user_me(x_remote_user: str = Header(...)):
return {"User": x_remote_user}
The X-Remote-User header is required for the request which is expected behavior.
When we now open the Swagger Ui, the header is documented and when clicking on "Try it out", we can provide the header value.
This behavior is great for development, but in all other cases it is undesired, because that header is provided by the reverse proxy. For instance, we generate clients using OpenAPI Generator and the clients then all require the X-Remote-User parameter in their requests.
Hence, it would be useful to have a configuration that distinguishes between the environments. If we are behind a reverse proxy, then the generated OpenAPI Schema by FastApi should not include the X-Remote-Header, otherwise if we are in development, it should be included.
What I did so far:
I checked the documentation about security and also some source code of these modules, but I was not able to find a solution.
In the documentation, I read the section Behind a Proxy, but nothing there points me to a potential solution.
I also read about Middleware, but again, no solution.
We could change the generated OpenApi schema. I sketched this in my answer below, but this is not a very elegant solution
Does anyone have a good solution to this problem?
We can use APIKeyHeader to remove the X-Remote-User header from the API signature, but still enforcing the header to be present.
from fastapi.security import APIKeyHeader
apiKey = APIKeyHeader(name="X-Remote-User")
#app.get("/user/me")
async def get_user_me(x_remote_user: str = Depends(apiKey)):
return {"User": x_remote_user}
When the header is not present, we get a "403 Forbidden". If it is present, we retrieve the header value.
The Swagger UI now has a button "Authorize" where we can fill-in the value of the X-Remote-User for testing purposes.
One approach is to generate the OpenApi schema as described in the documentation Extending OpenAPI. After the generation, remove the X-Remote-User from the schema. In the configuration could be a flag that the application it is behind a reverse proxy to execute the code conditionally:
from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi
from MyConfig import Config
app = FastAPI()
#app.get("/items/")
async def read_items():
return [{"name": "Foo"}]
if Config.reverse_proxy:
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title="Custom title",
version="2.5.0",
description="This is a very custom OpenAPI schema",
routes=app.routes,
)
// remove X-Remote-User here
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi
However this is not a very elegant solution, as we need to parse the Json string and remove the different deeply-nested occurrences of the X-Remote-User header everywhere. This is prone to bugs resulting in an invalid schema. Furthermore it could break if new Rest endpoints are added.
A new param will be soon available for Header, Query and other to exclude elements from the openAPI output: include_in_schema=False
Example:
def test(x_forwarded_for: str = Header(None, include_in_schema=False)):
...
Here the patch state: https://github.com/tiangolo/fastapi/pull/3144
For my project
I have created test cases in SOAPUI for Rest project.
I have to pass token in header for each test steps that I have added in the test cases.
Also the token validity only for 1 hour. So every hour I have to enter the token in the headers.
I want to know is there any way automate this token entry and generation dynamically ?
For now what I am doing is getting token every time by refreshing the URL in every 1 hour and putting it manually in header of every test case and test steps.
You could use something like the following Groovy script as the first test step of your test case. This gets your authorisation token from whatever service you use and sets it in your request header:
def authorisationToken = // Retrieve a new token from your authorisation service
// Get the headers for the request
def restRequest = testRunner.testCase.getTestStepByName('REST request')
def headers = restRequest.httpRequest.requestHeaders
// Set the token as a header. Remove it first in case it already exists
headers.remove("Authorisation") // Or whatever your header is called
headers.put("Authorisation", authorisationToken)
restRequest.httpRequest.requestHeaders = headers
If you need to, you could also create a custom property at, say, the test suite level, then set this property after you retrieve it:
testRunner.testCase.testSuite.project.setPropertyValue("Authorization", authorisationToken)
Then, you could use it anywhere you need with ${#TestSuite#authorisationToken}
I'm newbie to soap and soapui, I'm trying to create a test case in which I will send the same request(XML attachment) many times(about 500), the problem is that each time I need to increment/change a value in the request (the id).
Therefore, I wonder if the is a way to pass this parameter to the attached xml file ? or if there is another ways to do the test case.
Thank you in advance
UPDATE
here is the content of the xml file :
<mod:sendMSG xmlns:mod="http://test.soap/service/model">
<id>${#Project#parameter1}</id>
<date>2016-04-03T04:03:00</date>
<infos>
<firstName>AT </firstName>
<lastName>AT </lastName>
......
</infos>
</mod:sendMSG>
which is included in the soap request, ass shown in the following image :
Test steps:
Groovy Script
SOAP Request (disabled)
I disabled the SOAP Request because it runs once more after the script has already looped the request x times.
Groovy script:
int loops = 500;
for ( iter in 1..loops ) {
//Overwrite the 'parameter1' property at project level
testRunner.testCase.testSuite.project.setPropertyValue("parameter1", iter.toString())
//log.info("iter: " + testRunner.testCase.testSuite.project.getPropertyValue("parameter1"));
// Run the teststep named 'SOAP Request'
def testStep = testRunner.testCase.testSteps['SOAP Request'];
testStep.run( testRunner, context )
}
Now you should be able to run your TestCase. I recommend saving your project before, I had some problems with SoapUI crashing on me when running.
I'm trying to run a REST project and have inserted securitytoken and session into my header.
But I get an errormessage telling me that a cookie is missing (since my service needs a cookie to run successful).
I have tried to do this with Groovy:
import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport
def myCookieStore = HttpClientSupport.getHttpClient().getCookieStore()
import org.apache.http.impl.cookie.BasicClientCookie
def myNewCookie = new BasicClientCookie("mycookiename", "mycookievalue")
myNewCookie.version = 1
myNewCookie.domain = "my domain as IP"
myCookieStore.addCookie(myNewCookie)
But its still throwing me the same errormessage.
Are there any solution to inject a cookie as a header in SoapUI 5.0?
I would have like to add this as a comment, but I don't have 50 reputation yet.
Don't know if you are still working on this, but anyway:
Like Rao says it seems like you want to work in a session with a negotiated token. You can go three ways with this in soapui.
Like you propose: create the cookie and the values from scratch. That would be a good use case when you want to test which values are going to pass and which values or combos thereof will return errors or different kinds of messages.
If you want to test anything else then the headers, then you can load a certificate, go to the authentication link and retrieve your tokens and session IDs from the headers in the Set-Cookies as proposed by Rao.
Option number three, my personal favourite when testing other things than headers, is to trust SoapUI to take care of it. You can do this by setting the test case to remember your session. You can set this setting in the testcase settings menu. It is called something the likes of 'Maintain http session'.
Remark: In soapui you can modularize tests. You could for example make a testcase for the authentication in an 'util' test suite. This because you can then disable the util test suite to prevent it from running as a dead-weight test. You can then call to this testcase anywhere to invoke the authentication procedure. For this to work you have to set the settings for the 'Run Testcase' (it is named somehting like that) to 'transport the http session to and from this test case' and, like before, set the parent testcase to 'Maintain HTTP Session'. More info on modularization: https://www.soapui.org/functional-testing/modularizing-your-tests.html.
For the security certificate import, check this smartbear example: https://www.soapui.org/resources/blog/ws-security-settings.html
I'm creating a test case for a REST API in soapUI 4.5 where I'm going to use the content from step X to make a new call in step Y.
Ideally I'd create the REST request with some parameters, say A and B, and say that these parameters should be used in the URL:
http://myapi.com/v1/stuff/A/B
Then I'd do a property transfer step and simply set values extracted from step X into A and B.
It looks as if soapUI only lets me create querystring parameters, like this:
http://myapi.com/v1/stuff?ParamA=A&ParamB=B
This works of course, but I'd like to be able to call it both ways, to verify they're both working.
Am I missing something?
I am not a soapui expert by any means, but have just worked through a very similar scenario, so this might help you out.
Part 1: Create a paramatized resource
In my service, I have a resource called stuff:
http://{host}/stuff
I create a child resource with the below values:
Resource Name: Get stuff by ID
Resource Path/Endpoint: {stuffId}
and before clicking ok, click Extract Params - this will populate the Parameters table with an entry like:
Name | Default value | Style | Location
stuffId | stuffId | TEMPLATE | RESOURCE
then click ok. You now have a resource that allows you to dynamically supply an id:
http://{host}/stuff/{id}
you would need to repeat this to create the B parameter above (or you could create A and B as two parameters to the single resource if you never call /stuff/A without also supplying B).
Part 2: Create the test case
Now in the test case, you need to retrieve A, transfer the property, and then send a request to the above resource using the property:
In the test case, create the request to retrieve the response containing A
Right click the testcase and add a Properties step. Add a property to store the value of A.
From the response in the Outline view, right click the value of A and select "Transfer to > Property", select the property you just created and hit ok
Create a new request, using the new paramatized resource created in the first part. In the place of the id, put a reference to the property which is holding the value of A in this format:
${propertyName}
I might have done something wrong, but my test initially fails on the property transfer with "Missing source property". In the Source are of the PropertyTransfer step, I needed to set the property to ResponseAsXml
Hope this helps!