Marked Expected Fail as Passed Test Case

Hi Guys I wanna ask something, can you give me example how to expect fail 401 unauthorized in api testing as passed test case?

Hi Ahmad,

Which Library? Which Keyword?

For example with GET from RequestsLibrary you would use the expected_status argument, but every library and keyword will be different.

Dave.

Hi Dave

${error} Run Keyword And Ignore Error POST On Session token url=XXX(censored) data=${data} headers=${headers}
Run Keyword If ‘${error}’ == ‘’ Fail ${error}
Should Be Equal As Strings ${error.class.name} HTTPError
Should Be Equal As Strings ${error.response.status_code} 401
Should Be Equal As Strings ${error.response.json()[‘error_description’]} Invalid user credentials

currently that is my code, I use RequestsLibrary. Thanks for answering btw

Sincerely,

Ahmad

1 Like

Hi Ahmad,

Yeah the RequestsLibrary keywords use the same syntax → POST On Session, You’ll also see the refer to GET for details about the kwargs

But more details about expected_status can be found in Status Should Be

You could do

${error}    Run Keyword And Ignore Error    POST On Session token    url=XXX(censored)    data=${data}    headers=${headers}    expected_status=401

However this would fail if you got a 200OK, if you response is not always 401 unauthorized, but sometimes 200 OK

Then you might want something like

${error}    Run Keyword And Ignore Error    POST On Session token    url=XXX(censored)    data=${data}    headers=${headers}    expected_status= anything

Dave.

Hi Dave, I try to use your script but got error like below

HTTPError: 401 Client Error: Unauthorized for url: myurl

any idea why this keep happening?

Thanks

Btw sorry guys if this is really basic mistake, because to be honest this is my first day using robot framework.

1 Like

Hi Ahmad,

Which one did you use?

I just noticed I gave you expected_status= anything which should have been expected_status=anything (no space) like it is in the documentation.

I would suggest you try you try expected_status=401 when that’s working consider changing to anything version, but then you’ll need to check the response is in the expected ones as using anything disables the code validation.

Dave.

Hi Dave, your solution is worked, now I think it just need to convert tuple to json before I can assert it like usual

Resolving variable ‘${error.status_code}’ failed: AttributeError: ‘tuple’ object has no attribute ‘status_code’

Can you help me with that?

Thanks in Advance

Hi Ahmad,

That’s interesting, which version of Requests Library are you using?

Your syntax ${error.status_code} is correct, maybe Run Keyword And Ignore Error is interfering?

Or it might be a problem with using ${error} as your variable, or even the lack of the equals sign (=) after ${error}? I’m really not sure.

can you try it like this

    ${resp}=    POST On Session token    url=XXX(censored)    data=${data}    headers=${headers}    expected_status=anything
    Log    ${resp}
    Log    ${resp. status_code}

Hopefully we can get it working first then you can change one back at a time till you find which was the problem

Dave.

Hi Dave,

I use this version of Request Library 0.9.4

If I check on log this is the info after ${resp}= POST On Session token url=XXX(censored) data=${data} headers=${headers} expected_status=anything

INFO ${error} = (‘PASS’, <Response [401]>)

Hi Ahmad,

I changed my Requests Library version to be 0.9.4 (same as yours)

Then I created this example to see if I could reproduce your issue, perhaps you can try running this and see if you get the same result?

*** Settings ***
Library		RequestsLibrary


*** Test Cases ***
afadhlir example
	# Request URL: https://sso.godaddy.com/v1/api/idp/login?realm=idp&app=venture-redirector&path=%2F&marketid=en-AU
	# {"plid":1,"password":"zyx","API_HOST":"godaddy.com","include_cdt":false,"remember_me":true,"include_cookies":true,"username":"xyz"}

	# Content-Type: application/json
	# Cache-Control: no-cache
	${myurl}= 		Set Variable 	https://sso.godaddy.com/v1/api/idp/login?realm=idp&app=venture-redirector&path=%2F&marketid=en-AU
	Create Session 	token 	${myurl}



	&{headers}= 	Create Dictionary 	Content-Type=application/json 	Cache-Control=no-cache
	&{data}= 			Create Dictionary 	plid=1 	password=zyx 	API_HOST=godaddy.com 	include_cdt=false 	remember_me=true 	include_cookies=true 	username=xyz

	${resp}= 	POST On Session 	token 	url=${myurl} 	data=${data} 	headers=${headers} 	expected_status=anything
	Log 	${resp}
	Log 	${resp. status_code}



#

Dave.

1 Like

Hi Dave,

Sorry for the late reply. Actually if we try not to assert something after this code

${resp}= POST On Session token url=${myurl} data=${data} headers=${headers} expected_status=anything

It will passed the test case, I think expected_status automatically marked the test case as passed because we get the same status code in response.

So do you think we need to assert the error message to in body response or is it enough to check the status code like I mention before (?)

Regards,

Ahmad

Anyway Dave, I try your suggestion and it’s completely perfect now. I’m so grateful for your help, hope we can involved in more discussion like this in the future (but hopefully next time I am the one who help you XD)

p.s this is my log. it’s so satisfying to successfully get all test case passed lol.

1 Like

Hi Ahmad,

It all depends on your application and what you are testing, there are times when it’s enough to just check the response code, there are times where the app will return a 200 OK with a stack trace or error message in the HTML (This is a really poor practice but surprisingly common, SAP is a regular offender of this behavior), and then there are times where an error code is expected, like the 401 you received is expected when you are doing negative testing to confirm invalid credentials can’t login. I don’t know the objective of your tests so you’ll need to decide if the assertion is required.

I see you returned to expected_status=401, so that is already doing an assertion and is probably enough for most test cases.

I’m glad I was able to help you resolve your issue, that’s what these forums are for after all :+1:

Dave.

Hi Dave,

I want to ask again. but this is unrelated to this thread, is there any way to get some value from another sources dynamically. let’s say there is token from some website I need to change in every 24 hours, how we do it automatically.

Second question, can we save result from our response then use it in different test file?

Thanks in Advance.

Hi Ahmad,

Sure you can do that.

The simple way is if you can get the token using Requests Library because you just create a keyword for get token, inside that keyword you create a session with a different alias for the token source site, and get the token (get/post on session?)

Then you can either:

Either way you have the token value to pass to your main test

Now if that doesn’t work, then this is where Robot Framework really shines;
You can use more than one library in the same test, so you could use SeleniumLibrary or Browser Library to go to the token source site, get the token and pass it back (see options above) then you can use requests library to make your API calls with the token, that might even then be used to get an ssh key that you pass to the SSH library to login into a remote server via SSH and run a command (i.e. read a temperature sensor), then you could use flaui Library to open a windows client server desktop application that you then record the temperature value you got back from the remote server. I guess you never imagined such a complicated scenario? but with Robot Framework it’s possible.

Once you have the data you need in a variable it’s easy to pass to another library, just make sure you pay attention to variable scopes

Dave.

Hi Dave,

I try to save the return variables in response with to some file txt. and when I check log, It actually passed but I don’t see the variable in file. any idea why that happen?

I use this code

${str_var}=    Evaluate    json.dumps(${body})
${access_var}=    Get Variable Value    ${str_var}    $.access_token
Append To Environment Variable    resources/var.txt    ${access_var}

Thanks.

Regards,

Ahmad

Hi Dave,

Just want to give update. It now success after I changed Append to Environtment Variable into Create File.

Thanks.

Sincerely,

Ahmad

1 Like

Hi Ahmad,

Robot framework doesn’t output individual variables to files automatically, what I gave you earlier was a way to do things without using files (file read and write operations can be very slow, especially in Windows)

But if you need to send a variable’s data as the content of a file, you can use Create File or one of the other file keywords from OperatingSystem Library

e.g:

${str_var}=    Evaluate    json.dumps(${body})
Create File    ${CURDIR}/example.json    ${str_var}

This is actually another example of combining the various robot framework libraries to achieve whatever you need your test case to do.

Dave.

Hi Dave, May I ask is my code already correct way to create body request like below

${data}= Create Dictionary to_number=xxx to_name=xxx category=xxx language=xx parameters=${parameters}
${parameters}= Create Dictionary body=${body}
${body}= Create List ${item}
${item}= Create Dictionary key=xx value_text=xx value=xx

and the body request is like this
{
“to_number”: “xxx”,
“to_name”: “xx”,
“category”: “xx”,
“language”: “xx”,
“parameters”: {
“body”: [
{
“key”: “xx”,
“value_text”: “xx”,
“value”: “xx”
}
]
}
}

Thanks.

Regards,

Ahmad