Как справиться с различиями в коде между dev и prod? - PullRequest
0 голосов
/ 21 июня 2020

Вероятно, это будет длинный вопрос, так что заранее извиняюсь.

Вот моя ситуация, я надеюсь, вы, ребята, сможете направить меня на правильный путь:

Сенарио: Я есть 2 основных файла, назовем их app-prod.py и app-dev.py. Оба (программных?) Файла используют Selenium для очистки веб-сайтов, один - это основной сайт (рабочий), а другой - сайт разработчика (локальный). app-prod.py требуется некоторый код входа (имя пользователя, пароль и код авторизации), и он должен сообщить Selenium, что нужно нажимать определенные кнопки, которые есть только на рабочем сайте.

app-dev.py не нужна аутентификация или инструкции для навигации, потому что сайты не совпадают. Сайт разработчика - это всего лишь несколько html таблиц, которые имитируют c сайт продукта, но без всякого входа в систему.

Пример производственного кода:

# app-prod.py

"""open browser to base url, login and get ready
logic to login and go to the right page goes here"""



base_url = config[env]["base_url"]

browser = Firefox()

browser.get(base_url)

print("Sleeping for 5 to let page load")
time.sleep(5)

# LOGIN SCRIPT

auth = input("Enter Auth Code: ")
username = "LETMEIN"
password = "P@55W@rD"

browser.find_element_by_xpath('//*[@id="username"]').send_keys(username)
browser.find_element_by_xpath('//*[@id="password_input"]').send_keys(password)
browser.find_element_by_xpath('//*[@id="secondary_password_input"]').send_keys(auth)
browser.find_element_by_xpath('//input[@name="Login"]').click()

print("Sleeping for 3 to let page load")
time.sleep(3)

# Click OK button on alert
browser.find_element_by_xpath('//input[@value="Continue"]')

class Table:
    def __init__(self, vls, name, intro):
**********

Пример кода разработчика:

# app-dev.py

"""open browser to base url, login and get ready
logic to login and go to the right page goes here"""


base_url = config[env]["base_url"]

browser = Firefox()

browser.get(base_url)


class Table:
    def __init__(self, vls, name, intro):
**********

Моя проблема - отслеживать 2 разных файла. Если я работаю над кодом разработчика, мне придется добавлять все изменения в файл prod, стараясь не испортить часть кода входа в систему. В настоящее время я использую VS Code для сравнения двух файлов, а затем копирую / вставляю различия между dev и prod, что работает, но немного утомительно.

Я попытался сделать раздел входа в систему модульным и импортировать его, но он жалуется, что "браузер" не определен (потому что веб-драйвер инициализируется в приложении - файл *. py).

Я думал, что когда вы импортировали модуль, он возьмет все в "import_me.py" и поместите его в app-dev.py, чтобы любой код в модуле мог использовать любой из импортированных в основной файл приложения, но, похоже, это не работает таким образом. Это похоже на то, как если бы python запускал модуль в собственном небольшом разделе как отдельный файл, без взаимодействия с основным файлом.

Итак, моей следующей мыслью было посмотреть, есть ли способ создать шаблон приложения -dev.py, чтобы я мог сказать:

here is some dev code blah blah blah. 
env='DEV'
if env == 'DEV'
    {{ include login code here that is imported from import_me.py}}
else:
    pass

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

Я используя configparser для изменения URL-адресов и путей к файлам, но я не думаю, что он может обрабатывать блоки кода, по крайней мере, я нигде не видел этого в документации.

Как вы, ребята, решаете такие проблемы ? Я не занимался программированием очень долго, поэтому, возможно, я пропустил пакет, который исправит это, но на данный момент у меня нет идей.

Любая помощь, которую вы можете мне оказать, очень признательна и надеюсь, я стану лучшим программистом!

Если вы дошли до этого места, спасибо! Имейте виртуального повара ie:)

TL; DR: нужен способ включить блок кода из файла 1 в определенную c область файла 2 с файлом 1, совместно использующим весь импорт файла 2, как если бы он был жестко закодирован во время выполнения.

**** РЕДАКТИРОВАТЬ ДЛЯ ДОПОЛНИТЕЛЬНОЙ ИНФОРМАЦИИ **** Я посмотрю, как отправить код завтра, так как его нет передо мной сейчас. Вот что я делаю: настройте Selenium для открытия веб-страницы, войдите в систему (в коде продукта), а затем приготовьтесь выполнить парсинг.

Возьмите файл Excel и получите идентификационный номер и имя, поместите его в по l oop на каждого указанного человека. Затем для каждого человека отправьте идентификационный номер и имя в класс, который я создал, который будет очищать таблицы с сайта.

Класс имеет 5 разделов, по 1 разделу для каждой таблицы. Каждая таблица имеет свой URL-адрес, который выглядит как {base_url} / {path_to_table} / {ID} (упрощенно по памяти). Затем он сообщает веб-драйверу go по этому URL-адресу, очищает его и отправляет эти данные в docx-tpl. Он открывает имеющийся у меня файл шаблона docx, а затем генерирует новый файл в зависимости от даты, когда он был загружен.

Это основа цикла / класса. Проблема в том, что URL-адреса разных prod и dev различаются, логин отличается (не существует в dev), и я уверен, что есть еще несколько отличий, о которых я забываю.

Я посмотрю, смогу ли я завтра выложить в Интернете какой-нибудь код, который поможет вам, ребята, увидеть, сколько ошибок я делаю: D

1 Ответ

1 голос
/ 21 июня 2020

Я думаю, вы неправильно понимаете, как работают модули Python. Я бы подошел к этому, чтобы реализовать сценарий со следующей структурой:

base-dir/
  setup.py <-- with entrypoints and dependencies defined
  README.md
  other_files.txt
  main_module/
    __init__.py <-- this marks it as a module
    scrape.py <-- shared code
    dev_specific.py
    prod_specific.py

Таким образом, если вы настроили виртуальную среду и используете сценарий entrypoint , вы будете в указанном вами контексте и сможете импортировать и ссылаться на код как обычно. Вы можете подойти к разделению кода env-specifici c несколькими способами; самый простой - использовать условный вентиль, например:

if args.env == "production":
    prod_specific.perform_login()

Код, определенный в другом модуле, не будет иметь доступ к коду или переменным в вызывающем модуле; вам нужно будет передать любую соответствующую информацию в качестве параметров функции. Не думайте, что включенный код «втягивается» в другой модуль; воспринимайте это как ссылку на этот код, доступный для кода в этом модуле.

...