pytest: multiple tests were failed if run together but success when run one by one - pytest

I'm testing the endpoint that created via fastApi. The tests that failing are all come from the endpoint that need to query the parameters, please see the example below
BTW: I'm using the TestClient from fastApi
Example 1
def test_fetch_paged_ggci_is_success():
page = 2
page_limit = 15
page_endpoint = "ggci/list?page={}&limit={}".format(page, page_limit)
response = client.get(page_endpoint, headers=headers)
fetched_page = response.json()
assert response.status_code == 200
assert len(fetched_page) == page_limit
Example 2
def test_increase_limits_of_the_paged_ggci_shall_not_influnce_fetch_order():
page = 1
page_limit = 10
page_endpoint = "ggci/list?page={}&limit={}".format(page, page_limit)
page_limit_increased = 15
page_endpoint_limit_increased = "ggci/list?page={}&limit={}".format(page, page_limit_increased)
response = client.get(page_endpoint, headers=headers)
response_limitresponse = client.get(page_endpoint, headers=headers)response = client.get(page_endpoint, headers=headers)_increased = client.get(page_endpoint_limit_increased, headers=headers)
assert response.status_code == 200
assert response_limit_increased.status_code == 200
fetched_page = response.json()
fetched_page_limit_increased = response_limit_increased.json()
assert len(fetched_page) == page_limit
assert len(fetched_page_limit_increased) == page_limit_increased
If running the test like the one above individually, it pass without issue. But when running the test all together only the first one passed.
I think they are interfering each-other. when response = client.get(page_endpoint, headers=headers) is called in each function. A function might picked up other function's page_endpoint .How can I segregate each test to run individually?

Related

Passing same value to multiple tasks in locust

We have a requirement where we need to send a post request and then send a delete request for the same end point(REST API).
Need to generate a unique id for each post request, for each user in each iteration.
generated unique string is put inside on_start() method of task class (SequentialTaskSet).
Problem is, it runs for one iteration, but generates same id for consecutive iterations for each user.
To get unique id for each user in each iteration, generating the unique string within the task itself works, but issue here is, I could not pass the same Id to next task where I need to send delete request.
This is what code looks like now:
class StudentClass(SequentialTaskSet):
rndString = None
def on_start(self):
self.rndString = str(uuid.uuid4())
#task
def postRequest(self):
endpoint = "/students"
headers = {
'Authorization': 'Bearer token',
'content-type': 'application/json', 'accept': 'application/json'
}
data = {
"Id": f'std-{self.rndString}',
}
with self.client.post(endpoint, name="Post request", headers=headers, data=json.dumps(data),
catch_response=True) as response:
........
Appreciate any help in achieving this.
I think if you don't need to call post and delete requests with different weights you can do both calls in same task. Is there something I am missing that requires you to separate tasks for post and delete calls? If yo do need to separate them you can update the self.rndString in post task and it will use the updated one in delete.
#task(1)
def hello_world(self):
response = self.client.get("/listing")
print(response.text)
#task
def fill_crud(self):
response = self.client.post('/api/fill_post/', {"number_1": 76, "number_2": 897, "number_3": 564, "text_4": "Sneha"})
print(response.status_code)
res = json.loads(response.text)
response_id = (res['id'])
response_put = self.client.put(f'/api/fill_post/{response_id}/', {"number_1": 76576, "number_2": 89657, "number_3": 5654, "text_4": "Sneha"})
response_patch = self.client.patch(f'/api/fill_post/{response_id}/', {"text_4": "Suveksha"})
response_delete = self.client.delete(f'/api/fill_post/{response_id}/')
You can try it in this way, I hope it will helps anyone.

Postman setNextRequest and workflow conditional workflow

I am trying to create a conditional workflow using setNextRequest. This workflow should do subsequent API call only when statuscode of current call is 201
My test looks something like this
var returnData = JSON.parse(responseBody);
tests["status code"] = (responseCode.code === 201);
if (responseCode.code == 201) {
postman.setNextRequest('ConfigurationModel-Module');
}
But even when my API response is 409 subsequent API call are triggered in postman runner
Depending on what you're doing you can add an else statement
else
postman.setNextRequest(null);

Fiddler: Cannot set the Response Code in

We are using the Fiddler customRules.js script to handle our API testing (external APIs from other companies when they do not have Test Servers for us) where we send a response file back to the requestor if one is present, otherwise we build the response. This is working fine, but I cannot set the HTTP Status code.
When we generate the response, in some cases we want to be able to specify the HTTP Status to what the external API might send.
static function OnBeforeResponse(oSession: Session) {
if (m_Hide304s && oSession.responseCode == 304) {
oSession["ui-hide"] = "true";
}
// Set Header values for later
var HeaderContentType = 'text/xml;charset=utf-8';
var HeaderServer = 'Apache-Coyote/1.1';
var HttpStatus = 200;
... // This is the removed code that determines text or file to return
// At the end of our process to determine to send a file or error we try to send an error value in this case. For simplicity, I am just hard assigning it without using a variable as we normally would.
oSession.responseCode = 500;
oSession.oResponse.headers.HTTPResponseCode = 500;
oSession.oResponse.headers.HTTPResponseStatus = "500 SERVER ERROR";
oSession.ResponseHeaders.SetStatus(500, 'Server Error'); // This also does not work
// However this does work to add the file contents into the response when the file exists.
var ResponseFile = new ActiveXObject("Scripting.FileSystemObject");
if (ResponseFile.FileExists(ReturnFileName)) {
oSession["x-replywithfile"] = ReturnFileName;
// Error message returned as the ReturnBody was not populated and Response File not found
} else {
oSession.utilSetResponseBody(ErrorMessage);
}
return;
}
Finally tracked it down. The problem is that I am often returning a file when returning an error using the oSession["x-replywithfile"]. However, this always makes the status an 200 OK, even if I try to change the status after the oSession["x-replywithfile"] setting.
oSession["x-replywithfile"] = ReturnFileName;
oSession.responseCode = 500;
This will still always return a 200 OK.
Changing to the following will work.
var FileContents = ReadFile(ReturnFileName);
oSession.utilSetResponseBody(FileContents);
oSession.responseCode = 500;

How to extract REST API Response and status code at one time using Rest Assured

I need to get some fields from the REST API response and the status code as well. I can get only one at a time .
Response res = given().header("Content-Type","application/json").body(json).when().post("/rest/auth/1/session").then().extract().response() ;
Integer stC = given().header("Content-Type","application/json").body(json).when().post("/rest/auth/1/session").then().extract().statusCode() ;
How can I get both in one request?
As expected, I asked a silly question.
This is how we can get everything from Response object
res.statusCode() ;
res.headers();
res.body() ;
You can try this:
Response res =
given().header("ContentType", "application/json").body(json).when().post("/rest/auth/1/session");
int statusCode = res.getStatusCode();

Getting name of previous test step of type Rest Request in SoapUI groovy script

I'm using groovy script to transfer a certain property from the response of a REST request like this:
def setCookie = testRunner.testCase.testSteps["SubmitCompleteDeviceRegistration"].testRequest.response.responseHeaders["Set-Cookie"]
def global = com.eviware.soapui.SoapUI.globalProperties
re = /(SESSION_AUTHENTICATION_TOKEN=[A-Za-z0-9_-]+;)/
matcher = ( setCookie =~ re )
def cookie = matcher[0][0]
global.setPropertyValue("SESSION_AUTHENTICATION_TOKEN","$cookie")
return cookie
Now what I want to do is make the name of the above teststep, "SubmitCompleteDeviceRegistration", variable, so I can use the transfer for various REST-Requests.
The name of this variable TestStep should equal the name of the previous TestStep of the RestRequest type.
How can I go about defining the TestStep that equals this condition?
I'm trying to use something like
def prevGroovyTestStep =
testRunner.testCase.findPreviousStepOfType(testRunner.testCase.getTestStepByName
("SubmitCompleteDeviceRegistration"),RestRequest)
log.info(prevGroovyTestStep.getName())
But I'm not sure how to implement this.
Any help would be really appreciated!
Getting the previous step name
def previousStepName = context.testCase.testStepList[context.currentStepIndex - 1].name
log.info "Previous step name is : ${previousStepName}"
Getting the previous step name if its type is Rest Request
def testStep = context.testCase.testStepList[context.currentStepIndex - 1]
def previousStepName
if (testStep instanceof com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep) {
previousStepName = testStep.name
} else {
log.error "Previous step is not of Rest Request Type"
}
if (previousStepName) {
log.info "Previous step name is : ${previousStepName}"
}
If type does not match in the above case, it will log the error message.
UPDATE - updating as per the latest comments from the author of this question. The below one helps all your need and the above may not needed any more.
Add a custom property for the test case, whose name is STEP_NAME and its value is the test step name to which http header needs to be added. As you commented, the last test step name in this case.
Go the request test step where you are getting the Cookie as response header.
Add an assertion of type Script Assertion and have the below code. Note that, you need to modify the test step name to which you want to add the request header Cookie. Using the place holder for now.
/**Below script should be used as script assertion for first test request step
* Assumes below
* a. test response contains http header called 'Set-Cookie'
* b. other request needs to send http header called 'Cookie'
* In case if there is any change in the two header names you may need to
* change its references below
**/
def responseCookieKey = 'Set-Cookie'
def requestCookieKey = 'Cookie'
def setHttpHeaders(String nextStepName, def headers) {
def nextRequest = context.testCase.testSteps[nextStepName].httpRequest
def existingHeaders = nextRequest.requestHeaders
headers.each {
existingHeaders[it.key] = it.value
}
nextRequest.requestHeaders = existingHeaders
}
if (messageExchange.responseHeaders.containsKey(responseCookieKey)) {
log.info "Found Cookie in the response headers"
def cookiez = messageExchange.responseHeaders[responseCookieKey]
assert null != cookiez, "Response does not contain Cookie"
def headers = [(requestCookieKey) : (cookiez)]
setHttpHeaders(context.testCase.getProvertyValue('STEP_NAME'), headers)
} else {
log.error "Not Found Cookie in the response headers"
}