Robot Framework: Populating parameters based off of a robot.properties file? - robotframework

I am attempting to mock-up a 'robot.properties' file to be utilized within my test cases with the Robot Framework. Inside my robot.properties file it contains things like for example:
project.username=stackoverflow
inside my test case file I have tried several times to 'import' the robot.properties file via adding within Settings: Resource ../path/to/properties and etc (see directory structure below), but when I attempt to pass 'project.username' as an argument to a test it passes it as the literal string value 'project.username' and not the value 'stack overflow'. I am new to Robot, I have implemented this in other languages like Java/C#, but I fully assume that the import is preventing me from accessing my value. Any help would be greatly appreciated, unfortunately this way of driving testing isn't really referenced much online that I can find.
Dir Structure:
Tests/Acceptance/MyTestCase.robot
Tests/robot.properties
If I try Library ../robot.properties I get:
"Import by filename is not supported"
If I try Resource ../robot.properties I get:
"Unsupported file format .properties"

Robot framework doesn't support a ".properties" file.
One solution is to use a variable file, which lets you define variables in python. Since you want to use dot notation, one way is to create a class and define your variables as properties of the class. The variable file can then make an instance of that class as a variable, and you can use extended variable syntax to access the variables.
The advantage to using a variable file over a plain text file is that you can create variables dynamically by calling other python functions. As a simple example, you could create a variable called "now" that contains the current date, or "host" that is the hostname of the machine running the test.
Example:
properties.py
import platform
class Properties(object):
username = "stackoverflow"
password = "SuperSecret!"
hostname = platform.uname()[1]
properties = Properties()
example.robot
*** Settings ***
Variables properties.py
Suite Setup log running on ${properties.hostname}
*** Test Cases ***
Example
should be equal ${properties.username} stackoverflow

Related

Robot Framework - Is there a way to get the current file name I am right now in?

I am using Page Object Model in Robot Framework Test Automation and I am trying to pick up the test data using the page object file name. So I would like to read the file name in which I am currently in.
Is there a way to pick up the file name from login.po.resource so that I can pick up the relevant test data automatically ?
I tried ${SUITE SOURCE} but that would only give me Test Suite Name.
Also tried to define a pythod library with file; But that gives me the library name.
PS: Found a work around. But still need a proper solution.

Sqlalchemy sqlite url relative to home or environment variable

A relative sqlalchemy path to a sqlite database can be written as:
sqlite:///folder/db_file.db
And an absolute one as:
sqlite:////home/user/folder/db_file.db
Is it possible to write a path relative to home? Like this:
sqlite:///~/folder/db_file.db
Or even better, can the path contain environment variables?
sqlite:////${MY_FOLDER}/db_file.db
This is the context of an alembic.ini file. So if the previous objectives are not possible directly, may I be able to cheat using variable substitution?
[alembic]
script_location = db_versions
sqlalchemy.url = sqlite:///%(MY_FOLDER)s.db
...
I have gone around this issue by modifying the values in the config object just after env.py imports it:
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
# import my custom configuration
from my_app import MY_DB_URI
# overwrite the desired value
config.set_main_option("sqlalchemy.url", MY_DB_URI)
Now config.get_main_option("sqlalchemy.url") returns the MY_DB_URI you wanted.
As others have pointed out, one key is 3 slashes for relative, 4 for absolute.
But it took for me than just that...
Had trouble with just a string, I had to do this:
db_dir = "../../database/db.sqlite"
print(f'os.path.abspath(db_dir): {str(os.path.abspath(db_dir))}')
SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.abspath(db_dir) # works
# SQLALCHEMY_DATABASE_URI = "sqlite:///" + db_dir # fails
From the alembic documentation (emphasis mine):
sqlalchemy.url - A URL to connect to the database via SQLAlchemy. This configuration value is only used if the env.py file calls upon them; in the “generic” template, the call to config.get_main_option("sqlalchemy.url") in the run_migrations_offline() function and the call to engine_from_config(prefix="sqlalchemy.") in the run_migrations_online() function are where this key is referenced. If the SQLAlchemy URL should come from some other source, such as from environment variables or a global registry, or if the migration environment makes use of multiple database URLs, the developer is encouraged to alter the env.py file to use whatever methods are appropriate in order to acquire the database URL or URLs.
So for this case, the sqlalchemy url format can be circunvented and generated by python itself.

Share data between tests

I know we can share parameters between actions in the same test by putting them in Global data table.
Is there a way to share data / parameters between tests in QTP? SO, If I run a batch of tests, and all the tests use a parameter, I want to change the value in one location and not in Global data table of each test.
You should use XML files for this.
You should first load your XML parameter file :
You need to declare environement variables in your test this way :
Environment.LoadfromFile "path\params.xml"
decalre the variable in your script
user=Environment.Value("username")
then use the variable this way in your test
JavaDialog("LoginWin").JavaEdit("JTextField").Set user
Then you need to decalre he variable in your xml file :
<Variable>
<Name>username</Name>
<Value>admin</Value>
</Variable>

How to get and set the default output directory in Robot Framework(Ride) in Run time

I would like to move all my output files to a custom location, to a Run directory created based on Date time during Run time. The output folder by datetime is created in the TestSetup
I have function "Process_Output_files" which will move the files to the Run folder(Run1,Run2,Run3 Folders).
I have tried using the argument-d and used the function "Process_Output_files" as suite tear down to move the output files to the respective Run directory.
But I get the following error "The process cannot access the file because it is being used by another process". I know this is because the Robot Framework (Ride) is currently using this.
If I dont use the -d argument, the output files are getting saved in temp folders.
c:\users\<user>\appdata\local\temp\RIDEfmbr9x.d\output.xml
c:\users\<user>\appdata\local\temp\RIDEfmbr9x.d\log.html
c:\users\<user>\appdata\local\temp\RIDEfmbr9x.d\report.html
My question is, Is there a way to get move the files to custom location during run time with in Robot Framework.
You can use the following syntax in RIDE (Arguments:) to create the output in newfolders dynamically
--outputdir C:/AutomationLogs/%date:~-4,4%%date:~-10,2%%date:~-7,2% --timestampoutputs
The above syntax gives you the output in below folder:
Output: C:\AutomationLogs\20151125\output-20151125-155017.xml
Log: C:\AutomationLogs\20151125\log-20151125-155017.html
Report: C:\AutomationLogs\20151125\report-20151125-155017.html
Hope this helps :)
I understand the end result you want is to have your output files in their custom folders. If this is your desire, it can be accomplished at runtime and you won't have to move them as part of your post processing. This will not work in RIDE, unfortunately, since the folder structure is created dynamically. I have two options for you.
Option 1: Use a script to kick off your tests
RIDE is awesome, but in my humble opinion, one shouldn't be using it to run ones tests, only to build and debug ones tests. Scripts are far more powerful and flexible.
Assuming you have a test, test2.txt, you wish to run, the script you use to do this could be something like:
from time import gmtime, strftime
import os
#strftime returns string representations of a date-time tuple.
#gmtime returns the date-time tuple representing greenwich mean time
dts=strftime("%Y.%m.%d.%H.%M.%S", gmtime())
cmd="pybot -d Run%s test2"%(dts,)
os.system(cmd)
As an aside, if you do intend to do post processing of your files using rebot, be aware you may not need to create intermediate log and report files. The output.xml files contain everything you need, so if you don't want to create superfluous files, use --log NONE --report NONE
Option 2: Use a listener to do post processing
A listener is a program you write that responds to events (x_start, x_end, etc). The close() event is akin to the teardown function and is the last thing called. So, assuming you have a function moveFiles() you simply need to create a listener class (myListener), define the close() method to call your moveFiles() function, and alert your test that it should report to a listener with the argument --listener myListener.
This option should be compatible with RIDE though I admit I have never tried to use listeners with the IDE.
At least you can write a custom run script that handles the moving of files after the test case execution. In this case the files are no longer used by pybot.

What is job.get() and job.getBoolean() in mapreduce

I am working on pdf document clustering over hadoop so I am learning mapreduce by reading some examples on internet.In wordcount examples have lines
job.get("map.input.file")
job.getboolean()
What is function of these functions?what is exactly map.input.file where is it to set? or is it just a name given to input folder?
Please post answer if anyone know.
For code see the following link
wordcount 2.0 example=http://hadoop.apache.org/docs/r1.0.4/mapred_tutorial.html
These are job configurations. i.e. set of configurations which are passed on to each mapper and reducer. Now, these configurations consist of well defined mapreduce/hadoop related configurations as well as user-defined configurations.
In your case, map.input.file is a pre-defined configuration and yes it is set to a comma separated list of all the paths you have set as input path.
While wordcount.skip.patterns is a custom configuration which is set as per user's input, and you may see this configuration to be set in run() as follows:
conf.setBoolean("wordcount.skip.patterns", true);
As for when to use get and when to use getBoolean, it should be self-explanatory, as whenever you want to set a value of type boolean you will use getBoolean and setBoolean to get and set the specific config value respectively. Similarly you have specific methods for other data types as well. If it is string then you may use get().

Resources