python - pytest -> How to use fixture return value in test method under a class -


i have fixture returns value this:

import pytest  @pytest.yield_fixture(scope="module") def onetimesetup(browser):     print("running 1 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 1 time teardown") 

this fixture gets browser value fixture reading command line option.

then have test class have more 1 test methods , want consume same returned value driver proceed tests.

import pytest  @pytest.mark.usefixtures("onetimesetup") class testclassdemo():      def test_methoda(self):         # use driver value here         # how 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") 

using self.driver fails error message

self = <test_class_demo.testclassdemo object @ 0x102fb6c18>      def test_methoda(self): >       self.driver.get("https://www.google.com") e           attributeerror: 'testclassdemo' object has no attribute 'driver' 

i aware can pass fixture argument every method want use that, not best way because need in every method , should possible pass class , use in test methods.

what best way can make driver object available methods?

edit 1:

created fixture in conftest.py suggested

@pytest.yield_fixture(scope="class") # <-- note class scope def onetimesetup(request, browser): # <-- note additional `request` param     print("running 1 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 class under test -->     if request.cls not none:         request.cls.driver = driver     ## <--      yield driver     print("running 1 time teardown") 

i have 1 more class, object in need in testclassdemo , need pass same driver instance class. consider class abc

class abc():      def __init(self, driver):         self.driver = driver      def entername(self):         # driver instance 

then in testclassdemo

@pytest.mark.usefixtures("onetimesetup", "setup") class testclassdemo(unittest.testcase):      # need create object of class abc, can use here     # abc = abc(self.driver)      @pytest.fixture(scope="class", autouse=true)     def setup(self):         self.abc = abc(self.driver)     # tried this, it's not working     # error message shows     # attributeerror: 'testclassdemo' object has no attribute 'driver'      def setup_module(self):     self.abc = abc(self.driver)     # not work     # error message ->  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") 

this abc object should usable in other test_ methods also.

all these classes in separate modules, mean in separate .py files.

also please explain in answer best way use instead of yield driver instance.

edit 2:

for example without yield, best way run onetimeteardown also? running teardown steps after yield

@pytest.fixture(scope="class") def onetimesetup(request, browser):     print("running 1 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 not none:         request.cls.driver = driver 

also tried using unittest class, when use def setupclass(cls), not able use objects instantiated in test_ methods. couldn't not figure out how achieve that.

i wanted provide command line arguments browser command line , when tried unittest, had write command line argument in every class. wanted provide them in 1 place only, test suite. conftest helped me here.

i had question on stackoverflow didn't response. please take @ also? python unittest passing arguments parent test class

thanks

thanks

there's technique outlined in py.text unittest integration documentation may helpful ... using built-in request fixture. otherwise, i'm not aware of way access return value of fixture without providing named fixture method param.

@pytest.yield_fixture(scope="class") # <-- note class scope def onetimesetup(request, browser): # <-- note additional `request` param     print("running 1 time setup")     if browser == 'firefox':         driver = webdriver.firefox()         print("running tests on ff")     else:         driver = webdriver.chrome()         print("running tests on chrome")      ## add `driver` attribute class under test -->     if request.cls not none:         request.cls.driver = driver     ## <--      yield driver     print("running 1 time teardown") 

now can access driver class attribute in testclassdemo, have in example (i.e. self.driver should work).

the caveat fixture must use scope='class', otherwise request object not possess cls attribute.

i hope helps!


update

i have 1 more class, object in need in testclassdemo , need pass same driver instance class. consider class abc

it's difficult know without more context, seems me can away instantiating abc object @ same time instantiate driver ... in onetimesetup fixture. example ...

@pytest.yield_fixture(scope="class") def onetimesetup(request, browser):     print("running 1 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 not none:         request.cls.driver = driver         request.cls.abc = abc(driver) # <-- here      yield driver     print("running 1 time teardown") 

but if need abc instance test class or two, here's how might use fixture inside class definition ...

@pytest.mark.usefixtures("onetimesetup", "setup") class testclassdemo(unittest.testcase):     @pytest.fixture(autouse=true)     def build_abc(self, onetimesetup): # <-- note onetimesetup reference here         self.abc = abc(self.driver)      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") 

i wouldn't particularly happy second example. third option have yield_fixture, or similar, separate onetimesetup , returns abc instance driver wrapped.

which way best you? not sure. you'll need decide based on you're working with.

it's proper note posterity pytest fixtures sugar , bit of magic. not required use them @ all, if find them difficult. pytest happy execute vanilla unittest testcases.


also please explain in answer best way use instead of yield driver instance.

here's had in mind ...

@pytest.fixture(scope="class") def onetimesetup(request, browser):     print("running 1 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 not none:         request.cls.driver = driver 

... notice doesn't return (or yield) driver object, means it's no longer useful provide fixture named parameter function/method, should fine if of test cases written classes (suggested examples).

however, if want use fixture named parameter, don't this.


Comments

Popular posts from this blog

wordpress - (T_ENDFOREACH) php error -

Export Excel workseet into txt file using vba - (text and numbers with formulas) -

Using django-mptt to get only the categories that have items -