⚖️ Старый vs Новый подход
⚡ Главные эволюции
- Хардкод URL в тестах →
BASE_URLпеременная → класс сself.url resp.text+ ручной разбор →resp.json()напрямую- Запросы разбросаны по тестам → класс-обёртка
CompanyApi - Проверка статуса после каждого вызова → проверка внутри метода класса
Сравнение 1: хардкод URL → base_url → класс
Из лекции (начальный подход) — URL в каждом тесте
# test_v1_hardcode.py
import requests
def test_get_companies():
resp = requests.get("http://5.101.50.27:8000/company/list") # хардкод
assert resp.status_code == 200
def test_auth():
resp = requests.post("http://5.101.50.27:8000/auth/login", # хардкод снова
json={"username": "harrypotter", "password": "expelliarmus"})
assert resp.status_code == 200
Проблема: при смене сервера или порта нужно менять URL в каждом тесте вручную.
Из лекции (улучшение) — переменная base_url
# test_v2_base_url.py
import requests
base_url = "http://5.101.50.27:8000" # один раз вверху файла
def test_get_companies():
resp = requests.get(base_url + "/company/list")
assert resp.status_code == 200
def test_auth():
resp = requests.post(base_url + "/auth/login",
json={"username": "harrypotter", "password": "expelliarmus"})
assert resp.status_code == 200
Современный подход — класс CompanyApi
# company_api.py
import requests
class CompanyApi:
def __init__(self, url):
self.url = url # URL хранится в объекте, легко переопределить
def get_company_list(self):
resp = requests.get(self.url + "/company/list")
assert resp.status_code == 200
return resp.json()
# test_v3_class.py
from company_api import CompanyApi
BASE_URL = "http://5.101.50.27:8000"
def test_get_companies():
api = CompanyApi(BASE_URL)
companies = api.get_company_list()
assert len(companies) > 0
Преимущества класса: URL в одном месте; методы переиспользуются; тест не знает деталей HTTP-вызова.
Сравнение 2: resp.text vs resp.json()
Устаревший способ — ручной разбор через text
# Из лекции: так делать неудобно
import requests
import json
resp = requests.get("http://5.101.50.27:8000/company/list")
# resp.text — строка, нужно вручную вызывать json.loads()
body = json.loads(resp.text)
first_name = body[0]["name"] # работает, но verbose
Современный способ — resp.json()
# Рекомендуется: requests делает разбор за нас
import requests
resp = requests.get("http://5.101.50.27:8000/company/list")
body = resp.json() # сразу dict/list, без json.loads()
first_name = body[0]["name"] # чище и короче
Когда всё же нужен resp.text: если сервер возвращает не JSON (XML, HTML, plain text), или для отладки — вывести сырой ответ.
Сравнение 3: повторение кода запроса в тестах → инкапсуляция
Из лекции: дублирование в каждом тесте
# test_duplicated.py — плохой паттерн
import requests
BASE_URL = "http://5.101.50.27:8000"
def test_create_company_increases_count():
# Получаем список ДО
resp = requests.get(BASE_URL + "/company/list")
assert resp.status_code == 200
initial_count = len(resp.json())
# Создаём компанию
resp2 = requests.post(BASE_URL + "/company/create",
json={"name": "Test", "description": "desc"})
assert resp2.status_code == 201
# Получаем список ПОСЛЕ
resp3 = requests.get(BASE_URL + "/company/list")
assert resp3.status_code == 200
assert len(resp3.json()) == initial_count + 1
Современный подход — метод класса
# test_clean.py — с CompanyApi
from company_api import CompanyApi
BASE_URL = "http://5.101.50.27:8000"
def test_create_company_increases_count():
api = CompanyApi(BASE_URL)
initial_count = len(api.get_company_list()) # статус проверяется внутри метода
api.create_company("Test", "desc")
assert len(api.get_company_list()) == initial_count + 1
Результат: тест в 3 строки вместо 12; проверки статусов — внутри класса; читаемость максимальная.
Сравнение 4: фиксированный ID → динамический
Ненадёжный тест с хардкод-ID (из лекции: так делать нельзя)
# Плохо: ID может не существовать или измениться
def test_get_company_bad():
resp = requests.get(BASE_URL + "/company/7") # ID 7 может не быть!
assert resp.status_code == 200
Надёжный тест: создаём компанию, берём ID из ответа
# Хорошо: ID получаем из ответа на создание
def test_get_company_good():
api = CompanyApi(BASE_URL)
result = api.create_company("Dynamic Company", "no hardcode")
new_id = result["id"] # ID из ответа, не из головы
company = api.get_company(new_id)
assert company["name"] == "Dynamic Company"