I am using sample code with unittest but I receive an error when I execute it -- 'str' object has no attribute 'get'.

I searched Google but did not get an answer.

from selenium import webdriver
import unittest

class google1search(unittest.TestCase):
    driver = 'driver'

    @classmethod
    def setupClass(cls):
        cls.driver = webdriver.Chrome(chrome_options=options)
        cls.driver.implicitly_wait(10)
        cls.driver.maximize_window()

    def test_search_automationstepbystep(self):
        self.driver.get("https://google.com")
        self.driver.find_element_by_name("q").send_keys("Automation Step By step")
        self.driver.find_element_by_name("btnk").click()

    def test_search_naresh(self):
        self.driver.get("https://google.com")
        self.driver.find_element_by_name("q").send_keys("Naresh")
        self.driver.find_element_by_name("btnk").click()

    @classmethod
    def teardownClass(cls):
        cls.driver.close()
        cls.driver.quit()
        print("Test completed")

if __name__== "__main__":
    unittest.main()

Supposed to execute 2 steps and give result pass.

2 Answers

1
sarthak gupta On

In the above code : There is no initialization of self.driver for

self.driver.get("https://google.com")

as the driver initiated is for

cls.driver = webdriver.Chrome(chrome_options=options)

please replace cls with self

1
Andrii Nikolaienko On

I want to extend @sarthak response little bit. In the sample code methods setUpClass and tearDownClass are used. These methods are called to prepare test class and called only once before executing all test in your test class.

Which can work in your case because at the beginning of each test you're overwriting internal state of the driver object and your previous test execution shouldn't affect your next test result. In this case you need to modify your tests to use class object:

def test_search_automationstepbystep(self):
    TestClass.driver.get("https://google.com")
    TestClass.driver.find_element_by_name("q").send_keys("Automation Step By step")
    TestClass.driver.find_element_by_name("btnk").click()


def test_search_naresh(self):
    TestClass.driver.get("https://google.com")
    TestClass.driver.find_element_by_name("q").send_keys("Naresh")
    TestClass.driver.find_element_by_name("btnk").click()

Where TestClass is the name of your test class.

The other option is to use setUp and tearDown methods to initialize driver object before each test case:

def setUp(self):
    self.driver = webdriver.Chrome(chrome_options=options)
    self.driver.implicitly_wait(10)
    self.driver.maximize_window()

def tearDown(self):
    self.driver.close()
    self.driver.quit()
    print("Test completed")

Both setUp and tearDown methods accept instance of TestClass as self argument and your tests should work without any additional changes.

Note: Usually second option is preferable for unit testing, cause you don't need to make sure in every test that you overwrite driver internal state before using find_element_by_name. And in second option you can put self.driver.get("https://google.com") code into setUp method, cause it's going to be executed before each test case anyway.