title: pytest -> How to use fixture return value in test method under a class
body: <p>I have a fixture that returns a value like this:</p>
  
  <pre><code>import pytest
  
  @pytest.yield_fixture(scope="module")
  def oneTimeSetUp(browser):
      print("Running one time setUp")
      if browser == 'firefox':
          driver = webdriver.Firefox()
          print("Running tests on FF")
      else:
          driver = webdriver.Chrome()
          print("Running tests on chrome")
      yield driver
      print("Running one time tearDown")
  </code></pre>
  
  <p>This fixture gets the browser value from another fixture which is reading the command line option.</p>
  
  <p>Then I have a test class where I have more than one test methods and they all want to consume the same returned value driver to proceed the tests.</p>
  
  <pre><code>import pytest
  
  @pytest.mark.usefixtures("oneTimeSetUp")
  class TestClassDemo():
  
      def test_methodA(self):
          # I would like to use the driver value here
          # How could I do this?
          # Something like this
          self.driver.get("https://www.google.com")
          self.driver.find_element(By.ID, "some id")
          print("Running method A")
  
      def test_methodB(self):
          print("Running method B")
  </code></pre>
  
  <p>Using self.driver fails with the error message</p>
  
  <pre><code>self = &lt;test_class_demo.TestClassDemo object at 0x102fb6c18&gt;
  
      def test_methodA(self):
  &gt;       self.driver.get("https://www.google.com")
  E           AttributeError: 'TestClassDemo' object has no attribute 'driver'
  </code></pre>
  
  <p>I am aware that I can pass the fixture as an argument to every method where I want to use that, but that is not the best way because I need this in every method and it should be possible to pass it to the class and then use it in all the test methods.</p>
  
  <p>What is the best way that I can make the driver object available to the methods?</p>
  
  <p><strong>EDIT 1:</strong></p>
  
  <p>Created the fixture in conftest.py like this as suggested</p>
  
  <pre><code>@pytest.yield_fixture(scope="class") # &lt;-- note class scope
  def oneTimeSetUp(request, browser): # &lt;-- note the additional `request` param
      print("Running one time setUp")
      if browser == 'firefox':
          driver = webdriver.Firefox()
          driver.maximize_window()
          driver.implicitly_wait(3)
          print("Running tests on FF")
      else:
          driver = webdriver.Chrome()
          print("Running tests on chrome")
  
      ## add `driver` attribute to the class under test --&gt;
      if request.cls is not None:
          request.cls.driver = driver
      ## &lt;--
  
      yield driver
      print("Running one time tearDown")
  </code></pre>
  
  <p>I have one more class, which object in need in the TestClassDemo and I need to pass the same driver instance to the class. Consider it as class ABC</p>
  
  <pre><code>class ABC():
  
      def __init(self, driver):
          self.driver = driver
  
      def enterName(self):
          # Do something with driver instance
  </code></pre>
  
  <p>Then in the TestClassDemo</p>
  
  <pre><code>@pytest.mark.usefixtures("oneTimeSetUp", "setUp")
  class TestClassDemo(unittest.TestCase):
  
      # I need to create an object of class ABC, so that I can use it here
      # abc = ABC(self.driver)
  
      @pytest.fixture(scope="class", autouse=True)
      def setup(self):
          self.abc = ABC(self.driver)
      # I tried this, but it's not working
      # This error message shows up
      # AttributeError: 'TestClassDemo' object has no attribute 'driver'
  
      def setup_module(self):
      self.abc = ABC(self.driver)
      # This also does not work
      # Error message -&gt;  AttributeError: 'TestClassDemo' object has no attribute 'abc'
  
  
      def test_methodA(self):
          self.driver.get("https://google.com")
          self.abc.enterName("test")
          print("Running method A")
  
      def test_methodB(self):
          self.abc.enterName("test")
          print("Running method B")
  </code></pre>
  
  <p>This abc object should be usable in other test_ methods also.</p>
  
  <p><strong>All these classes are in separate modules, I mean to say in separate .py files.</strong></p>
  
  <p>Also please explain in the answer what is the best way to use instead of yield driver instance.</p>
  
  <p><strong>EDIT 2:</strong></p>
  
  <p>For this example without yield, what would be the best way to run oneTimeTearDown also? I was running the tearDown steps after the yield</p>
  
  <pre><code>@pytest.fixture(scope="class")
  def oneTimeSetUp(request, browser):
      print("Running one time setUp")
      if browser == 'firefox':
          driver = webdriver.Firefox()
          driver.maximize_window()
          driver.implicitly_wait(3)
          print("Running tests on FF")
      else:
          driver = webdriver.Chrome()
          print("Running tests on chrome")
  
      if request.cls is not None:
          request.cls.driver = driver
  </code></pre>
  
  <p>Also I tried using UnitTest class, but when I use def setUpClass(cls), I was not able to use the objects instantiated in the test_ methods. So I couldn't not figure out how to achieve that.</p>
  
  <p>I also wanted to provide command line arguments like browser from the command line and when I tried unittest, I had to write the command line argument in every class. I wanted to provide them in one place only, like a test suite. So conftest helped me here.</p>
  
  <p>I had a question on stackoverflow but didn't get a response. Could you please take a look at that also?
  <a href="https://stackoverflow.com/questions/37674801/python-unittest-passing-arguments-to-parent-test-class">Python unittest passing arguments to parent test class</a></p>
  
  <p>Thanks</p>
  
  <p>Thanks</p>