0

I have implemented the selenium python framework using unittest and pytest with the page object model. I have created a conftest.py file with oneTimeSetup method which will initialize the webdriver and then it will be used by all my test files. Below is the approach I've used. I have created the webdriver factory like this below

WebDriverFactory.py:

from selenium import webdriver
class WebDriverFactory():
    def __init__(self,browser):
        self.browser = browser

    def get_browser_instance(self):
        if self.browser == "FF":
            driver = webdriver.Firefox()

        elif self.browser == "Chrome":
            driver = webdriver.Chrome()

        elif self.browser == "IE":
            driver = webdriver.Ie()

        else:
            driver = webdriver.Chrome()


        baseUrl = "http://live.demoguru99.com/index.php/"
        driver.delete_all_cookies()
        driver.maximize_window()
        driver.implicitly_wait(5)
        driver.get(baseUrl)

        return driver

conftest.py:

import pytest
from base.WebDriverFactory import WebDriverFactory

def pytest_addoption(parser):
    parser.addoption("--browser")

@pytest.fixture(scope="session")
def browser(request):
    return request.config.getoption("--browser")

@pytest.fixture(scope="session")
def oneTimeSetup(request,browser):
    print("This is one time setup")
    wdf = WebDriverFactory(browser)
    driver = wdf.get_browser_instance()

    if request.cls is not None:
        request.cls.driver = driver

    yield driver
    driver.quit()
  

Below is my test file:

from pages.mobile_page.mobile_page import MobilePage
from utilities.mark_test_status import MarkTestStatus
import unittest
import pytest

@pytest.mark.usefixtures("oneTimeSetup")
class TestMobile(unittest.TestCase):

    @pytest.fixture(autouse=True)
    def classObject(self,oneTimeSetup):
        self.mb = MobilePage(self.driver)
        self.ts = MarkTestStatus(self.driver)

    def test_Mobile(self):
        result = self.mb.mobile()
        self.ts.finalMark(testcase="Mobile Sort By test",result=result,resultMessage="Testing Mobile SOrt functionality")

I am getting the below error when running the test in cmd. cmd

If I change the scope for my oneTimeSetup to "class" in conftest.py, the test runs fine. But I am looking to run all mt test's in a single webdriver session when I add more tests.

Details: Selenium Python v 3.1.41.0 Chrome 86.0.4240.111 pytest 6.0.1

hoefling
  • 59,418
  • 12
  • 147
  • 194
Atique
  • 45
  • 6
  • Well, the message says it all: the `request` fixture has the `cls` attribute set only if the caller fixture is class-scoped. You should be able to enhance the check with smth like `if hasattr(request, "cls") and request.cls is not None:` though. – hoefling Nov 06 '20 at 11:16
  • Thanks I added below if hasattr(request, "cls") and request.cls is not None: request.cls.driver = driver and it worked. However I didnt understand what made the difference. Could you explain the significance of it please? – Atique Nov 06 '20 at 19:22

1 Answers1

0

oneTimeSetup fixture is session level and session level request parameter does not have cls attribute. So rather than accessing request.cls like this

if request.cls is not None:
    request.cls.driver = driver

use request.node.items and setattr for individual item like this

session = request.node
for item in session.items:
    cls = item.getparent(pytest.Class)
    setattr(cls.obj, "driver", driver)
Utsav Patel
  • 319
  • 1
  • 5
  • 14