0

外部ツールとインターフェイスし、robotframeworkから使用するいくつかの基本的なキーワードを公開するライブラリがあります。このライブラリはPythonパッケージとして実装されており、このパッケージのモジュール内に、複雑なロジックを実装し、より多くのキーワードを公開する拡張機能を実装したいと思います。パッケージにはテストケーススコープが与えられていますが、これがどのように機能するかは完全にはわかりません。私が考えたいくつかの方法を提案した場合、もう少し知識のある人が、私が正しい方向に進んでいる場所と、間違った木を吠えている場所を教えてくれませんか...

  1. インスタンス変数を使用します-スコープが、pythonインタープリターがパッケージを現在のテストケースによってインポートされたものと見なすようなものである場合(つまり、これは同じパッケージの個別のインスタンスではなく、異なるテストケースで個別のパッケージとして扱われます)、初期化時に、パッケージ内の別のモジュールとの間でグローバル変数INSTANCEを設定し、それをインポートして使用することができます。selfINSTANCE

  2. インスタンスディクショナリを使用する-スコープがすべてのインポートでパッケージが同じであると見なされる場合は、robot.running.contextを使用して、パッケージが持つ各コンテキストのインスタンスディクショナリにアイテムが存在するようにディクショナリキーを設定できます。インポートされました-これは、これに基づくモジュールでルックアップキーと同じコンテキスト変数を使用できることを意味します。(これの欠点は、パッケージ自体がスコープ外になるまでガベージコレクションを防ぎ、永続的にスコープ内にあることに依存することです。)

  3. 私がまだ気付いていないコンテキスト変数は、スコープ内にあるインスタンスを提供します。ドキュメントを検索するのはかなり難しいので、これを簡単にする何かが欠けている可能性があります。また、スコープ内のキーワードを呼び出すことができるものも同様に優れています。

  4. 私が考慮しなかったいくつかの優れた可能性....

だから誰かが助けることができますか?

4

2 に答える 2

1

これの功績はrobotframeworkユーザーグループのKevinO.にありますが、基本的には次のrobot.libraries.BuiltIn.BuiltIn().get_library_instance(library_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)
于 2012-09-17T09:26:57.570 に答える
0

インポートされたコードにモンキーパッチを適用することについて話しているようです。そのため、そのパッケージをインポートする他のモジュールも実行時の変更を確認できます。(私が間違っている場合は訂正してください。あなたの質問には、私が完全にフォローしていないビットがいくつかあります)

単純なパッケージのインポートの場合、これは機能するはずです。

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パスが2つのディレクトリ、たとえば「/foo」と「/foo / bar」を含むように設定されている場合、これら2つのインポートは

from foo.bar import baz

from bar import baz

モジュールを2回ロードし、モジュール内のオブジェクト(メソッド、クラスなど)の2つのバージョンを定義することになります。その場合、一方にパッチを適用しても他方には影響しません。

そのような場合を防ぐ必要がある場合は、sys.modulesをトラバースして、インポートされたパッケージを探し、見つかった各バージョンにパッチを適用する必要があります。もちろん、これは他のすべてのインポートがすでに行われている場合にのみ機能します。これを先制的に行うことはできません(インポートフックを作成しないと、さらに深いレベルになります:))

元のパッケージをフォークして直接拡張することはできませんか?それははるかに簡単でしょう:)

于 2012-09-13T07:16:02.333 に答える