Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Вызов значений словарей одной функции в другой функции


#1

Подскажите, пожалуйста,

Есть функция, в которой определён словарь

def click_up_menu(driver):
    items_of_up_menu = {'point1t':driver.find_element_by_xpath(".//*[@id='navigation']/div/ul/li[1]/a"),
                                    'point2':driver.find_element_by_xpath(".//*[@id='navigation']/div/ul/li[2]/a"),
                                    'point3':driver.find_element_by_xpath(".//*[@id='navigation']/div/ul/li[3]/a"),
                                    'point4':driver.find_element_by_xpath(".//*[@id='navigation']/div/ul/li[4]/a")}

внутри функции вызвать каждый элемент без проблем

Но как вызвать внутри другой функции
к примеру:

def test_clicking_menu(driver), в ней вызываю предыдущую функцию
       click_up_menu(driver)

но как далее работать с элементом и вернуть результат items_of_up_menu['point2'] не пойму

Подскажите, пожалуйста новичку


(Mykhailo Poliarush) #2

Вопрос мне не до конца понятен, честно. Все зависит, где должна использоваться структура items_of_up_menu. Но могу предположить что можно сделать через замыкание.

Например реализация через замыкание:

def test_clicking_menu(driver):
    # something before

    items_of_up_menu = {
        'point1':driver.find_element_by_xpath(".//*[@id='navigation']/div/ul/li[1]/a"),
        'point2':driver.find_element_by_xpath(".//*[@id='navigation']/div/ul/li[2]/a"),
        'point3':driver.find_element_by_xpath(".//*[@id='navigation']/div/ul/li[3]/a"),
        'point4':driver.find_element_by_xpath(".//*[@id='navigation']/div/ul/li[4]/a")
    }

    def click_up_menu(driver):
        # do something with item items_of_up_menu['point1']
        pass

    click_up_menu() # function execution call

    # do something with items_of_up_menu['point1']

Или возможно структуру данных надо будет сохранить где-то в экземпляре класса:

class TestSomething(object):
    items_of_up_menu = {
        'point1': ".//*[@id='navigation']/div/ul/li[1]/a",
        'point2': ".//*[@id='navigation']/div/ul/li[2]/a",
        'point3': ".//*[@id='navigation']/div/ul/li[3]/a",
        'point4': ".//*[@id='navigation']/div/ul/li[4]/a"
    }

    def test_clicking_menu(self, driver):
        driver.find_element_by_xpath(self.items_of_up_menu['point1'])

        def click_up_menu(driver):
            driver.find_element_by_xpath(self.items_of_up_menu['point2'])

        click_up_menu() # function execution call

        driver.find_element_by_xpath(self.items_of_up_menu['point3'])

Ну и конечно надо избавляться от плохого кода, т.е. дубликатов, четко видно что все локаторы поддаются какому-то одному принципу, поэтому код можно оптимизировать следующим образом.

class TestSomething(object):
    xpath = ".//*[@id='navigation']/div/ul/li[{}]/a"
    items_of_up_menu = lambda self, x: self.xpath.format(x)

    def test_clicking_menu(self, driver):
        driver.find_element_by_xpath(self.items_of_up_menu(1))

        def click_up_menu(driver):
            driver.find_element_by_xpath(self.items_of_up_menu(2))

        click_up_menu() # function execution call

        driver.find_element_by_xpath(self.items_of_up_menu(3))

Ну и могу сказать, что вам надо немного больше поразбираться с ООП в python. Рекомендую посмотреть http://lessons2.ru/lesson/preview/yunit-testirovanie-v-python/ и http://lessons2.ru/lesson/preview/ispolzovanie-modulej-i-paketov-v-python/


(ex3me0) #3

Вынести в отдельный класс, в котором реализовать необходимые методы.
Или может просто за пределы функции

class Something(object):
    items_of_up_menu = {'point1t':driver.find_element_by_xpath(".//*[@id='navigation']/div/ul/li[1]/a"),
                                    'point2':driver.find_element_by_xpath(".//*[@id='navigation']/div/ul/li[2]/a"),
                                    'point3':driver.find_element_by_xpath(".//*[@id='navigation']/div/ul/li[3]/a"),
                                    'point4':driver.find_element_by_xpath(".//*[@id='navigation']/div/ul/li[4]/a")}

    def __init__(self, driver):
        self.driver = driver

    def click_up_menu(item_locator):
        self.driver.click(item_locator)


>>> c = Something(driver)
>>> c.items_of_up_menu

#4

Спасибо за ответы.
Вынес за пределы функции.