机器人框架:访问同一个库的多个资源文件

Posted

技术标签:

【中文标题】机器人框架:访问同一个库的多个资源文件【英文标题】:Robot Framework: Multiple Resource-Files accessing the same Library 【发布时间】:2018-07-09 12:11:37 【问题描述】:

所有 RobotFramework 用户您好

问题

我们有许多不同抽象级别的关键字,并且正在寻找一种简单的方法来导入它们,同时在 IDE 中保持对自动完成等的支持。

继承可能如下所示:

   /---------------------> basic_keywords.robot <---\
  /                             ^                    \
 /                              |                    |
 |  advanced_keywords_1.robot --/            advanced_keywords_2.robot
 |            ^
 |            |
more_advanced_keywords_1.robot

方案一:导入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

在测试套件中导入:

*** Settings ***
Resource   all_keywords.robot

好处:

这在执行时起作用。 使用任何测试套件中的同一行,我们可以访问所有关键字。 我们不需要在每个高级关键字文件中导入必要的关键字,这会导致双重导入。

缺点:

不支持自动补全等,因为advanced_keywords.robot 不知道basic_keywords.robot。 在测试套件中导入许多(通常不使用)关键字,降低性能 (?)

提案2:参考basic_keywords...在advanced_keywords

@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

双重导入由 Robot Framework 处理。

在测试套件中导入:

*** Settings ***
Resource   more_advanced_keywords_1.robot
Resource   advanced_keywords_2.robot

好处:

这在执行时起作用 支持自动完成等,因为 IDE 知道 Advaned Keyword 的定义位置 更好地控制哪些关键字可用,更快

缺点:

您必须明确决定/导入您在测试套件中使用的advanced_keywords

ROBOT_LIBRARY_SCOPE = 'GLOBAL' 中的SomeLibrary.py 可以防止库的双重实例化,请参阅Robot Framework makes two instances from the class instead of one 和Robot Framework User Guide

其他建议?

这两种建议各有利弊。有什么建议吗?你会建议什么结构?

【问题讨论】:

【参考方案1】:

解析在什么级别不起作用?

常识(以及个人使用 PyCharm 的经验)来看,在仅导入 basic.robot 的套件中,来自 more_advanced_keywords_1.robot 的关键字将是可解析的——它们是通过 basic 间接导入的,因此在当前上下文中。

编辑more_advanced_keywords_1 时,我认为没有IDE 可以解析advanced_keywords_1basic 中的关键字。原因是当前文件无法单独访问它们。

在一个使用上下文(套件 A)中,消费者可能已经导入了这个文件(more_advanced_keywords_1)和另一个文件(advanced_keywords_1),并且可以访问后者的关键字;但在另一种情况下(套件 B),消费者可能只导入了 more_advanced_keywords_1。 那么如果more_advanced_keywords_1 引用来自advanced_keywords_1 的关键字,B 会发生什么?它会在运行时失败,因为此时未定义(可访问)关键字。 这与编辑 more_advanced_keywords_1 时 IDE 无法解析 advanced_keywords_1basic 中定义的关键字的原因相同 - 它在当前上下文中无法访问它们。

你有两个选择:

咬紧牙关,不要让IDE在更深的关键字文件中解析;它仍然可以在套件中使用,所以这是可以忍受的。 使用双重导入 - basic 导入 advanced_keywords_1advanced_keywords_1 导入 basic;这听起来可能很可怕或错误,但 Robot Framework(实际上是 py)可以很好地管理它。即使是循环导入也不会引起问题(a 导入 b,b 导入 a)。

过去我有一个和你一样的结构 - 一个主关键字文件,它本身导入了 20 多个二级资源文件,其中一些导入了三级资源文件。我使用了双重导入并且没有遇到问题(唯一的要求 - 没有关键字名称冲突)。从那时起,我转向更分解的结构 - 没有主文件,套件只导入他们需要的资源。原因 - 更轻和更快的初始加载,主要是 - 我厌倦了在当前命名空间中不断提供 1000 多个关键字 - 例如出现在自动建议中:)

【讨论】:

感谢您的反馈!我明白你的观点,双重进口通常有效。但是如果basic_keywords 访问SomeLibrary.py,你会生成这个库的多个实例,对吧?这可能是有问题的,例如当访问到只能打开一次的目标的串行连接时。当然,Python 中有解决方法(全局变量),但仍然...... 实际上 - 不,它只会生成一个(刚刚测试过) - 请自己尝试确定。重要但与这种情况没有直接关系的是声明的ROBOT_LIBRARY_SCOPE - 此设置控制库本身何时/多少次被初始化。 GLOBAL 每次运行一次,TEST SUITE - 在每个套件启动时。然而,无论导入结构如何,此设置都处于控制之中(并且会执行此操作)。所以再一次 - 不应该是一个问题,自己试试吧。 实际上是 v2 - 从头开始​​,即使 ROBOT_LIBRARY_SCOPE 也不应该搞砸任何事情 - RF 中的案例和套件是串行执行的,所以即使范围是案例或套件,lib - 和一次只实例化一个连接;如果它正确关闭了连接(例如在析构函数中),那么应该没有问题。 ROBOT_LIBRARY_SCOPE 是必要的提示,非常感谢@Todor!我重构了代码 s.t. basic_keywords 将引用库,advanced_keyword 将导入 basic_keywords。当将 ROBOT_LIBRARY_SCOPE 显式设置为 'GLOBAL' 时,我可以简单地在所有套件中使用关键字,并且不需要在测试用例等之后显式关闭连接。 关于库范围的旁注:如果未明确设置为 'GLOBAL',则在使用多个嵌套套件(文件夹)时,库会被多次实例化。当显式设置为'GLOBAL' 时,一切正常,无需显式关闭库中的连接(RobotFramework 3.0.2)。【参考方案2】:

这是与 PyCharm IDE 相关的问题,我用 RED Robot Editor 做了一个正确处理继承资源的示例:

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

我很确定 RIDE 也会处理这种情况,尽管我没有安装它。

【讨论】:

与 OP 相比,您的导入结构是相反的 - 您在 advanced.robot 中导入 basic.robot,而他(s)他在 basic 中导入高级,他的套件仅在 basic 中导入。在您的情况下(几乎)每个 IDE 或它的插件都会成功解决,因为它是微不足道的。 @Todor - 好的,我明白了 - 不怀疑这会起作用,但我错了。在 RED 中,用户可以使用生成的关键字文档(机器人 libdoc 模块)进行自动编译和验证,这仅适用于库,但我们正在评估是否也不允许对资源文件进行此操作(在设置部分有和没有显式导入)。 像 OP 示例中那样隐藏依赖项可能在短期内很方便,但以后可能会造成噩梦来维护测试库单体(测试仅适用于所有导入,无法离线验证 KW, KW 变化的脆弱性)。现在在 RED 中,用户可以从未导入的资源/库中添加 KW,但 RED 将在当前测试套件的设置中添加显式导入。准隐式导入的一个地方是将资源添加到 python_path 的情况(测试存储库中可能不存在文件的导入),我不喜欢这种情况。 我不像你那样理解 OP 的设计意图——对我来说,目的是在每个套件中都有一个单独的导入,这将帮助用户进入他的框架。 “只需导入 basic_keywords,您就可以访问所有可用的关键字”。唯一的缺点是跨资源引用,但这可以通过双重/循环导入来解决。我也不同意你的观点,这种方法增加了额外的关键字脆弱性——它是一个设计属性,这是依赖管理——以及完全暴露的管理策略...... 我并不是说 OP 的计划是最好的架构 - 但它已经足够好了。我使用了类似的 1.5 年,离开它主要是因为厌倦了它(真的!:) 和 SUT 中的业务域分离(长话短说,不要问:)。我对它的问题很小。一旦我决定将其重构为显式和特定于功能的导入,就不需要太多时间(2-3 个工作日)——而且规模相当大。我的观点是 - 这种方法不是死胡同,当需要重构时,RF 是宽容的。

以上是关于机器人框架:访问同一个库的多个资源文件的主要内容,如果未能解决你的问题,请参考以下文章

一种以动态库的方式使用资源表的方案

机器人框架:从 python 库导入变量

如何从多个项目访问公共资源文件

访问捆绑包上的资源[重复]

Spring中的资源文件框架——Resource

C#项目中如何调用C#写的dll中的资源文件,如 xml文件