Robot not overriding variable passed in from command line - robotframework

I have the following test:
*** Test Cases ***
My Test
${MY_VAR} Set Variable %{MY_VAR=mydefault}
If I export MY_VAR before running the test it picks that up.
If I don't have the env var set it uses the value mydefault.
So far so good, but I was expected to also explicitly override via the command line.
When I pass --variable MY_VAR=fromcmd it does not use that value.
Does %{} not support overriding with --variable?

It's true the variable setting in the command line has the highest priority, but this is not what happens here - in this line you are effectively re-setting the value.
You passed some value from the CLI, but when the execution got to that line, it actually did "the variable MY_VAR will now be set to the value of the env variable MY_VAR, or if there isn't such - to mydefault".
E.g. you're effectively overriding the value from the CLI args, present or not.
You can solve for this by first checking is the var already defined (from CLI, or some place else), and fall back to env and default only if not. The Get Variable Value returns by default None (the py type) if a variable is not defined, so using that:
${MY_VAR}= Get Variable Value ${MY_VAR}
IF $MY_VAR is None # not set yet?
${MY_VAR}= Set Variable %{MY_VAR=mydefault}
END

Related

Robotframework : file_1.robot needs to update a variable in file_2.robot

I tried using the Set Global Variable keyword but I am not sure if I am doing this correct. I was hoping to make 2 files have access to this variable. Here is my variables section. I am using VS code with Robot plugin for syntax highlighting. The error show when I run this
is:
Invalid variable name 'Set Global Variable'.robotcode.diagnostics(ModelError)
*** Variables ***
Set Global Variable ${VERBOSE} 0
${SERIAL_PORT} None
Is there a special library I need to import to use Set Global Variable?
My use case is that I have 2 robot files both of them need to know if Verbose mode is enabled. I pass verbose to file_1.robot file via command line, I was hoping I could also pass the verbose variable to a Resource file_2.robot, but I am unable to do this because
in my second file there is no "command line argument to pass in to it"
Is there a way from file_1.robot I can set/update a variable in file_2.robot ?
For file one i can do this via command line, but for file 2 I was hoping something like this would exist:
Resource ../resources/Serial.robot -v Verbose:0
(in this case Serial.robot is the infamous file 2 )
To make things even simpler I dont need Verbose in File 1 , i Just need it to pass it on to the resource file somehow
Set Global Variable is a keyword that could be used inside test cases or custom keywords. What you need is to define variable (link to documentation).
I pass verbose to file_1.robot file via command line, I was hoping I could also pass the verbose variable to a Resource file_2.robot, but I am unable to do this because in my second file there is no "command line argument to pass in to it"
Nope, you are passing global variable visible from everywhere. Take a look at documentation about scopes and priorities for variables.
If you want to define once and use in multiple places you could create file with common variables and import in both files. Example:
Here you define:
# BaseVariables.robot
*** Variables ***
${VERBOSE} 0
And use:
# file_1.robot
*** Settings ***
Resource BaseVariables.robot
and in second file
# file_2.robot
*** Settings ***
Resource BaseVariables.robot

Filter Data in Oracle Goldengate Replicat Side

I have a requirement to setup CDC from Source(Oracle) to Target(BigQuery) using Goldengate.
I can have only option to filter data in replicat side based on Specific column name .
As per the below link :
https://docs.oracle.com/en/cloud/paas/goldengate-cloud/gwuad/using-oracle-goldengate-parameter-files.html#GUID-7F405A81-B2D1-4072-B254-DC2B0EC56FBA
I have setup the replicat like below
REPLICAT RPOC
TARGETDB LIBFILE libggjava.so SET property=dirprm/bqpoc.props
SOURCEDEFS /app/oracle/ogg_bigdata/dirdef/poc.def
REPORTCOUNT EVERY 1 MINUTES, RATE
GROUPTRANSOPS 500
MAP ARADMINPI.TPOC, TARGET PRD.TPOCFL,KEYCOLS(ID),WHERE (NAME= ?SOUVIKPOC);
===================================
export SOUVIKPOC='Smith'
But I am getting below error
2020-02-19 05:47:37 ERROR OGG-01157 Error in WHERE clause for ARADMINPI.TPOC.
=============================
Is there anything I am doing wrong here?
For Parameter Substitution to work, you'll need to enclose ?SOUVIKPOC in quotes, like this:
MAP ARADMINPI.TPOC, TARGET PRD.TPOCFL,KEYCOLS(ID),WHERE (NAME= '?SOUVIKPOC');
There should also be additional information about the failure earlier in the report file.
Another Example Using #GETENV
Another option is to use the #GETENV function instead of Parameter Substitution. Here, the MAP statement uses a FILTER clause instead of the WHERE clause:
MAP ARADMINPI.TPOC, TARGET PRD.TPOCFL,KEYCOLS(ID),
FILTER (#STREQ(NAME, #GETENV('OSVARIABLE', 'SOUVIKPOC')));
Unless you set the SOUVIKPOC environment variable prior to running GGSCI (and executing START MGR), you need to add a SETENV statement to your parameter file:
SETENV (SOUVIKPOC = 'Smith')
Putting it all together:
REPLICAT RPOC
TARGETDB LIBFILE libggjava.so SET property=dirprm/bqpoc.props
SOURCEDEFS /app/oracle/ogg_bigdata/dirdef/poc.def
REPORTCOUNT EVERY 1 MINUTES, RATE
GROUPTRANSOPS 500
SETENV (SOUVIKPOC = 'Smith')
MAP ARADMINPI.TPOC, TARGET PRD.TPOCFL,KEYCOLS(ID),
FILTER (#STREQ(NAME, #GETENV('OSVARIABLE', 'SOUVIKPOC')));

How to re initiate Variable value in RobotFramework in mid of test case

I have some variables defined in Resource file.
*** Variables ***
${x} SomeValue
# Derived String
${y} SomeString_${x}
After using this in existing test case I modified ${x}. After same am able to use ${x} as modified variable but ${y} remain unchanged. Do we have some way to re initiate ${y} as per new ${x}.
Short answer - not automatically; the value of ${y} will remain as is, regardless that ${x} changed.
The reason is the values in the Variables section are set once, on instantiating the suite. At that time the value of ${y} is set to "SomeString_the-current-value-of-x", and that's it; e.g. it's not some kind of pointer to the present value of ${x}, changing as ${x} changes.
If you want to re-set the value of y, you can do it after you've changed x:
${y}= Set Variable SomeString_${x}

Using Get Time in Robot Framework Test cases

How to Use a particular Time For all the test cases in RF.Suppose i have to give time in some field of UI(User Interface).
I have to give that as current time plus 15 mins across all the test cases..How can this be done?
I have declared global variable in Resources.txt and this is being imported across all the test case files
${hr}= Get Time hour NOW + 15min
${min}= Get Time min NOW + 15min
When i run the test case, am getting the following error :
Setting variable '${hr}' failed: Creating a scalar variable with a list value in the Variable table is no longer possible. Create a list variable '#{hr}' and use it as a scalar variable '${hr}' instead.
Setting variable '${min}' failed: Creating a scalar variable with a list value in the Variable table is no longer possible. Create a list variable '#{min}' and use it as a scalar variable '${min}' instead.
But when i use the same in Test1.txt they are working fine..
If the code you are using is in the *** Variables *** section, the format is wrong. Within the variables table you cannot call keywords. What you're doing is creating a list named ${hr} with the literal value of ["Get Time", "hour", "NOW + 15min"]
From the robot framework user's guide:
The most common source for variables are Variable tables in test case
files and resource files. Variable tables are convenient, because they
allow creating variables in the same place as the rest of the test
data, and the needed syntax is very simple. Their main disadvantages
are that values are always strings and they cannot be created
dynamically.
You will need to call the Get Time keyword from within a keyword or test case. Since you want to do this at startup, you can call the keyword in the suite setup.
*** Keywords ***
initialize timestamp variables
${hr}= Get Time hour NOW + 15min
${min}= Get Time min NOW + 15min
set suite variable ${hr}
set suite variable ${min}
*** Settings ***
Suite setup initialize timestamp varaibles
If you do this in multiple suites, it's entirely possible that not all suites will use exactly the same value. An alternative solution would be to set a global variable, and only set it once. Each suite could detect if it's been set yet, and only set it if it hasn't been set.
You could also do this through a python based variable file.
Note: this solution only sets the variable for the current suite. If you do this in a suite initialization file (eg: mysuite/__init__.robot), you will need to use Set Global Variable rather than Set Suite Variable.

How can I tell robot framework not to log a keyword?

In a robot framework test case I set a variable and then do a process.
Because the setting of the variable is not a very interesting bit of information, I don't want to include that in my report.
| Verifying STUFF |
| | ${endpoint}= | set variable | STUFF
| | Verify
My report contains this:
KEYWORD: ${endpoint} = BuiltIn.Set Variable STUFF
But I would rather not have it there. How can I tell Robot Framework to just not log that line?
------edit------
It looks like this should do it:
pybot --removekeywords NAME:SetVariable testcase.txt
But the Set Variable keywords are still there.
(And yes, I upgraded my robot framework to 2.8.3 to take advantage of this function.)
The best you can do is to use
Set Log Level NONE
but it will still log all the keyword calls, just not anything inside those.
Or if you call a python function which calls another function, then the call to the second function is not logged.
Like this:
*** Settings ***
Library lib.py
*** Test Cases ***
demo
Set Log Level NONE
${a} foo
xyzzy
*** Keywords ***
xyzzy
qwerty
qwerty
No Operation
Log 123
and lib.py being like this:
def foo():
abc = bar()
return abc
def bar():
c = 1
print c
return c
The problem is that when you assign a variable like ${var} = Keyword, the name of the keyword in Robot Framework outputs is ${var} = Keyword, not Keyword as you would expect. If your keyword is from a library or a resource file, its name will also be included like ${var} = MyLibrary.Keyword. The latter is a feature but the former is a bug that is hopefully fixed in RF 2.9.
An easy workaround for the keyword name, for now, including the variable name is using wildcards. Something like this ought to work for you:
--RemoveKeywords 'name:* = BuiltIn.Set Variable'
You can use --removekeywords or --flattenkeywords option on pybot to remove the content of keyword So if you have e.g. keyword "foo" that contains lot's of logging keywords, you can set "--flattenkeywords name:foo" option to pybot, and In the log you'll only see the primary keyword, but no keywords inside it.
http://robotframework.googlecode.com/hg/doc/userguide/RobotFrameworkUserGuide.html?r=2.8.3#removing-and-flattening-keywords
If you use a python library, the following monkey-patching works for me:
from robot.libraries.BuiltIn import BuiltIn
from robot.output.logger import LOGGER
import types
def _nothing(*args, **kwargs):
pass
def disable_keyword_logging(self):
self._logging_methods = (LOGGER.start_keyword, LOGGER.end_keyword)
LOGGER.start_keyword = types.MethodType(_nothing,LOGGER)
LOGGER.end_keyword = types.MethodType(_nothing,LOGGER)
def enable_keyword_logging(self):
LOGGER.start_keyword, LOGGER.end_keyword = self._logging_methods
Then when this script is run:
Disable keyword logging
Log Hello world
Enable keyword logging
the "Log" keyword is not logged to the output but the output is.
If you really want nothing (also no debug/info/warn information logged by the called keywords), you will still have to set the log level to "NONE".
Robot Framework doesn't log "global" variables as part of a variable table. Global is in quotation marks because Set Global Variable actually is logged, but if you initialize your variable like so...
*** Variables ***
${endpoint} stuff
*** Keywords ***
...then it will not be in the Log. Additionally, if you don't want anyone to see the variable at all if they're just looking at the front end of your testing suite, you can bury it in a Resource file and the call the Resource file.
Robot Framework logs your Set Variable keywords and results because Set Variable implies that you're setting a variable dynamically and might be setting it based on the result of a keyword, in which case you'd probably want to know what the result of the keyword is. If you're just creating a static variable, then no extra work beyond the table is required. Is a dynamic variable a required part of your code?

Resources