Robot Framework : Configuration Profiles - robotframework

I have a configuration file that I am reading into my robot test cases. This configuration file contains the following variables:
${DATABASE_IP} 127.0.0.1
${ORACLE_SYSTEM_ID} xe
${ORACLE_DATABASE_URL} jdbc:oracle:thin:#${DATABASE_IP}:1521:${ORACLE_SYSTEM_ID}
${ORACLE_DATABASE_USER} cooluser
${ORACLE_DATABASE_PASSWORD} coolpassword
${ORACLE_DATABASE_DRIVER} oracle.jdbc.driver.OracleDriver
One thing I'd like to be able to do is change some of these properties, depending on where the script is executed from. Example: jenkins
A simple way to look at this, is say as follows:
I have a test file called database_test.robot.
If I invoke this file on my local machine, I'd like to pass in an argument to ensure ${DATABASE_IP} equates to 127.0.0.1 . When Jenkins does it, I want that value to point somewhere else.
Something like this already exists with maven, where you can specify a profile at runtime. Ex: mvn verify -Plocal-config ; mvn verify -Pjenkins-config
I have looked through the robot framework documentation, but cannot seem to implement something similar. The only way to swap out properties that I see is to remove the old and replace in the new. Note : I have hundreds of properties that will differ, and several other environments aside form Jenkins and local that would take different values.

Robot gives you at least three ways to solve this: argument files, variable files, and resource files. In each of the cases, you can specify which environment settings to use with a command line argument.
Argument files
Argument files are, as the name implies, files from which robot can read arguments. They are a convenient way to specify a group of command line arguments.
For example, you could create a "environments" folder that contains argument files for each of your environments (production.args, staging.args, local.args) and within the file you would set the values for all of the variables.
For example, you could create a file named local.args with the following contents:
--variable DATABASE_IP:127.0.0.1
--variable ORACLE_SYSTEM_ID:xe
--variable ORACLE_DATABASE_URL:jdbc:oracle:thin:#127.0.0.1:1521:xe
--variable ORACLE_DATABASE_USER:cooluser
--variable ORACLE_DATABASE_PASSWORD:coolpassword
--variable ORACLE_DATABASE_DRIVER:oracle.jdbc.driver.OracleDriver
Then, to run with this configuration you would use the -A or --argumentfile option:
robot --argumentfile environments/local.args ...
The advantage to using argument files is that you can override single values on the command line for times when you need to change just one value:
robot --argumentfile environments/local.args --variable ORACLE_DATABASE_USER:anotheruser
Also, with argument files you can also specify any other command line arguments. For example, if you always want to ignore tests on your CI server that are known to be broken, you could include something like --exclude known-broken (where known-broken is a tag you've applied to one or more tests)
One downside to argument files is that you can't define variables based on the value of previous variables (ie: you can't do --variable FOOBAR=${FOO}bar). I've not found that to be much of a problem.
Variable files
Variable files work in a similar way, but let you define the variables with python. The advantage to variable files is that you can do anything that python lets you do. For example, you could automatically determine the IP of the local database, or selectively turn features on or off based on runtime conditions.
The simplest way to define a variable file is to simply create python variables, which robot will find by importing your file.
For example, the variable file for your variables might look like this:
DATABASE_IP = "127.0.0.1"
ORACLE_SYSTEM_ID = "xe"
ORACLE_DATABASE_URL = " jdbc:oracle:thin:#%s:1521:%s % (DATABASE_IP, ORACLE_SYSTEM_ID)
ORACLE_DATABASE_USER} = "cooluser"
ORACLE_DATABASE_PASSWORD} = "coolpassword"
ORACLE_DATABASE_DRIVER} = "oracle.jdbc.driver.OracleDriver"
Resource Files
Much like the other two solutions, you can have separate resource files for each environment. Since robot allows you to use variables in resource file paths within a suite, you can use a variable to define which resource file to use.
For example, you could import a resource file like this:
# some_tests.robot
*** Settings ***
Resource config/${environment}.robot
You would then create a config file for each environment like you normally would (eg: config/local.robot, config/staging.robot, etc). Then, when you run robot you can tell it which resource file to use:
$ robot --variable environment:local ...

I tried the third option with Resource files but given above command line argument statement:
$ robot --variable environment=local
Didn't work for me. After looking at the robot help file, came to know that variable values should be passed through : and not with =.
So I tried with:
$ robot --variable environment:local
And it worked for me.

The correct way to specify the Resource path for a subdirectory is:
Resource ../config/${environment}.robot
if config is a subdirectory.

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

How to set custom filename for pabot result (html)

I implemented test cases for my application and decided to run it everyday. The problem is the result of the previous test will be overwritten by the latest test result. I need to keep them both so I came up with a solution that include the test date and time in the report name, for example; report-202111181704.html (use time in 24-hour format).
I searched through the internet and did not found any solution yet. Anybody here know the solution? or any alternative solution will be fine.
It depends on where you execute your tests. From command line you can save the date to variable. Then use this variable to change the name of generated outputs. For example
date=$(date '+%Y-%m-%d_%H:%M:%S')
robot --output ${date}output.xml --log ${date}log.html --report ${date}report.html test.robot
I found the solution. Instead of setting .html file name, I create a folder and put the result there.
To do this, add --outputdir in pabot command so it's gonna look like this
pabot --pabotlibport $PABOT_PORT --pabotlib --resourcefile ./DeviceSet.dat --processes $thread --verbose --outputdir ./result/$OUTPUT_DIR $ENV
where
$OUTPUT_DIR=`date + "%Y%m%d-%H%M"`
The output folder gonna be like ./result/20220301-2052

Add an extension in a .pro variable

I'm trying to print a message with QMake but I have problems with extensions:
lib_name = $$1
message("test1: $$MYPATH/$$lib_name/src/$$lib_name.pri");
message("test2: $$MYPATH/$$lib_name/src/$$lib_name");
For some reason, test1 doesn't print the correct path. It just prints the path until src/. But, test2 is ok. It prints everything until the value in $$1.
Any workaround?
QMake supports variables (objects) with members that can be used using the dot . operator e.g. target.path for INSTALLS. So, in your case, $$lib_name.pri means that you're accessing the member pri of lib_name which doesn't exist so there's no output.
You need to enclose variables in curly braces for QMake to distinguish them from the surrounding text i.e. $${lib_name}.pri.
Example:
message("test1: $$MYPATH/$$lib_name/src/$${lib_name}.pri");
# ~~~~~~~~~~~~
For more examples of objects, see Adding Custom Target and Adding Compilers sections of QMake's Advanced Usage page.
Here's another relevant SO thread: QMake - How to add and use a variable into the .pro file

Defining setup, teardown and variable in argumentfile in robotframework

Basically 2 issues:
1. I plan to execute multiple test cases from argument file. The structure would look like that:
SOME_PATH/
-test_cases/
-some_keywords/
-argumentfile.txt
How should i define a suite setup and teardown for all those test cases executed from file (-A file)?
From what i know:
a) I could execute it in file with 1st and last test case, but the order of test cases may change so it is not desired.
b) provide it in init.robot and put it somewhere without test cases only to get the setup and teardown. This is because if I execute:
robot -i SOME_TAG -A argumentfile /path/to/init
and the init is in test_case folder it will execute the test_cases with a specific tag + those in a folder twice.
Is there any better way? Provide it, for example, in argumentfile?
2 How to provide PATH variable in argumentfiles in robotframework?
I know there is possibility to do:
--variable PATH:some/path/to/files
but is it not for test suite env?
How to get that variable to be visible in the file itself: ${PATH}/test_case_1.robot
For your 2nd question, you could create a temporary environment variable that you'd then use. Depending on the OS you're using, the way you'll do this will be different:
Windows:
set TESTS_PATH=some/path/here
robot -t %TESTS_PATH%/test_case_1.robot
Unix:
export TESTS_PATH="some/path/here"
robot -t $TESTS_PATH/test_case_1.robot
PS: you might want to avoid asking multiple, different questions in the same thread

remove log information from report and save report in desire location

I am new to robot framework and wanted to see if i can get any simple code for custom report. I am also fine with answer to my problem. I went through all questions related to report but could not find any specific answer to my problem. currently my report contains log and wanted to see if i can remove log information from reports and save report in specific location. I just want to get PASS/FAIL information in my report. Can any one give me example how i can overcome this problem? I also need to know how i can save my report in different location. Any example would be helpful. Thank you in advance.
There is a tool called Rebot which is part of Robot Framework.
By default, Robot Framework creates XML reports. The XML reports are automatically converted into HTML reports by Rebot.
You can set the location of the output files in the execution by specifying the parameter --outputdir (and thus set a different base directory for outputs).
From the documentaiton:
All output files can be set using an absolute path, in which case they are created to the specified place, but in other cases, the path is considered relative to the output directory. The default output directory is the directory where the execution is started from, but it can be altered with the --outputdir (-d) option. The path set with this option is, again, relative to the execution directory, but can naturally be given also as an absolute path. Regardless of how a path to an individual output file is obtained, its parent directory is created automatically, if it does not exist already.
You can call Rebot yourself to control this conversion.
You can also run Rebot after the test was run in order to create new output on a different location.
See documentation in:
http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#post-processing-outputs
The following example shows how to store the HTML reports in a different location and including only partial data:
rebot --include smoke --name Smoke_Tests c:\results\output.xml --outputdir c:\version1.0\reports
In the example above, we process the file c:\results\output.xml, create a new report called Smoke_Tests that includes only tests with the tag smoke and save it to the output folder c:\version1.0\reports
In addition you can also set the location of the log file (HTML) from the execution.
The command line option --log (-l) determines where log files are created.
The command line option --report (-r) determines where report files are created
Removing log lines can be done a bit differently. If you run rebot --help you'll get the following options:
--removekeywords all|passed|for|wuks|name: * Remove keyword data
from all generated outputs. Keywords containing
warnings are not removed except in `all` mode.
all: remove data from all keywords
passed: remove data only from keywords in passed
test cases and suites
for: remove passed iterations from for loops
wuks: remove all but the last failing keyword
inside `BuiltIn.Wait Until Keyword Succeeds`
name:: remove data from keywords that match
the given pattern. The pattern is matched
against the full name of the keyword (e.g.
'MyLib.Keyword', 'resource.Second Keyword'),
is case, space, and underscore insensitive,
and may contain `*` and `?` as wildcards.
Examples: --removekeywords name:Lib.HugeKw
--removekeywords name:myresource.*
--flattenkeywords for|foritem|name: * Flattens matching keywords
in all generated outputs. Matching keywords get all
log messages from their child keywords and children
are discarded otherwise.
for: flatten for loops fully
foritem: flatten individual for loop iterations
name:: flatten matched keywords using same
matching rules as with
`--removekeywords name:`

Resources