Урок переносить URL, email і пароль з тестового коду в локальний `.env`, завантажує їх через `python-dotenv`, а потім централізує конфігурацію у session-scoped pytest fixture. Наприкінці показано amend останнього коміту; це корисно для локальної історії, але переписування вже опублікованої гілки потребує обережності.
Примітка: конспект укладено за автоматичними українськими субтитрами; назви API та файлів нормалізовано за контекстом відео.
Після цього уроку ви зможете
Виносити локальну test configuration з коду в environment variables.
Завантажувати .env через python-dotenv і явно перевіряти обов’язкові значення.
Централізувати session configuration у conftest.py fixture.
Розрізняти amend локального commit і ризик переписування remote history.
Автотести розглядаються як застосунок, якому потрібна конфігурація: базові URL, email, пароль та інші параметри запуску. У корені проєкту створюється .env, а імена незмінних конфігурацій записуються в UPPER_SNAKE_CASE, наприклад BASE_URL, EMAIL, PASSWORD.
.env і .venv додаються до .gitignore. Сірий файл в IDE означає, що Git його не відстежує. Важливе уточнення: .gitignore діє лише на невідстежувані файли. Якщо .env уже був закомічений, його треба прибрати з індексу; якщо секрет уже опублікований — також відкликати або змінити сам секрет.
Приклад коду
Fail-fast завантаження локальної конфігурації
import os
from pathlib import Path
from dotenv import load_dotenv
load_dotenv(Path(__file__).with_name(".env"))
required = ("BASE_URL", "EMAIL", "PASSWORD")
missing = [name for name in required if not os.getenv(name)]
if missing:
raise RuntimeError(f"Missing configuration: {', '.join(missing)}")
print(os.environ["BASE_URL"])
Приклад завантажує сусідній .env, перевіряє всі обов’язкові keys і завершується з явною помилкою, якщо конфігурація неповна.
Очікуваний результат: Для підготовленого .env друкується https://example.test; при відсутньому key виникає RuntimeError.
Потрібно: python-dotenv
Практика
Перевірити повну й неповну конфігурацію
Створіть локальний .env лише з test placeholders.
Запустіть loader з усіма required keys.
Видаліть один key і перевірте, що запуск падає з назвою відсутньої конфігурації.
Результат: Повна конфігурація проходить, неповна зупиняє тести до відкриття браузера.
Хардкоджені значення замінюються на os.getenv("BASE_URL"), os.getenv("EMAIL") і os.getenv("PASSWORD"). Для цього імпортується стандартний модуль os.
Плагін підтримки .env може дати IDE автодоповнення й підсвічування, але не є частиною виконання тестів. Реальне джерело значень — середовище процесу після завантаження .env.
Розглядаються два підходи: зберегти базовий домен і збирати адреси через f-string або одразу зберігати готові BASE_URL та BASE_APP_URL. Другий варіант обрано як простіший для поточної потреби: немає зайвої конкатенації та прихованих правил побудови адрес.
Приклад f-string — f"https://app.{domain}". Він корисний, коли частини адреси справді комбінуються у багатьох конфігураціях; створювати такий механізм лише «на майбутнє» суперечило б YAGNI.
Уточнення
Environment variables мають вищий пріоритет
Оскільки load_dotenv() не override-ить наявні environment variables за замовчуванням, CI або shell може без зміни .env надати іншу конфігурацію.
Термін
load_dotenv
load_dotenv() читає key-value pairs з .env і додає їх до environment; за замовчуванням уже наявні environment variables не перезаписуються.
Сам файл .env не потрапляє в os.environ автоматично. Додається пакет python-dotenv, викликається load_dotenv(), після чого os.getenv() бачить локальні значення. Версію залежності фіксують у requirements.txt.
Після зміни запускаються всі наявні тести. Їх успішне проходження підтверджує, що перенесення конфігурації не змінило поточну поведінку сценаріїв.
Повторювані звернення до environment variables піднімаються у зрозумілі константи на рівні файлу: LOGIN_URL, EMAIL, PASSWORD. IDE Replace використовується для послідовної заміни старих виразів.
Автор свідомо не додає YAML, кілька конфігураційних класів чи систему environment-профілів. Поточна потреба — один передпродакшн стенд, тому достатньо .env. Розширення потрібне лише тоді, коли реально з’являться різні середовища з відмінними наборами параметрів.
Перед комітом створюється окрема гілка. До diff входять код завантаження конфігурації, .gitignore і залежність, але не локальний .env. Перед push ще раз перевіряється, що email і пароль не відстежуються.
Це важлива межа: .env захищає локальні секрети від випадкового Git tracking, але не є менеджером секретів для CI. У CI значення мають надходити з захищених variables/secrets платформи.
Щоб не повторювати load_dotenv() і читання змінних у кожному тестовому файлі, конфігурація переноситься в conftest.py. Pytest автоматично знаходить цей файл у відповідній директорії та робить fixtures доступними тестам нижче по дереву.
Створюється fixture конфігурації зі scope session. Вона обчислюється один раз на весь тестовий запуск і повертає набір значень, потрібних сценаріям.
Термін
Fixture scope
Pytest fixture зі scope session створюється один раз на test session, тому підходить для незмінної конфігурації всього запуску.
Тест отримує config як параметр так само, як page. На цьому етапі fixture повертає dictionary, тому значення читаються за ключами: URL для відкриття сторінки, email і пароль для авторизації.
Зміна проходить через реальний запуск тестів. Помилки на кшталт невірного імені fixture або відсутнього ключа знаходяться лише тоді, коли відповідний шлях справді виконується.
Під час запуску виправляються пропущене передавання config і неправильне звернення до значення. До залежностей додається відсутній пакет, код форматується, після чого спершу запускається цільовий тест, а потім весь наявний набір.
Цикл уроку: маленька зміна → запуск найближчого тесту → виправлення → ширший прогін. Так легше локалізувати причину, ніж накопичити кілька незалежних рефакторингів до першої перевірки.
Amend замінює останній коміт новою версією, що дозволяє додати забутий файл без окремого шумового коміту. Якщо попередній коміт уже запушено, його hash змінився, тому звичайний push відхиляється як non-fast-forward.
У відео показано force-push у власну feature-гілку й окремо застережено не робити цього в main. Практичне уточнення: безпечніший варіант — --force-with-lease, і лише коли правила репозиторію дозволяють переписування гілки та ніхто інший не базує на ній роботу. Якщо це не погоджено, простіше додати новий виправний коміт.
Що змінилося після запису
Force-push після amend
АктуальноДля вже опублікованої feature branch поточна Git documentation надає --force-with-lease як захисний варіант. Він не робить history rewrite безпечним автоматично: branch має бути персональною, а переписування — дозволеним командними правилами.
Перевірено 2026-07-31
Термін
--force-with-lease
--force-with-lease дозволяє update лише якщо remote ref має очікуване значення; це зменшує ризик затерти чужі commits порівняно з безумовним --force.