I have a fixture file.
import pytest
from selenium.webdriver.chrome.options import Options as chrome_options
from driver.singleton_driver import WebDriver
@pytest.fixture
def get_chrome_options():
options = chrome_options()
options.add_argument('chrome')
options.add_argument('--start-maximized')
options.add_argument('--window-size=1920,1080')
options.add_argument('--incognito')
return options
@pytest.fixture
def get_webdriver(get_chrome_options):
options = get_chrome_options
driver = WebDriver(options).driver
return driver
@pytest.fixture(scope='function')
def setup(request, get_webdriver):
driver = get_webdriver
if request.cls is not None:
request.cls.driver = driver
yield driver
driver.close()
File with my tests
import pytest
@pytest.mark.usefixtures('setup')
class TestSteamPages:
def test_first(self):
self.driver.get('https://www.google.com/')
def test_second(self):
self.driver.get('https://www.google.com/')
As I understand it, after the first test, the function in the driver.close() fixture is triggered. But when the second test is run, the fixture does not restart the webdriver. An error
venv/lib/python3.10/site-packages/selenium/webdriver/remote/errorhandler.py:243: InvalidSessionIdException
============================================================================== short test summary info ==============================================================================
FAILED tests/test_first.py::TestSteamPages::test_second -
selenium.common.exceptions.InvalidSessionIdException: Message: invalid session id
ERROR tests/test_first.py::TestSteamPages::test_second - selenium.common.exceptions.InvalidSessionIdException: Message: invalid session id
For the driver, I use the Singleton pattern
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
class WebDriver:
class __WebDriver:
def __init__(self, options):
self.driver = webdriver.Chrome(options=options, service=ChromeService(ChromeDriverManager().install()))
driver = None
def __init__(self, options):
if not self.driver:
WebDriver.driver = WebDriver.__WebDriver(options=options).driver
CodePudding user response:
The driver
is not reinitialized because of the singleton. WebDriver.driver
is initialized before first test, so in the next time setup
is running if not self.driver
is False
, because self.driver
is not None
anymore.
If you want to initialize the WebDriver
every test don't use singleton
@pytest.fixture
def get_webdriver(get_chrome_options):
options = get_chrome_options
driver = webdriver.Chrome(options=options, service=ChromeService(ChromeDriverManager().install()))
return driver
If you do want to initialize the WebDriver
only once you can change fixtures scope to 'class'
(for all tests in TestSteamPages
) or even move it to conftest.py
with scope 'session'
for one driver instance for all the test. Note that in this case all the fixtures need to have scope='class'
@pytest.fixture(scope='class')
def setup(request, get_webdriver):
driver = get_webdriver
if request.cls is not None:
request.cls.driver = driver
yield driver
driver.close()