I'm using Robot Framework with Python to create a small framework for test automation. I have a few different libraries; a couple are application-specific and one has keywords that I would like to be always available. This always-available library is my common library and I need it to be accessible from the functions in my other libraries as well.
The way I have accomplished this until now has been some boilerplate at the top of my other libraries. Specifically, in my other libraries I have:
try:
self.common_library = BuiltIn().get_library_instance("my_common_lib")
except RuntimeError:
BuiltIn().import_library("my_common_lib", True)
self.common_library = BuiltIn().get_library_instance("my_common_lib")
This code checks the current Robot context for the existence of the common library and gets a reference to it, importing the library first if necessary. This means that I have a reference to the common library within all my other libraries and means that whenever I import any of my libraries in the Robot settings table, I have access to the common library keywords too.
The issue is that when running multiple Robot tests in sequence, the common library seems to disappear. I have a few Robot scripts in a directory and run "robot *.robot". In each test, I run a keyword from the common library. I never import the common library in the settings table, as it should be automatically imported by the other libraries as outlined above. In the first test, the common library exists and the keywords in it work fine. In all the following tests, I am getting a keyword not found error. When I print the results of BuiltIn().get_library_instance(all=True)
I can see that, while my application-specific library is still loaded, the common library no longer exists.
All my libraries have ROBOT_LIBRARY_SCOPE = 'GLOBAL'
in them, including the common library. My common library is dynamically imported via BuiltIn and has a global scope defined, but it seems to fall out of scope when running subsequent tests in one command. Is there a reason that dynamically imported libraries fall out of scope even if they have a global library scope?
Essentially, I want this common library to always be available in my robot scripts and have each of my custom libraries maintain a reference to the common library. If there is a better way to accomplish this or some way to make what I'm currently doing work, please let me know! Thanks.
A solution may be to unconditionally import the common library in all your custom libraries. E.g. in their constructors (__init__()
) call this:
BuiltIn().import_library("my_common_lib", True)
Thus you will always have its keywords in scope. Naturally if that common lib does a step that must be ran only once (affects some resource, for example), that had to be accommodated for in it (using a singleton pattern, or something similar).
Edit: come to think of it, this might also not work, the __init__()
will be called just once as the libraries are with global scope; and thus the common one's keywords will once again not be imported in the suite's namespace.
Enter RF's listener interface :) : in your custome libraries define the class method suite_start()
, and move the try-except block in it. On the start of every suite that uses such library, the method will be executed, and the common keywords - available.
The same precaution as two paragraphs above - make sure reimporting the common library has no side effects.
Another solution may be to change the custom libraries scope to 'TEST SUITE'
, as you have already deducted yourself (and are reluctant to do, based on the comments :).
Thus the custom libraries will be reinstantiated on every import in the suites, and they will import the common library in the suite's namespace.