💻 Примеры: requests в действии

← К оглавлению урока

⚡ Ключевые примеры

# test_api_quick.py
import requests

BASE_URL = "http://5.101.50.27:8000"

# 1. GET-список
resp = requests.get(BASE_URL + "/company/list")
assert resp.status_code == 200
companies = resp.json()  # list[dict]

# 2. POST-авторизация
resp = requests.post(BASE_URL + "/auth/login",
                     json={"username": "harrypotter", "password": "expelliarmus"})
token = resp.json()["user_token"]

# 3. POST-создание
resp = requests.post(BASE_URL + "/company/create",
                     json={"name": "ITCH", "description": "курсы"})
assert resp.status_code == 201
new_id = resp.json()["id"]

Пример 1: первый тест — GET-список компаний

Из лекции: минимальный тест — отправить GET-запрос и проверить статус.

# test_x_clients.py
import requests

BASE_URL = "http://5.101.50.27:8000"


def test_get_company_list_status():
    """Шаг 1: проверяем только статус."""
    resp = requests.get(BASE_URL + "/company/list")
    assert resp.status_code == 200


def test_get_company_list_content_type():
    """Шаг 2: добавляем проверку заголовка Content-Type."""
    resp = requests.get(BASE_URL + "/company/list")
    assert resp.status_code == 200
    assert resp.headers["Content-Type"] == "application/json"


def test_get_company_list_body():
    """Шаг 3: проверяем название первой компании."""
    resp = requests.get(BASE_URL + "/company/list")
    response_body = resp.json()       # list[dict]
    first_company = response_body[0]  # первый элемент списка

    assert resp.status_code == 200
    assert resp.headers["Content-Type"] == "application/json"
    assert first_company["name"] == "QA Студия 'ТестировщикЪ'"

Пример 2: авторизация и получение токена

Из лекции: POST-запрос с JSON-телом, токен используется в защищённых запросах.

# test_x_clients.py
import requests

BASE_URL = "http://5.101.50.27:8000"


def test_auth():
    """Проверяем авторизацию и наличие токена в ответе."""
    creds = {
        "username": "harrypotter",
        "password": "expelliarmus"
    }
    resp = requests.post(BASE_URL + "/auth/login", json=creds)

    assert resp.status_code == 200
    assert resp.json()["user_token"] is not None

Пример 3: создание компании

# test_x_clients.py
import requests

BASE_URL = "http://5.101.50.27:8000"


def test_create_company():
    """Создание компании возвращает 201 и ID новой компании."""
    company_data = {
        "name": "python",
        "description": "requests"
    }
    resp = requests.post(BASE_URL + "/company/create", json=company_data)

    assert resp.status_code == 201  # 201 Created — компания успешно создана
    body = resp.json()
    assert "id" in body
    assert body["name"] == "python"
    assert body["is_active"] is True

Пример 4: тест с CompanyApi — создание и получение по ID

Из лекции: надёжный тест сначала создаёт компанию, потом получает её по ID — не использует хардкод ID.

# test_x_clients.py
from company_api import CompanyApi

BASE_URL = "http://5.101.50.27:8000"


def test_get_one_company():
    """Создаём компанию и получаем её по ID — проверяем данные."""
    api = CompanyApi(BASE_URL)

    name = "PyCharm"
    descr = "IDE"
    result = api.create_company(name, descr)
    new_id = result["id"]

    new_company = api.get_company(new_id)

    assert new_company["name"] == name
    assert new_company["description"] == descr
    assert new_company["is_active"] is True

Пример 5: тест на удаление компании

Из лекции: тест создаёт компанию, проверяет её существование, удаляет, затем проверяет, что список уменьшился.

# test_x_clients.py
from company_api import CompanyApi

BASE_URL = "http://5.101.50.27:8000"


def test_delete_company():
    """Тест: удаление компании уменьшает список на 1."""
    api = CompanyApi(BASE_URL)

    # 1. Создаём компанию
    result = api.create_company("Company to be deleted", "Delete me")
    company_id = result["id"]

    # 2. Проверяем, что компания создана корректно
    new_company = api.get_company(company_id)
    assert new_company["name"] == "Company to be deleted"
    assert new_company["is_active"] is True

    # 3. Запоминаем количество до удаления
    len_before = len(api.get_company_list())

    # 4. Удаляем компанию
    api.delete_company(company_id)

    # 5. Проверяем, что список уменьшился
    len_after = len(api.get_company_list())
    assert len_before - len_after == 1

Пример 6: деактивация компании

# test_x_clients.py
from company_api import CompanyApi

BASE_URL = "http://5.101.50.27:8000"


def test_deactivate_company():
    """Тест: деактивация компании меняет is_active на False."""
    api = CompanyApi(BASE_URL)

    result = api.create_company("Company to be deactivated")
    company_id = result["id"]

    body = api.set_active_state(company_id, False)

    assert body["is_active"] is False

Пример 7: разница text vs json()

# demo_text_vs_json.py
import requests

resp = requests.get("https://jsonplaceholder.typicode.com/posts/1")

# resp.text — строка str, даже если это JSON
print(type(resp.text))   # 
print(resp.text[:50])    # '{\n  "userId": 1,\n  "id": 1,...'

# resp.json() — автоматически парсит в dict
data = resp.json()
print(type(data))        # 
print(data["title"])     # 'sunt aut facere repellat...'

# Нельзя: resp.text["title"] -> TypeError: string indices must be integers
# Нужно:  resp.json()["title"] -> работает корректно

Пример 8: практическое задание из лекции — reqres.in

⚠️ С 2024 года reqres.in требует бесплатный ключ x-api-key: reqres-free-v1 в заголовке — иначе 401. Передаём HEADERS в каждый запрос.
# test_reqres.py
import requests
import pytest

BASE_URL = "https://reqres.in/api/users"
HEADERS = {"x-api-key": "reqres-free-v1"}  # бесплатный ключ reqres.in (с 2024)


@pytest.mark.parametrize("user_id, expected_first, expected_last, expected_email", [
    (2, "Janet", "Weaver", "janet.weaver@reqres.in"),
])
def test_get_existing_user(user_id, expected_first, expected_last, expected_email):
    """Тест: получение данных существующего пользователя."""
    response = requests.get(f"{BASE_URL}/{user_id}", headers=HEADERS)

    assert response.status_code == 200, f"Ожидался статус 200, получен {response.status_code}"

    data = response.json()
    assert "data" in data, "Ответ API не содержит ключ 'data'"

    user = data["data"]
    assert user["id"] == user_id
    assert user["first_name"] == expected_first
    assert user["last_name"] == expected_last
    assert user["email"] == expected_email


def test_get_non_existing_user():
    """Тест: несуществующий пользователь возвращает 404."""
    response = requests.get(f"{BASE_URL}/23", headers=HEADERS)
    assert response.status_code == 404
    assert response.text == "{}"