Attribute error: Object has no attribute 'driver'

107 Views Asked by At

I am trying to set up test framework for a simple test to count the search results for a word on google.com. Here is how my framework looks:

repo
 |-pages
 |   |-google_launch_page.py
 |   |-google_search_results.py
 |
 |-tests
 |   |-conftest.py
 |   |-test_google.py
 |-conftest.py

Here is the test_google.py:

from selenium.webdriver.common.by import By
from pages.google_launch_page import LaunchPage
from pages.google_search_results_page import SearchResultPage
import time, re, pytest

@pytest.mark.usefixtures("setup")
class testgooglesite():
    def test_search_results(self):
        lp = LaunchPage(self.driver)
        lp.clickSearch("Chocolate")
        # test 1: there should be non-zero results
        result_element = self.driver.find_element(By.XPATH, "//div[@id='result-stats']")
        result_text = result_element.text
        numbers = re.findall(r'\d{1,3}(?:\s?\d{3})*', result_text)[0]
        result_count = int(''.join(numbers[0]))
        self.driver.close()
        assert result_count>0,"No results"

myobj = testgooglesite()
myobj.test_search_results()

And here is the tests/conftest.py (repo/conftest.py is empty):

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import pytest

@pytest.fixture(scope="class")
def setup(request):
    service = Service()
    options = webdriver.ChromeOptions()

    driver = webdriver.Chrome(service=service, options=options)
    driver.get('https://google.com/')
    webdriver.wait(driver,5)
    driver.maximize_window()
    request.cls.driver = driver

Finally, here is the error message:

tests\test_google.py:16: in test_search_results
    lp = LaunchPage(self.driver)
E   AttributeError: 'testgooglesite' object has no attribute 'driver'

I am assuming that pytest is likely overlooking conftest.py but I am unable to figure out the reason. Can someone please help?

Based on one suggestion in the comments, I have tried the following conftest.py:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import pytest

@pytest.fixture(scope="class", autouse=True)
def driver(request):
    service = Service()
    options = webdriver.ChromeOptions()

    driver = webdriver.Chrome(service=service, options=options)
    driver.get('https://google.com/')
    webdriver.wait(driver,5)
    driver.maximize_window() 
    request.cls.driver = driver
    yield driver

And the test file:

from selenium.webdriver.common.by import By
from pages.google_launch_page import LaunchPage
from pages.google_search_results_page import SearchResultPage
import time, re, pytest

# @pytest.mark.usefixtures("driver")
class testgooglesite():
    def test_search_results(self):
        lp = LaunchPage(driver)
        lp.clickSearch("Chocolate")
        # test 1: there should be non-zero results
        # find the corresponding element
        result_element = driver.find_element(By.XPATH, "//div[@id='result-stats']")
        result_text = result_element.text
        print(result_text)
        numbers = re.findall(r'\d{1,3}(?:\s?\d{3})*', result_text)[0]
        result_count = int(''.join(numbers[0]))
        driver.close()
        assert result_count>0,"No results"

myobj = testgooglesite()
myobj.test_search_results()

Here, I tried to replace the fixture by yielding the driver and modifying the fixture to do autouse=True. But this gives me the error that E NameError: name 'driver' is not defined.

1

There are 1 best solutions below

0
Chinmay Sharma On

Thanks to @MrBean Bremen, I found the error in my code. It was simply using the Class name in lowercase. It should be class TestGoogleSite instead of the usual class testgooglesite. It is necessary to start with Test whenever the class lacks an __init__() method(read here).

The following code works:

test_google.py

from selenium.webdriver.common.by import By
from pages.google_launch_page import LaunchPage
from pages.google_search_results_page import SearchResultPage
import time, re, pytest

@pytest.mark.usefixtures("setup")
class TestGoogleSite():
    def test_search_results(self):
        lp = LaunchPage(self.driver)
        lp.clickSearch("Chocolate")
        # test 1: there should be non-zero results
        result_element = self.driver.find_element(By.XPATH, "//div[@id='result-stats']")
        result_text = result_element.text
        numbers = re.findall(r'\d{1,3}(?:\s?\d{3})*', result_text)[0]
        result_count = int(''.join(numbers[0]))
        self.driver.close()
        assert result_count>0,"No results"

and conftest.py:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import pytest

@pytest.fixture(scope="class")
def setup(request):
    service = Service()
    options = webdriver.ChromeOptions()

    driver = webdriver.Chrome(service=service, options=options)
    driver.get('https://google.com/')
    webdriver.wait(driver,5)
    driver.maximize_window()
    request.cls.driver = driver