Reputation: 1564
I am seeing the "NameError: global name 'x' is not defined" error while running a testcase in Robot Framework.
Following is my custom library file (modified as per Bryan Oakley's comments):
import re
def pass_fail_criteria():
if int(re.findall(r"NUM_FLOWS\n-+[\s\S]*?(\d+)\s*-+", x)[0]):
return "pass"
else:
return "fail"
Following is the "pass_fail.robot" file contents:
*** Settings ***
Library Selenium2Library
Library SSHLibrary
Library regexp_def.py
Suite Setup Go to gmail page
Suite Teardown Close All Browsers
*** Variables ***
${HOMEPAGE} https://www.gmail.com/intl/en/mail/help/about.html
${BROWSER} firefox
${LOGINPAGE} https://www.gmail.com/intl/en/mail/help/about.html
${FINALURL} https://mail.google.com/mail/
${FINALURL1} https://accounts.google.com/ServiceLogin?service=mail&continue=https://mail.google.com/mail/'
${HOST} 1.1.1.1
${USERNAME} test
${PASSWORD} test
*** Test Cases ***
Login into gmail
Go to gmail page
Login Page Should Be Open
Click Signin Button
Input Username [email protected]
Input Password test@123
Submit Credentials
Inbox page should open
Check Deep Packet Inspection Stats
Open Connection ${HOST}
enable ssh logging XYZ
Login ${USERNAME} ${PASSWORD}
Write enable
Write show dpi app stats gmail on AVC/ap7532-15E8CC
${x} Read Until Regexp .*#
Pass fail Criteria
${status} pass fail criteria
should be equal ${status} pass
${result} Pass fail criteria ${x}
*** Keywords ***
Go to gmail page
Open Browser ${HOMEPAGE} ${BROWSER}
Maximize Browser Window
Login Page Should Be Open
Location Should Be ${LOGINPAGE}
Click Signin Button
Click Element id=gmail-sign-in
Input Username
[Arguments] ${username}
Input Text id=Email ${username}
Input Password
[Arguments] ${password}
Input Text id=Passwd ${password}
Submit Credentials
Click Button id=signIn
Inbox page should open
Location Should Be ${FINALURL}
I am getting the following error while running this file:
C:\Users\symbol\Desktop\Projects\gmail_stats_with_pass_fail_criteria>pybot pass_
fail.robot
==============================================================================
Pass Fail
==============================================================================
Login into gmail | PASS |
------------------------------------------------------------------------------
Check Deep Packet Inspection Stats | PASS |
------------------------------------------------------------------------------
Pass fail Criteria | FAIL |
NameError: global name 'x' is not defined
------------------------------------------------------------------------------
Pass Fail | FAIL |
3 critical tests, 2 passed, 1 failed
3 tests total, 2 passed, 1 failed
==============================================================================
Output: C:\Users\symbol\Desktop\Projects\gmail_stats_with_pass_fail_criteria\ou
tput.xml
Log: C:\Users\symbol\Desktop\Projects\gmail_stats_with_pass_fail_criteria\lo
g.html
Report: C:\Users\symbol\Desktop\Projects\gmail_stats_with_pass_fail_criteria\re
port.html
C:\Users\symbol\Desktop\Projects\gmail_stats_with_pass_fail_criteria>
There are issues in the below code:
Pass fail Criteria
${status} pass fail criteria
should be equal ${status} pass
${result} Pass fail criteria ${x}
How can I fix this issue?
Upvotes: 2
Views: 11361
Reputation: 386342
You have several problems working against you. It seems like you have a fundamental misunderstanding of how Python-based keywords work.
You are defining and importing a library named regexp_def.py. In it there is one keyword, "pass_fail_criteria". Robot will remove the underscores, so from Robot's perspective, this keyword is named "Pass fail criteria".
In your test case you are also creating a keyword called "Pass fail criteria". It is unclear why you're doing that. Do not do that. Remove that keyword; it is unnecessary.
You are using a variable x
in pass_fail_criteria
, but you haven't defined it. That is what the error is telling you. You need to define it, or pass it in. To pass it in you need to make it a parameter, and then you need to provide a value for that parameter. This is no different than any other keyword, or any other function.
In file regexp_def.py:
import re
def pass_fail_criteria(x):
if int(re.findall(r"NUM_FLOWS\n-+[\s\S]*?(\d+)\s*-+",x)[0]):
return "pass"
else:
return "fail"
(notice the added parameter in the definition)
In your test case:
Pass fail Criteria
${status} pass fail criteria ${x}
(notice the argument on the end of the second line)
The way you currently have your test cases structured, you are defining ${x}
in one test case, and then attempting to use it in another. I don't know if this was intentional or not, but many people consider this bad test case design. Test cases should be as independent as possible.
While you can do this (using the built-in keyword Set Suite Variable), I recommend calling pass fail criteria
in the test case named "Check Deep Packet Inspection Stats", where ${x}
is defined.
For example:
Check Deep Packet Inspection Stats
...
${x} Read Until Regexp .*#
${status} pass fail criteria ${x}
Run keyword if "${status}" == "pass" ...
Upvotes: 2
Reputation: 10223
x
is not defined and you are using x
in the following statement.
if int(re.findall(r"NUM_FLOWS\n-+[\s\S]*?(\d+)\s*-+",x)[0]):
Pass x
as an argument to function pass_fail_criteria(x)
and use try except
def pass_fail_criteria(x):
try:
a = int(re.findall(r"NUM_FLOWS\n-+[\s\S]*?(\d+)\s*-+",x)[0])
return "pass"
except:
return "fail"
Upvotes: 1