Hello to all RobotFramework users
Problem
We have many keywords at different levels of abstraction and are looking for a simple way to import them while maintaining support for autocompletion etc. in IDEs.
The inheritance could look as follows:
/---------------------> basic_keywords.robot <---\
/ ^ \
/ | |
| advanced_keywords_1.robot --/ advanced_keywords_2.robot
| ^
| |
more_advanced_keywords_1.robot
Proposal 1: Import all keywords in all_keywords.robot
all_keywords.robot:
*** Settings ***
Library SomeLibrary.py
Resource basic_keywords.robot
Resource advanced_keywords_1.robot
Resource more_advanced_keywords_1.robot
Resource advanced_keywords_2.robot
more_advanced_keywords_1.robot:
# No Import of basic_keywords.robot here!!!
*** Keywords ***
My More Advanced Keyword
Advanced Keyword # from advanced_keywords.robot
Basic Keyword # from basic_keywords.robot
Import in test suites:
*** Settings ***
Resource all_keywords.robot
Benefits:
This works at execution.
With the same line in any of the test suites, we have access to all keywords.
We do not need to import the necessary keywords in each of the advanced keywords files, which would lead to double imports.
Drawbacks:
Autocompletion etc. is not supported because advanced_keywords.robot does not know about basic_keywords.robot.
Imports many (often not used) keywords in test suites, slows down performance (?)
Proposal 2: Reference basic_keywords... in advanced_keywords
Proposed by #Todor
advanced_keywords.robot:
*** Settings ***
Resource basic_keywords.robot
*** Keywords ***
Advanced Keyword
Basic Keyword # from basic_keywords.robot
more_advanced_keywords_1.robot:
Resource advanced_keywords.robot
# basic_keywords is imported here by advanced_keywords.robot
*** Keywords ***
My More Advanced Keyword
Advanced Keyword # from advanced_keywords.robot
Basic Keyword # from basic_keywords.robot
Double imports are handled by Robot Framework.
Import in test suites:
*** Settings ***
Resource more_advanced_keywords_1.robot
Resource advanced_keywords_2.robot
Benefits:
This works at execution
Auto completion etc. is supported as the IDE knows where the Advaned Keyword is defined
Better control on which keywords are available, faster
Drawbacks:
You have to explicitly decide / import which advanced_keywords you use in a test suite.
Double instantiations of the library can be prevented by ROBOT_LIBRARY_SCOPE = 'GLOBAL' in SomeLibrary.py, see Robot Framework makes two instances from the class instead of one and the Robot Framework User Guide
Other Proposals?
There are benefits and drawbacks to both proposals. Any recommendations? What structure would you propose?
At what level does the resolving not work?
Judging from common sense (and personal experience with PyCharm), in suites that import just basic.robot, the keywords from more_advanced_keywords_1.robot will be resolvable - they are indirectly imported through basic, and thus in the current context.
When editing more_advanced_keywords_1, I don't think there is an IDE which will resolve keywords from advanced_keywords_1 or basic. The reason is that the current file does not have access to them in isolation.
In one usage context (suite A), the consumer may have imported both this file (more_advanced_keywords_1) and another (advanced_keywords_1) and have access to the latter's keywords; but in another context (suite B), the consumer may have imported just more_advanced_keywords_1.
So what would hapen in B, if more_advanced_keywords_1 was referencing a keyword from advanced_keywords_1? It would fail at runtime, as the keyword is not defined (accessible) at this point.
This is the same reason an IDE doesn't resolve the keywords defined in advanced_keywords_1 or basic when editing more_advanced_keywords_1 - it has no access to them in the current context.
You have two options:
Bite the bullet and not have IDE resolving in the deeper keyword files; it still will work in the suites, so that's something bearable.
Go with double imports - basic imports advanced_keywords_1, and advanced_keywords_1 imports basic; it may sound scary or wrong, but Robot Framework (actually py) manages it just fine. Even circular imports are not causing issues (a imports b, and b imports a).
In the past I had a structure just like yours - a master keyword file, importing in itself 20+ 2nd level resource files, some of them importing 3rd level. I've used the double import and did not run into issues (the only req - no keyword names conflicts).
Since then I moved to more broken-down structure - no master file, the suites import only the resources they need. The reason - lighter and faster initial loading, and mainly - I was sick of having 1000+ keywords constantly available in the current namespace - e.g. present in the autosuggestion :)
This is issue related with PyCharm IDE, I made an example with RED Robot Editor which handles inherited resources correctly:
project structure:
res/basic.robot contains basic kw
res/advanced.robot imports basic.robot -> all kws from basic are avaliable and validated
res/even_more_adv.robot imports advanced.robot -> all kw from advanced + all kw from basic
main_testsuite.robot imports res/even_more_adv.robot -> all kw from even_more + advanced + basic resources are visible
I am pretty sure that RIDE will handle such cases as well although I do not have it installed.
Related
I have 2 Testcases within a Robot suite. This suite is like the Initialization Suite which has a dependency on an underlying framework(UF).
UF has different folder structure for the main Initialization Suite, Functional Suites and few other tools and calls them with separate robot commands. So I cannot store variables with Set Global Variables during initialization but have to create resource files which I will import in Functional Suites.
TC1: Parses a json file and creates a variables.txt file.
TC2: Uses few variables stored in variables.txt and logs into server the gets the node details and stores in hostname.txt
Is there a way to import/source the variables.txt within TC2 ?
Looking for this implementation, as there are Common User Keywords(CUKW) which will also need this variables.txt. As this is dynamically generated I cannot define it as Resource in Settings section in CUKW.
New to Robot framework, Apologies for any misunderstanding. Any better implementation suggestions are most welcome.
Thanks in Advance!
You can use the import resource keyword.
Imports a resource file with the given path.
Resources imported with this keyword are set into the test suite scope similarly when importing them in the Setting table using the Resource setting.
Acc.to the documentation
Reload Library name_or_instance
Rechecks what keywords the specified library provides.
Can be called explicitly in the test data or by a library itself when keywords it provides
have changed. The library can be specified by its name or as the active instance of the
library. The latter is especially useful if the library itself calls this keyword as a
method. New in Robot Framework 2.9.
The goal:
Is to provide a concrete example 1, where a library A uses Reload Library LibraryB and checks that the keywords LibraryB provides indeed have changed.
Another example 2 would be to use the Reload Library LibraryB in the test data and check that the keywords LibraryB provides indeed have changed.
With the given documentation, i am unable to provide such an example. Thank you for your effort.
I have a BDD-style test case in my robot framework. Which is calling the API. There is a variable in API, which value changes. So I want to write only one test case and want that variable to be changed after one has executed.
Please find the code below:
*** Variables ***
${Upload_Project_Asset_To_Flagship_API} /workstream/api/projects/${projectId}/assets/${assetId}/external?debug=1&user_id=${userId}
*** Test Cases ***
TC_01:
When User Executes Upload Asset To Flagship API
Then Assert the response after asset upload
[Teardown] User gets the uploaded file details
*** Keywords ***
User Executes Upload Asset To Flagship API
${resp}= Put request session1 ${Upload_Project_Asset_To_Flagship_API} headers=${api_header}
This is an old question, but for anyone landing here:
It is perfectly possible to combine Given When Then descriptions with Data driven tests - also in Robot Framework. Many BDD tools (e.g. Cucumber) use a list of "Examples" under the GWEN.
With standard Robot Framework, template tests can be used to list data, but only one template can be used in a suite.
To support Examples in a more natural way, I have written the Robot Framework library RobotFramework-Examples.
Is it possible to call a robot framework file from another robot framework file. Can some one give examples of it
Requirement
We have some tests which are of repetitive nature. The idea is to have these tests present in a Robot file which can be called into the main robot tests file. This will allow us to keep adding to the list of repetitive tests and all the new / old tests will be available for the main tests.
Any examples will help. Thanks.
-KK
Tests (or Test cases) are not reusable components in robot framework. Tests exist to perform verifications. Once those verifications have been made, there's no point in running the test again in the same test run.
Even though tests can't call other tests, they can call user keywords, which is the foundation of robot framework. If you have bits of functionality that you want to be reusable, you put that functionality in keywords, and then you can use those keywords in as many tests as you want.
For example, lets say that you need to send a signal to a device and check for a light to come on. Instead of writing a test that does this, and then repeating the test over and over, you create a keyword that sends the signal, and a keyword that verifies the light is on, and then call these keywords from multiple tests (or one data-driven test).
Yeah.
Just declare the file that you wish to call in Settings section of your code as specified below.
Resource ../common/Resource_Apps.robot
Now you can use or call all the keywords written in this resource file.
just import the another robot as a Resource
Settings:
Library PythonLibrary.py
Resource <Folder_Name>/Example.robot
I have a robot test suite that contains child test suites, and those have their own child test suites.
All tests use a certain set of variables and libraries.
As far as I can tell, I have to define the variables and import the libraries in every single test suite. I hope I'm just missing a trick -- is there a better way to make these things available to all tests at all levels of the hierarchy?
Bonus points if I can do it in a way that supports keyword completion in RIDE. I'm using RIDE 1.2.3 and robot 2.8.3
Create one main resource where you import everything and then import only that main resource in every test suite.
You can wire a resource file and polulate it with Keywords that can be imported into your test suites and test cases.
Read the detailed explaination.