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
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.
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.
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.
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
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:
- return the value of the token from the keyword
- set the token value as a Test Variable or Suite Variable
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
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