← Назад к вопросам

Написать API тест

2.0 Middle🔥 121 комментариев
#API тестирование#Теория тестирования

Условие

Напишите тест для REST API endpoint POST /api/users, который создает нового пользователя.

Request body:

{
  "name": "John",
  "email": "john@test.com"
}

Expected response: 201 Created

Требования

  • Использовать requests или REST Assured
  • Проверить статус код
  • Проверить структуру ответа
  • Добавить негативные тест-кейсы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Решение

Анализ требований

Нужно написать тесты для endpoint POST /api/users, который создает пользователя. Требуется:

  • Позитивный тест (201 Created)
  • Проверка структуры ответа
  • Негативные тесты (валидация)

Решение 1: Используя requests и pytest (Python)

import requests
import pytest
from jsonschema import validate

BASE_URL = "http://api.example.com"
ENDPOINT = "/api/users"

USER_SCHEMA = {
    "type": "object",
    "properties": {
        "id": {"type": "integer"},
        "name": {"type": "string"},
        "email": {"type": "string"}
    },
    "required": ["id", "name", "email"]
}

class TestCreateUser:
    
    def test_create_user_success(self):
        payload = {
            "name": "John",
            "email": "john@test.com"
        }
        
        response = requests.post(
            f"{BASE_URL}{ENDPOINT}",
            json=payload
        )
        
        assert response.status_code == 201
        data = response.json()
        validate(instance=data, schema=USER_SCHEMA)
        assert data["name"] == "John"
        assert data["email"] == "john@test.com"
    
    def test_create_user_missing_name(self):
        payload = {"email": "john@test.com"}
        response = requests.post(f"{BASE_URL}{ENDPOINT}", json=payload)
        assert response.status_code == 400
    
    def test_create_user_missing_email(self):
        payload = {"name": "John"}
        response = requests.post(f"{BASE_URL}{ENDPOINT}", json=payload)
        assert response.status_code == 400
    
    def test_create_user_invalid_email(self):
        payload = {
            "name": "John",
            "email": "invalid-email"
        }
        response = requests.post(f"{BASE_URL}{ENDPOINT}", json=payload)
        assert response.status_code == 400
    
    def test_create_user_duplicate_email(self):
        payload = {
            "name": "John",
            "email": "existing@test.com"
        }
        response = requests.post(f"{BASE_URL}{ENDPOINT}", json=payload)
        assert response.status_code == 409
    
    def test_create_user_empty_name(self):
        payload = {
            "name": "",
            "email": "john@test.com"
        }
        response = requests.post(f"{BASE_URL}{ENDPOINT}", json=payload)
        assert response.status_code == 400

Решение 2: С использованием fixtures

import pytest
import requests

BASE_URL = "http://api.example.com"

@pytest.fixture
def api_client():
    class APIClient:
        def __init__(self, base_url):
            self.base_url = base_url
            self.session = requests.Session()
        
        def create_user(self, name, email):
            payload = {"name": name, "email": email}
            return self.session.post(
                f"{self.base_url}/api/users",
                json=payload
            )
    
    return APIClient(BASE_URL)

class TestUserAPI:
    
    def test_create_user_success(self, api_client):
        response = api_client.create_user("John", "john@test.com")
        assert response.status_code == 201
        assert response.json()["name"] == "John"
    
    def test_create_user_invalid_email(self, api_client):
        response = api_client.create_user("John", "not-an-email")
        assert response.status_code == 400

Решение 3: REST Assured (Java)

import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class UserAPITest {
    
    @Test
    public void testCreateUserSuccess() {
        String payload = "{ \"name\": \"John\", \"email\": \"john@test.com\" }";
        
        given()
            .header("Content-Type", "application/json")
            .body(payload)
        .when()
            .post("http://api.example.com/api/users")
        .then()
            .statusCode(201)
            .body("name", equalTo("John"))
            .body("email", equalTo("john@test.com"));
    }
    
    @Test
    public void testCreateUserMissingEmail() {
        String payload = "{ \"name\": \"John\" }";
        
        given()
            .header("Content-Type", "application/json")
            .body(payload)
        .when()
            .post("http://api.example.com/api/users")
        .then()
            .statusCode(400);
    }
}

Позитивные тесты

  • Успешное создание с валидными данными
  • Проверка статус кода 201
  • Проверка структуры ответа (наличие всех полей)
  • Проверка возвращаемых данных

Негативные тесты

  • Отсутствует обязательное поле (name или email)
  • Невалидный email формат
  • Дублирующийся email (409 Conflict)
  • Пустые значения
  • Очень длинные строки
  • Спецсимволы и XSS попытки
  • SQL injection в name/email

Граничные тесты

  • Максимальная длина имени
  • Минимальная длина имени
  • Специальные символы: @, #, !
  • Unicode символы: кириллица, иероглифы
  • Пробелы в начале/конце

Лучшие практики

  1. Используйте фикстуры для переиспользуемого кода
  2. Параметризуйте тесты для похожих сценариев
  3. Проверяйте структуру ответа через JSON schema
  4. Логируйте запросы и ответы для дебага
  5. Используйте правильные HTTP коды в assertions
  6. Тестируйте таймауты для долгих операций
  7. Проверяйте заголовки (Content-Type, etc)

Запуск тестов

# Python
pytest test_api.py -v --tb=short

# Java
mvn test -Dtest=UserAPITest
Написать API тест | PrepBro