Проверка работы API с помощью PHP: от основ до автоматизации

Раздел: Разработка программного обеспечения -> Тестирование

Основные подходы к тестированию API на PHP

Как организовать автоматическое тестирование REST API с помощью PHPUnit и Guzzle?

Основное решение: использование PHPUnit в сочетании с HTTP-клиентом Guzzle. Этот подход позволяет создавать тесты, которые отправляют реальные HTTP-запросы к вашему API и проверяют ответы. Тесты могут быть интегрированы в процесс CI/CD.


composer require --dev phpunit/phpunit guzzlehttp/guzzle

Unit tests php (юнит-тестирование php)

Далее создается тестовый класс, наследующий от PHPUnit\Framework\TestCase. Внутри метода используем Guzzle для выполнения запросов и утверждений PHPUnit для проверки.


use PHPUnit\Framework\TestCase;
use GuzzleHttp\Client;

class ApiTest extends TestCase
{
    private $client;

    protected function setUp(): void
    {
        $this->client = new Client([
            'base_uri' => 'http://localhost:8000/api/',
            'http_errors' => false,
        ]);
    }

    public function testGetUsersReturnsSuccess()
    {
        $response = $this->client->get('users');
        $this->assertEquals(200, $response->getStatusCode());
        $data = json_decode($response->getBody(), true);
        $this->assertIsArray($data);
        $this->assertNotEmpty($data);
    }
}

система тестирования php (система тестирования на php)

Пояснение: setUp создает клиент с базовым URI. В тесте выполняется GET запрос, проверяется статус 200 и формат ответа. Проблемы: если API требует авторизации, необходимо добавить заголовки. Также возможны проблемы с окружением (базовый URI).

Типичные ошибки: - Ошибка соединения, если сервер не запущен. Решение: проверять статус сервера или использовать mock-клиент. - Изменение данных в тестах влияет на другие тесты. Решение: использовать транзакции или фабрики данных в setUp/tearDown.

Как тестировать API без Guzzle, используя встроенную функцию cURL?

Вариант с cURL: можно обойтись без внешних библиотек, используя PHP-расширение cURL. Это полезно в средах, где composer недоступен или нужно минималистичное решение.


public function testCreateUserWithCurl()
{
    $ch = curl_init('http://localhost:8000/api/users');
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['name' => 'John']));
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    $this->assertEquals(201, $httpCode);
    $data = json_decode($response, true);
    $this->assertEquals('John', $data['name']);
}

Http localhost test php (тестирование php на localhost)

Пояснение: настройка cURL опциями, выполнение запроса, получение кода ответа. Проблемы: сложность в обработке ошибок, необходимость вручную обрабатывать исключения.

Проблемы cURL: - Требуется расширение php-curl. - Нет удобного интерфейса для цепочек вызовов. - Возможны утечки ресурсов, если не закрывать дескриптор.

Какие инструменты позволяют проводить тестирование API без написания кода?

Инструмент Postman с Newman для автоматизации. Postman позволяет создавать коллекции запросов, тесты на JavaScript, а Newman запускает их из командной строки. Это подходит для QA-инженеров, не владеющих PHP.

newman run collection.json -e environment.json --reporters cli,junit

Php testing (тестирование php)

Пояснение: запуск коллекции с окружением. Результат в консоли и XML. Проблемы: сложнее интеграция с PHP-кодом, нет возможности проверить внутреннюю логику приложения.

Недостатки Postman/Newman: - Нет глубокой интеграции с PHP-проектом. - Нельзя тестировать вызовы protected/private методов. - Управление тестами отдельно от кода.

Как тестировать API в Laravel с помощью встроенных методов?

В Laravel есть встроенный HTTP-тестинг на основе PHPUnit. Он позволяет делать запросы к приложению без запуска сервера.


public function test_can_create_user()
{
    $response = $this->postJson('/api/users', ['name' => 'Jane']);
    $response->assertStatus(201);
    $response->assertJson(['name' => 'Jane']);
}

Пояснение: postJson отправляет JSON-запрос, assertStatus проверяет код. Проблемы: тесты изолированы, но могут требовать настройки базы данных.

Ошибки в Laravel: - Отсутствие миграций может вызвать ошибку таблицы. - Использование фабрик для генерации данных.

Расширенные практические примеры

Пример теста с аутентификацией:

Пример

public function testAuthenticatedEndpoint()
{
    $client = new Client(['base_uri' => 'http://localhost:8000/api/']);
    $loginResponse = $client->post('auth/login', [
        'json' => ['email' => 'test@test.com', 'password' => 'password']
    ]);
    $token = json_decode($loginResponse->getBody(), true)['access_token'];

    $response = $client->get('protected/resource', [
        'headers' => ['Authorization' => 'Bearer ' . $token]
    ]);
    $this->assertEquals(200, $response->getStatusCode());
}
{
  "access_token": "eyJ...",
  "token_type": "Bearer"
}
// После запроса protected/resource получаем:
HTTP 200

Тестирование пагинации:

Пример

public function testPagination()
{
    $response = $this->client->get('users?page=1&per_page=5');
    $data = json_decode($response->getBody(), true);
    $this->assertArrayHasKey('data', $data);
    $this->assertArrayHasKey('meta', $data);
    $this->assertEquals(5, count($data['data']));
}

Использование Mock-сервера (например, Mockery):

Пример

use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;

public function testExternalApiMock()
{
    $mock = new MockHandler([
        new Response(200, [], json_encode(['status' => 'ok'])),
    ]);
    $handler = HandlerStack::create($mock);
    $client = new Client(['handler' => $handler]);

    $response = $client->get('http://external.api/endpoint');
    $this->assertEquals('ok', json_decode($response->getBody(), true)['status']);
}

Тестирование валидации ошибок:

Пример

public function testValidationFail()
{
    $response = $this->client->post('users', [
        'json' => ['email' => 'invalid']
    ]);
    $this->assertEquals(422, $response->getStatusCode());
    $data = json_decode($response->getBody(), true);
    $this->assertArrayHasKey('errors', $data);
}

Интеграция с CI (GitHub Actions):

Пример

# .github/workflows/test.yml
name: API Tests
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install dependencies
        run: composer install
      - name: Run API tests
        run: vendor/bin/phpunit --testsuite api

Тестирование API на PHP - comments

En
Api tests php (php)