我感到非常困惑,并希望有人可以帮助我。
所以这是我的场景:我有一个包含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)
但是,我想避免在测试模块中进行多重继承,主要原因是更多的测试必须使用来自其他模块的特定网页的方法。
在这种情况下,有没有办法避免多重继承?
非常感谢提前。
答案 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)
这对我有用,但可能有更好的方法,尚未发现它:)