私はクラス「ラッパー」を持っています。ラッパーはオブジェクトから継承しますが、主な責任はテスト中にメソッド呼び出しをセレンに呼び出すことです。それはそれの関数スコープは、呼び出された自己へのアクセス権を与えますか?
__init__(self, object_to_wrap, actions={}, **kwargs)
一部が機能__init__
メソッドのシグネチャですされたのinitメソッドに引数として辞書を取るために、そして__getattr__
魔法の方法 (シグネチャを定義することによって、object_to_wrap
オブジェクトの属性としてのキーを公開することです: __getattr__(self, item):
) とitem
のself.actions
のキーを確認してください。見つかった場合、メソッドが呼び出されます。テストコードで
、初期化はのようになります。
def navigate(scoped_self, to=''):
self.driver.switch_to_default_content()
self.driver.switch_to.frame(to)
scoped_self.navigations.append(to)
# the navigate method is scoped in an
# instance method of the test class, so it has access to self
だから、私の質問は、私はスコープを作ることができるか、である、または上記の方法ではself
、私Wrapper
クラスのスコープも、テストクラスではない?私はこの質問に探しています解決策が見つかった場合に明確にするために
、ナビゲート実装があることを変更します
def navigate(scoped_self, to=''):
self.object_to_wrap.switch_to_default_content()
self.object_to_wrap.switch_to.frame(to)
また明確にするため、私は私が探しているものをかなり確信していますまさにJavascripts Function.prototype.bind
が達成するものです。
UPDATE:ラッパークラスの内部、例えば移動などの方法を定義ラッパークラスをテスト固有のロジックを持つことができないように、オプションではありません。テストスイートは、n> 1 DOMで実行されますが、完全に無関係です。たとえば、テストの1つでは、メソッドalert_handlers(window.alert関数を上書きし、文字列として表示されたアラートを返す)、別のメソッドがnavigateメソッドを必要とし、3番目のメソッドで両方が必要な場合があります。
UPDATE#2:c17rから以下の回答のおかげで、私はのgetAttributeなしコードは、私たちはすでに達成していた何かを求めていたかのように見えるだろうと、私の例に含まれていることに気づきました。私が探しているのは、上記のnavigateメソッドの能力で、scoped_self
がWrapperのインスタンスであることです。あなたはJavaScriptを使用して慣れていない場合は、;また、私は特に「動的」(機能にFunction.prototype.bind
は、「動的」this
はmyEventListener.bind(ウィンドウ)であるthis
を設定する方法をscoped_selfを渡す方法を探しています
体にイベントリスナーを作成し、結合なしthis
をCONSOLE.LOG、その後、結合して、違いを見るために)
さらに、私はそれが私が探しています解決せずに実装例を与えるために役立つかもしれない考え出しの場合。これは、現在正常に機能している:
class Wrapper(object):
def __init__(self, wrapped, actions={}):
self.wrapped = wrapped
self.actions = actions
self.navigations = [] # EXAMPLE, SEE THE TEST CLASS CODE
def __getattr__(self, item):
if item in self.actions:
return self.actions[item]
# do other fancy stuff here
# UPDATE #2: added for clarity. this is the current implementation
orig_attr = self.wrapped.__getattribute__(item)
if callable(orig_attr):
def hooked(*args, **kwargs):
self.pre(item, *args, **kwargs)
self.err = False
try:
result = orig_attr(*args, **kwargs)
except Exception as e:
#logs
self.post(*args, **kwargs)
raise
if type(self.wrapped) == type(result):
return self
return result
return hooked
else:
return orig_attr
class SomeTest():
#blah blah init stuff, set self.driver = selenium.webdriver.Phantomjs
def spawn_actions(self):
def navigate(scoped_self, to=''):
self.driver.switch_to_default_content()
self.driver.switch_to.frame(to)
scoped_self.navigations.append(to) # <--- appended to wrapper.navigations
return {'navigate': navigate}
def run(self):
driver = Wrapper(self.driver, self.spawn_actions())
driver.get(url)
driver.navigate('New Request')
# fun tests!
あなたは正しく私を理解しなかった、と私は(簡潔にするため)__getattr__のすべてを除外をお詫び申し上げます。実際の実装がどのように見えるかについての私の更新を見てください。コードには含まれないというインスタンスメソッドが複数あることに注意してください(また、製品のプロダクションコードに近すぎるため) – h3xc0ntr0l
コードを徹底的に読み直した後、私の質問に答えました:)実装があるマシンに着くとすぐにテストします。 – h3xc0ntr0l