机器人框架库动态导入不保持全局
Posted
技术标签:
【中文标题】机器人框架库动态导入不保持全局【英文标题】:Robot Framework Library Dynamic Import Not Remaining Global 【发布时间】:2019-03-10 00:43:48 【问题描述】:一些背景
我正在使用带有 Python 的 Robot Framework 来创建一个用于测试自动化的小型框架。我有几个不同的图书馆;一对是特定于应用程序的,一个具有我希望始终可用的关键字。这个始终可用的库是我的常用库,我也需要它可以从我的其他库中的函数访问。
到目前为止,我完成此任务的方式一直是我其他库顶部的一些样板。具体来说,在我的其他库中,我有:
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")
此代码检查当前机器人上下文是否存在公共库并获取对它的引用,如有必要,首先导入库。这意味着我在所有其他库中都引用了公共库,这意味着每当我在机器人设置表中导入我的任何库时,我也可以访问公共库关键字。
问题是当按顺序运行多个机器人测试时,公共库似乎消失了。我在一个目录中有一些机器人脚本并运行“robot *.robot”。在每个测试中,我从公共库中运行一个关键字。我从不在设置表中导入公共库,因为它应该由其他库自动导入,如上所述。在第一个测试中,公共库存在并且其中的关键字工作正常。在以下所有测试中,我得到一个关键字未找到错误。当我打印BuiltIn().get_library_instance(all=True)
的结果时,我可以看到,虽然我的应用程序特定库仍在加载,但公共库不再存在。
问题
我所有的库中都有ROBOT_LIBRARY_SCOPE = 'GLOBAL'
,包括公共库。我的公共库是通过 BuiltIn 动态导入的,并且定义了全局范围,但是在一个命令中运行后续测试时,它似乎超出了范围。动态导入的库是否有原因超出范围,即使它们具有全局库范围?
本质上,我希望这个公共库始终在我的机器人脚本中可用,并让我的每个自定义库都维护对公共库的引用。如果有更好的方法来完成此操作或某种方法可以使我目前正在做的工作,请告诉我!谢谢。
【问题讨论】:
1) 因此,当要运行的套件是“A”,然后是“B”时,在“A”中存在公共库关键字,但在“B”中不存在;当执行顺序是“B”,然后是“A”时呢?那么关键字是否出现在“B”中,而不是“A”中? 2)您是否尝试过自定义库的范围“SUITE” - 在这种情况下,理论上,它们将被重新实例化,从而重新加载通用库? (下面继续) 3) 当套件没有 可以访问公共库的关键字时,common_library
库实例变量的值是多少? 4) 当套件 不 可以访问公共库的关键字时,您是否看到正在执行的 except 块? 5)当您调用import_library
时传递的True
参数是否有任何意义(只是好奇)?我的钱在 2) 顺便说一句:)
1) 如果顺序是“B”然后是“A”,则关键字在“B”中可用,而在“A”中不可用。 2)是的,我已经尝试过使用范围“TEST SUITE”,并且它确实如您所提到的那样重新实例化。这确实有效,并且关键字在套件中再次可用,但如果可能的话,我更愿意将库保持在全局范围内。作为后备,这至少可以工作。我想在原帖中提到这一点,但觉得太长了:)
3) 当套件无法访问变量时,公共 lib 变量的值仍然与以前相同。对公共库的引用在两次执行之间在内存中保持相同的地址,但该套件似乎没有将公共库关键字保留在“可用关键字列表”中,松散地说。其他库可以访问公共库中的方法等,但如果有意义的话,框架不会保持库的加载。打印 get_library_instance(all=True) 时,未列出公共库。
4) 由于我有公共库 + 多个其他库,因此导入的第一个库会命中 except 块。这会导入公共库并获得对它的引用。我导入的其余库具有相同的块,并且在最初的尝试中永远不会失败。在我们正在讨论的情况下,如果库是全局的并且它在 init 中,则以后的套件中永远不会调用 init,因此套件“B”通过任何从不运行这个。 5)没有意义,只是我应该删除的一些内部状态:)
【参考方案1】:
解决方案可能是在所有自定义库中无条件导入公共库。例如。在他们的构造函数(__init__()
)中调用这个:
BuiltIn().import_library("my_common_lib", True)
因此,您将始终将其关键字放在范围内。自然,如果该公共库执行的步骤必须只运行一次(例如,影响某些资源),则必须在其中适应(使用单例模式或类似的东西)。
编辑:想想看,这可能也行不通,__init__()
将只被调用一次,因为库是全局范围的;因此,common 的关键字将再次不会被导入到套件的命名空间中。
输入RF's listener interface :) :在您的自定义库中定义类方法suite_start()
,并在其中移动try-except 块。在每个使用此类库的套件开始时,都会执行该方法,并且常用关键字 - 可用。
与上述两段相同的预防措施 - 确保重新导入公共库没有副作用。
另一个解决方案可能是将自定义库范围更改为'TEST SUITE'
,因为您已经扣除了自己(并且不愿意这样做,基于 cmets :)。
因此,自定义库将在套件中的每次导入时重新实例化,并且它们将在套件的命名空间中导入公共库。
【讨论】:
我认为监听器接口是完美的解决方案。谢谢,很好的发现!以上是关于机器人框架库动态导入不保持全局的主要内容,如果未能解决你的问题,请参考以下文章