Python 如何调用已在当前运行测试用例范围内的库实例的方法

Python 如何调用已在当前运行测试用例范围内的库实例的方法,python,robotframework,Python,Robotframework,我有一个与外部工具接口的库,并公开了一些基本关键字以供robotframework使用;这个库是作为python包实现的,我想实现扩展功能,在这个包的模块中实现复杂的逻辑,并公开更多的关键字。这个包被赋予了测试用例的范围,但我不完全确定它是如何工作的。如果我提出一些我曾经想到的方法,有没有一个稍微有点知识的人能让我知道我在正确的轨道上,我在哪里走错了路 使用实例变量-如果范围是python解释器将看到当前测试用例导入的包(即在不同的测试用例中将其视为单独的包,而不是同一包的单独实例),然后在初始

我有一个与外部工具接口的库,并公开了一些基本关键字以供robotframework使用;这个库是作为python包实现的,我想实现扩展功能,在这个包的模块中实现复杂的逻辑,并公开更多的关键字。这个包被赋予了测试用例的范围,但我不完全确定它是如何工作的。如果我提出一些我曾经想到的方法,有没有一个稍微有点知识的人能让我知道我在正确的轨道上,我在哪里走错了路

  • 使用实例变量-如果范围是python解释器将看到当前测试用例导入的包(即在不同的测试用例中将其视为单独的包,而不是同一包的单独实例),然后在初始化时,我可以将全局变量
    实例
    设置为
    self
    ,然后从包中的另一个模块导入
    实例
    ,并使用它

  • 使用实例字典-如果作用域使所有导入都看到相同的包,我可以使用robot.running.context设置一个字典键,以便在导入包的每个上下文的实例字典中都有一个项-这意味着我可以在基于此的模块中使用相同的上下文变量作为查找键。(这种方法的缺点是,它将阻止垃圾收集,直到包本身超出范围,并依赖于它始终处于范围内。)

  • 我还不知道的一个上下文变量将给我范围内的实例。这些文档很难搜索,所以我完全有可能遗漏了一些东西,这会使它变得微不足道。同样好的是,我可以调用范围内的关键字

  • 一些我没有考虑过的极好的可能性


  • 有人能帮忙吗?

    听起来您在谈论导入的代码,这样导入该包的其他模块也会看到您的运行时修改。(如果我错了,请纠正我;你的问题中有几点我不太明白)

    对于简单的包导入,这应该可以:

    import my_package
    
    def method_override():
        return "Foo"
    
    my_package.some_method = method_override
    
    my_package
    ,在本例中,它引用导入的模块,而不仅仅是本地名称,因此其他模块将看到重写的方法

    这在其他代码已经完成的情况下不起作用

    from my_package import some_method
    
    因为在这种情况下,
    some_method
    是导入位置的本地名称。如果在其他地方替换该方法,则不会看到该更改

    如果发生这种情况,则您需要更改源以导入整个模块,或者通过替换方法内部来进行更深一点的修补:

    import my_package
    
    def method_override():
        return "Foo"
    
    my_package.some_method.func_code = method_override.func_code
    
    在这一点上,该方法如何导入到任何其他模块中都无关紧要;与该方法关联的代码对象已被替换,新代码将运行,而不是原始代码

    在这种情况下,唯一需要担心的是,在任何情况下,模块都是从相同的路径导入的。每当从同一路径导入现有模块时,Python解释器将尝试重用现有模块,而不是重新导入和重新初始化它们

    但是,如果您的python路径设置为包含两个目录,例如:'/foo'和'/foo/bar',那么这两个导入

    from foo.bar import baz
    

    最终将加载模块两次,并定义模块中任何对象(方法、类等)的两个版本。如果发生这种情况,那么修补一个不会影响另一个

    如果您需要防范这种情况,那么您可能必须遍历sys.modules,查找导入的包,并修补找到的每个版本。当然,这只有在所有其他导入都已经发生的情况下才会起作用,您不能先发制人地这样做(不编写导入挂钩,但这又是更深层次的:)


    你确定不能直接将原始包分叉并扩展它吗?这会容易得多:)

    这要归功于robotframework用户组的Kevin O,但本质上魔法存在于
    robot.libraries.BuiltIn.BuiltIn().get\u library\u instance(library\u name)
    ,可以这样使用:

    from robot.libraries.BuiltIn import BuiltIn
    class SeleniumTestLibrary(object):
      def element_should_be_really_visible(self):
        s2l = BuiltIn().get_library_instance('Selenium2Library')
        element = s2l._element_find(locator, True, False)
    
    from robot.libraries.BuiltIn import BuiltIn
    class SeleniumTestLibrary(object):
      def element_should_be_really_visible(self):
        s2l = BuiltIn().get_library_instance('Selenium2Library')
        element = s2l._element_find(locator, True, False)