Python Selenium - 如何使用相同的webdriver实例访问来自不同模块的方法

时间:2016-09-27 04:20:30

标签: python selenium inheritance selenium-webdriver pytest

我感到非常困惑,并希望有人可以帮助我。

所以这是我的场景:我有一个包含Base类的模块,其中创建了webdriver实例,并且所有测试都会继承它。一个单独的模块,其中包含一个类,该类将由特定页面的所有测试继承(让我们调用该页面约定);以及用于打开不同网页的单独模块(让我们称之为报告)。我创建了另一个带有测试的模块,可以访问参与页面和报告页面。

当我尝试访问报告模块下的方法时,它总是失败。原因是当我尝试访问这些方法时,它没有使用由autouse fixture(在Base类中)创建的webdriver实例。

我通过多重继承来实现它:

这是base.py

class Base:
    @pytest.fixture(autouse=True):
    def _init_browser(self):
        self.browser = webdriver.PhantomJS()

这是base_engagements.py

class BaseEngagements(Base):
    @pytest.fixture(autouse=True)
    def login_engagements(self):
        print("login for engagements goes here")

这是engagement_reports.py

class CheckReportsPage(Base):
    def open_reports_for_engagement(self, voice_name):
        print("opening reports")
        self.browser.find_element_by_id("report_name")

这是test_voice_engagement.py

下的测试
class TestVoice(BaseEngagements, CheckReportsPage):
    def test_open_reports_for_voice(self, voice_name):
        self.open_reports_for_engagement(voice_name)

但是,我想避免在测试模块中进行多重继承,主要原因是更多的测试必须使用来自其他模块的特定网页的方法。

在这种情况下,有没有办法避免多重继承?

非常感谢提前。

2 个答案:

答案 0 :(得分:0)

如果您想避免多重继承,可以使用合成。 本文通过示例以很好的方式解释了继承与组合 https://learnpythonthehardway.org/book/ex44.html

注意 - 答案是python的通用答案,不是特定于Pytest或Selenium

继承方式 Child继承Parent

class Parent(object):

    def override(self):
        print "PARENT override()"

    def implicit(self):
        print "PARENT implicit()"

    def altered(self):
        print "PARENT altered()"

class Child(Parent):

    def override(self):
        print "CHILD override()"

    def altered(self):
        print "CHILD, BEFORE PARENT altered()"
        super(Child, self).altered()
        print "CHILD, AFTER PARENT altered()"

撰写方式未继承Parent的子项,而是在init期间创建父项的另一个对象。因此,子包含父对象,并且可以通过此对象访问父母的所有方法。

class Other(object):

    def override(self):
        print "OTHER override()"

    def implicit(self):
        print "OTHER implicit()"

    def altered(self):
        print "OTHER altered()"

class Child(object):

    def __init__(self):
        self.other = Other()

    def implicit(self):
        self.other.implicit()

    def override(self):
        print "CHILD override()"

    def altered(self):
        print "CHILD, BEFORE OTHER altered()"
        self.other.altered()
        print "CHILD, AFTER OTHER altered()"

答案 1 :(得分:0)

我能够通过向CheckReportsPage添加构造函数并在调用它时传递浏览器实例来使用CheckReportsPage中的方法。它基本上看起来像这样:

class CheckReportsPage(Base):
    def __init__(self, browser):
        self.browser = browser

所以在TestVoice中我这样做了:

def test_open_reports_for_voice(self, voice_name):
    self.reports = CheckReportsPage(self.wd)
    self.reports.open_reports_for_engagement(voice_name)

这对我有用,但可能有更好的方法,尚未发现它:)