Рефакторинг с использованием декораторов для уменьшения объема кода

88
12

Недавно я переключился на новый проект, и все наши тесты selenium написаны на Python. Мне было интересно, могу ли я уменьшить объем кода с помощью декораторов


что мы получили прямо сейчас:


class BasePage(object):
view_button = ".//a[text()='View']"
create_button = ".//a[text()='Create']"
#some code here

class BaseTestCase(unittest.TestCase):
setUpclass(cls):
#code here

def find(cls,xpath):
return cls.driver.find_element_by_xpath(xpath)

class SomeTest(BaseTestCase):
def test_00_something(self):
self.find(self.view_button).click()


Я думаю, есть ли способ свести к минимуму все это self.find(self.view_button).click() во что-то вроде click.view_button


Я слышал, что это можно сделать с помощью декораторов, но, будучи человеком Java, у меня был небольшой успех.

спросил(а) 2021-01-27T23:35:18+03:00 2 месяца, 2 недели назад
1
Решение
76

вы также можете проверить следующее решение; Создайте новый модуль - navigation.py с помощью:


class Button():

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

@property
def click(self):
return self.driver.find_element_by_xpath(self.locator).click()

class Navigation():

"""NAVIGATION COMMANDS """
def goTo(self):
#somethign

def previousPage(self):
#something

""" BUTTONS """
@property
def view_button(self):
xpath = ".//a[text()='View']"
view = Button(self.driver,xpath)
return view

@property
def create_button(self):
xpath = ".//a[text()='Create']"
create = Button(self.driver,xpath)
return create


В basetestcase.py:


class BaseTestCase(unittest.TestCase, Navigation)

setUpClass(cls):
#somethign here

и ваш тестовый пример будет выглядеть следующим образом:


class TestSomething(BaseTestCase):

def test_99_somethign(self):
#finds .//a[text()='View'] and clicks
self.view.click

#create button
self.create_button.click


Таким образом, вы сможете использовать класс навигации внутри своего теста. Кроме того, вы сохраняете все навигационные элементы в одном месте.

ответил(а) 2021-01-27T23:35:18+03:00 2 месяца, 2 недели назад
62

Я не уверен, как вы это сделаете, чтобы сделать click.view_button. Однако вы могли бы дать вам элемент своего класса. Таким образом вы можете достичь чего-то вроде view_button.click(). В моем проекте я делаю это для всех своих элементов.


class BaseElement:
def __init__(self, driver, locator):
self.driver = driver
self.locator = locator

def get(self):
self.driver.find_element(locator)

def click():
self.get().click()

class ViewButton(BaseElement):
def __init__(self, driver):
locator = (By.XPATH, ".//a[text()='View']")
super(ViewButton, self).__init__(driver, locator)

class BasePage(object):
def __init__(self, driver):
self.view_button = ViewButton(driver)

class BaseTestCase(unittest.TestCase):
setUpclass(cls):
# driver stuff
self.page = BasePage(driver)

class SomeTest(BaseTestCase):
def test_00_something(self):
self.page.view_button.click()

ответил(а) 2021-01-27T23:35:18+03:00 2 месяца, 2 недели назад
62

благодаря сообщению от RemcoW я нашел решение, см. ниже


class ViewButton():

def __init__(self,driver):
self.driver = driver
self.locator = (".//a[text()='View']")

@property
def click(self):
return self.driver.find_element_by_xpath(self.locator).click()

class BaseTestCase(unittest.TestCase):
#some code here

@property
def view(self):
view = ViewButton(self.driver)
return view

в тестовых случаях он работает следующим образом


class TestThign(BaseTestCase):

def test_00_something(self):
self.view.click

ответил(а) 2021-01-27T23:35:18+03:00 2 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема