Python Selenium - how to access methods from different modules using the same webdriver instance
<p>I am getting very confused and was hoping someone here could help me out.</p>

<p>So here is my scenario: I have one module containing the Base class where the webdriver instance is created and this will be inherited by all tests; a separate module containing a class that will be inherited by all tests for a specific page (let's call that page engagements); and a separate module for opening a different webpage (let's call it reports). I created another module with tests that will access the engagements page and the reports page.</p>

<p>When I try to access the methods under the reports module, it always fails. The reason is when I tried to access the methods, it was not using the webdriver instance that was created by the autouse fixture (which is in the Base class).</p>

<p>I got it working by multiple inheritance here:</p>

<p>This is base.py</p>

<pre><code>class Base:
    @pytest.fixture(autouse=True):
    def _init_browser(self):
        self.browser = webdriver.PhantomJS()
</code></pre>

<p>This is base_engagements.py</p>

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

<p>This is engagement_reports.py</p>

<pre><code>class CheckReportsPage(Base):
    def open_reports_for_engagement(self, voice_name):
        print("opening reports")
        self.browser.find_element_by_id("report_name")
</code></pre>

<p>And this is the test under test_voice_engagement.py</p>

<pre><code>class TestVoice(BaseEngagements, CheckReportsPage):
    def test_open_reports_for_voice(self, voice_name):
        self.open_reports_for_engagement(voice_name)
</code></pre>

<p>However, I would like to avoid multiple inheritance in the test module, for the main reason that more tests will have to use methods from other modules which are for specific webpages.</p>

<p>Is there a way to avoid multiple inheritance in this scenario?</p>

<p>Many thanks in advance.</p>

<p>If you want to avoid <strong>multiple inheritance</strong> you could use <strong>composition</strong>.
This article explains inheritance vs composition in nice way with example
<a href="https://learnpythonthehardway.org/book/ex44.html" rel="nofollow">https://learnpythonthehardway.org/book/ex44.html</a></p>

<p><strong>Note</strong> - <em>Answer is generic to python and not specific to Pytest or Selenium</em></p>

<p><strong>Inheritance way</strong> <em>Child is inheriting Parent</em></p>

<pre><code>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()"
</code></pre>

<p><strong>Composition way</strong> Child in not inheriting Parent, rather creating another object of parent during its <code>init</code>. So child contains a parent object and have access to all methods of parents via this objct.</p>

<pre><code>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()"
</code></pre>

python selenium inheritance selenium-webdriver py.test