Modern QA2026Основы gRPC
Join

Course14 API Testing Fundamentals

Foundations · Chapter 14

Основы gRPC

Updated Jul 2026

gRPC использует Protocol Buffers (protobuf) для определения схемы и HTTP/2 для транспорта. Он распространён в микросервисных архитектурах, где сервисы нуждаются в высокопроизводительной, типобезопасной коммуникации. Как QA-инженер, вы можете тестировать gRPC реже, чем REST, но понимание его становится всё более важным.

Чем gRPC отличается от REST

Аспект REST gRPC
Протокол HTTP/1.1 или HTTP/2 Только HTTP/2
Формат данных JSON (текст) Protocol Buffers (бинарный)
Схема Необязательная (OpenAPI) Обязательная (файлы .proto)
Генерация кода Необязательная Встроенная (генерирует клиентский/серверный код)
Стриминг Не нативный Нативный (серверный, клиентский, двунаправленный)
Поддержка браузера Нативная Требуется gRPC-Web прокси
Коды ошибок HTTP-коды состояния Коды состояния gRPC (своя система)

Protocol Buffers

Сервисы gRPC определяются в файлах .proto:

syntax = "proto3";

package user;

service UserService {
    rpc GetUser(GetUserRequest) returns (UserResponse);
    rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
    rpc CreateUser(CreateUserRequest) returns (UserResponse);
    rpc UpdateUser(UpdateUserRequest) returns (UserResponse);
    rpc DeleteUser(DeleteUserRequest) returns (Empty);
}

message GetUserRequest {
    string id = 1;
}

message UserResponse {
    string id = 1;
    string name = 2;
    string email = 3;
    string role = 4;
    string created_at = 5;
}

message ListUsersRequest {
    int32 page = 1;
    int32 per_page = 2;
}

message ListUsersResponse {
    repeated UserResponse users = 1;
    int32 total = 2;
}

Файл .proto — это контракт. И клиент, и сервер генерируют код из него, обеспечивая типобезопасность.

Исследование с grpcurl

grpcurl — это аналог curl для gRPC, необходимый для ручного исследования и отладки.

# List available services
grpcurl -plaintext localhost:50051 list

# List methods in a service
grpcurl -plaintext localhost:50051 list user.UserService

# Describe a method
grpcurl -plaintext localhost:50051 describe user.UserService.GetUser

# Call a method
grpcurl -plaintext -d '{"id": "123"}' localhost:50051 user.UserService/GetUser

# Call with headers (metadata)
grpcurl -plaintext \
    -H "Authorization: Bearer token123" \
    -d '{"id": "123"}' \
    localhost:50051 user.UserService/GetUser

# Call without TLS (-plaintext) for local development
# Call with TLS for staging/production (omit -plaintext)
grpcurl -d '{"id": "123"}' api.staging.example.com:443 user.UserService/GetUser

Тестирование gRPC с Python

import grpc
import user_pb2
import user_pb2_grpc

@pytest.fixture(scope="session")
def grpc_channel():
    channel = grpc.insecure_channel("localhost:50051")
    yield channel
    channel.close()

@pytest.fixture
def user_service(grpc_channel):
    return user_pb2_grpc.UserServiceStub(grpc_channel)

def test_get_user(user_service):
    request = user_pb2.GetUserRequest(id="123")
    response = user_service.GetUser(request)
    assert response.name == "Alice"
    assert response.email == "alice@test.com"

def test_get_nonexistent_user(user_service):
    request = user_pb2.GetUserRequest(id="nonexistent")
    with pytest.raises(grpc.RpcError) as exc_info:
        user_service.GetUser(request)
    assert exc_info.value.code() == grpc.StatusCode.NOT_FOUND

def test_create_user(user_service):
    request = user_pb2.CreateUserRequest(
        name="New User",
        email="new@test.com",
        role="viewer"
    )
    response = user_service.CreateUser(request)
    assert response.id != ""
    assert response.name == "New User"

Коды состояния gRPC

gRPC использует собственную систему кодов состояния, а не HTTP-коды:

Код gRPC Значение Эквивалент REST
OK Успех 200
INVALID_ARGUMENT Клиент отправил некорректные данные 400
NOT_FOUND Ресурс не существует 404
ALREADY_EXISTS Дублирование при создании 409
PERMISSION_DENIED Недостаточные разрешения 403
UNAUTHENTICATED Отсутствует или невалидная аутентификация 401
RESOURCE_EXHAUSTED Ограничение частоты или квоты 429
INTERNAL Ошибка сервера 500
UNAVAILABLE Сервис недоступен 503
DEADLINE_EXCEEDED Запрос превысил таймаут 504
UNIMPLEMENTED Метод не реализован 501

Стриминг

gRPC поддерживает четыре паттерна коммуникации:

Паттерн Описание Случай использования
Унарный Клиент отправляет один запрос, сервер отправляет один ответ Стандартный CRUD
Серверный стриминг Клиент отправляет один запрос, сервер отправляет поток ответов Живая лента, чтение логов
Клиентский стриминг Клиент отправляет поток запросов, сервер отправляет один ответ Загрузка файлов, пакетная обработка
Двунаправленный Обе стороны отправляют потоки одновременно Чат, совместная работа в реальном времени

Тестирование серверного стриминга

def test_server_streaming(user_service):
    """Server streams all users matching a query."""
    request = user_pb2.ListUsersRequest(page=1, per_page=100)
    users = []
    for response in user_service.StreamUsers(request):
        users.append(response)
    assert len(users) > 0
    assert all(hasattr(u, "name") for u in users)

Тестирование дедлайнов/таймаутов

gRPC имеет встроенное распространение дедлайнов — клиент может установить дедлайн, и если сервер не ответит вовремя, вызов завершится ошибкой.

def test_deadline_exceeded(user_service):
    """Request with very short deadline should fail."""
    request = user_pb2.GetUserRequest(id="123")
    with pytest.raises(grpc.RpcError) as exc_info:
        # 1 microsecond deadline — guaranteed to fail
        user_service.GetUser(request, timeout=0.000001)
    assert exc_info.value.code() == grpc.StatusCode.DEADLINE_EXCEEDED

Практическое упражнение

  1. Установите grpcurl и исследуйте gRPC-сервис (используйте публичный демо или настройте локальный)
  2. Перечислите доступные сервисы и методы
  3. Сделайте унарный вызов и проинспектируйте ответ
  4. Напишите Python-тесты для gRPC-сервиса: успешный случай, not found, invalid argument
  5. Протестируйте обработку дедлайнов с очень коротким таймаутом

Ключевые выводы

  • gRPC использует Protocol Buffers (бинарные, типизированные) вместо JSON (текстовый, нетипизированный)
  • grpcurl — необходимый инструмент для ручного исследования gRPC
  • gRPC имеет собственную систему кодов состояния — изучите соответствия HTTP-кодам
  • Тестируйте стриминг (серверный, клиентский, двунаправленный), когда сервис его поддерживает
  • Распространение дедлайнов встроено — тестируйте поведение при таймаутах
  • Файл .proto — источник истины для контракта API