Usando Guzzle e PHPUnit para teste de API REST

Guzzle é um cliente HTTP escrito em PHP que facilita o envio de requisições para integrações de serviços web.

PHP Moderno: Criando uma aplicação com área administrativa

Concordamos que o PHPUnit é um framework para testes unitários e não de api/integração, porém, testes nunca são demais em uma aplicação. Veremos nas próximas linhas como instalar e fazer requisições HTTP através da biblioteca Guzzle.

Guzzle é uma biblioteca escrita em PHP que fornece interfaces para comunicações com serviços web, facilitando no envio de requisições em diferentes formatos e verbos HTTP. Existem outras bibliotecas, como o cURL, nativo do próprio PHP.

Para esse projeto vamos fazer uma consulta na URL do Github, obter o status code e verificar se um item da lista existe, tudo utilizando o Guzzle. Vamos usar o seguinte endereço: https://api.github.com/users/satellasoft.

Instalando o PHPUnit e Guzzle

Vamos criar um exemplo bem simples a partir do zero, assim fica fácil assimilar o conhecimento. Vamos utilizar o Composer para gerenciar nossas dependências e scripts.

Primeiramente precisamos instalar o PHPUnit através do comando do Composer abaixo.

composer require --dev phpunit/phpunit

Uma vez o PHPUnit instalado, precisamos instalar o Guzzle, para isso, usamos o comando abaixo.

composer require --dev guzzlehttp/guzzle

Até aqui temos as duas principais bibliotecas para esse nosso projeto instalada. Note que usamos a flag --dev, isso torna essas bibliotecas dependências de desenvolvimento, ou seja, em produção elas não serão instaladas.

Configurando script no Composer

Para facilitar a nossa vida, vamos criar uma nova entrada no arquivo composer.json, para isso, abra ele no editor de código e insira o novo índice, conforme mostra a linha a seguir.

"scripts": {
     "test": "vendor\\bin\\phpunit"
}

Agora a gente tem um novo comando do Composer disponível, que é o composer test, ao executar, ele vai inicializar o arquivo PHPUnit, dispensando a necessidade de incluí-lo via linha de comando.

composer test

Até o momento nosso arquivo está como mostra o código a seguir.

{
    "name": "satellasoft/phpunit-guzzle",
    "autoload": {
        "psr-4": {
            "Satellasoft\\PhpunitGuzzle\\": "src/"
        }
    },
    "require-dev": {
        "guzzlehttp/guzzle": "^7.4",
        "phpunit/phpunit": "^9.5"
    },
    "scripts": {
        "test": "vendor\\bin\\phpunit"
    }
}

Arquivo de configuração do PHPUnit

Vamos criar um último arquivo com as suas configurações, que é o phpunit.xml, arquivo esse que deve estar na root do nosso projeto. Ele armazena diversas informações e configurações a respeito de como nossos testes unitários devem ser executados.

Basicamente vamos informar onde está nosso arquivo de autoload, especificar para exibir relatórios coloridos e por fim, definir no node <testsuite> qual o diretório que contém nossos testes.

Abra o arquivo e insira as linhas abaixo.

<?xml version="1.0" encoding="UTF-8"?>
<phpunit 
    bootstrap="vendor/autoload.php" colors="true">
        <testsuites>
            <testsuite name="default">
                <directory>tests/</directory>
            </testsuite>
        </testsuites>
</phpunit>

Criando teste com PHPUnit

Okay, até aqui apresentei como podemos configurar minimamente um ambiente de testes e suas dependências, mas agora chegou o momento de escrever nossos testes. Para isso, na root do projeto crie uma pasta chamada tests.

Dentro da pasta tests/, crie um arquivo chamado GithubTest.php. Nele vamos criar uma classe e estender da classe TestCase, conforme mostra o código a seguir.

<?php

//Definimos que vamos usar a classe TestCase
use PHPUnit\Framework\TestCase;

//Criamos uma classe e estendemos a TestCase para acessar seus métodos
class GithubTest extends TestCase
{
}

 Vamos inicializar a classe do Guzzle no método setUp e destruí-lo no método tearDown, conforme mostra o código abaixo.

    private $http;

    public function setUp(): void
    {
        $this->http = new GuzzleHttp\Client(['http_errors' => false]);
    }

    public function tearDown(): void
    {
        $this->http = null;
    }

Por fim, vamos escrever nosso método de teste com duas asserções, uma delas vai verificar o código de resposta enquanto a outra verifica se o ID do usuário é um inteiro. Nosso método fica conforme mostra o código abaixo.

/**
     * Testa se o código de resposta é 200 e te o id do usuário é um inteiro
     *
     * @return void
     */
    public function testGetStatusCode()
    {
        //Realizamos uma requisição do tipo GET na URL informada
        $response = $this->http->request('GET', 'https://api.github.com/users/satellasoft');

        //Através do método getStatusCode(), conseguimos saber qual o status de resposta. 
        //Verificamos se o status de resposta é 200, caso informamos um usuário inválido, o status seria 400.
        $this->assertEquals(200, $response->getStatusCode());

        //Obtemos o JSON da resposta e decodificamos para objeto.
        $body = json_decode($response->getBody()->getContents());

        //Verificamos se contém o indice id ao mesmo tempo que validamos se é um inteiro válido
        $this->assertIsInt($body->id);
    }

Com os testes escritos, basta rodar o comando abaixo para que os testes sejam executados.

composer test

Nossa classe completa fica como mostra o código abaixo.

<?php

//Definimos que vamos usar a classe TestCase
use PHPUnit\Framework\TestCase;

//Criamos uma classe e estendemos a TestCase para acessar seus métodos
class GithubTest extends TestCase
{
    private $http;

    public function setUp(): void
    {
        $this->http = new GuzzleHttp\Client(['http_errors' => false]);
    }

    public function tearDown(): void
    {
        $this->http = null;
    }
    
    /**
     * Testa se o código de resposta é 200 e te o id do usuário é um inteiro
     *
     * @return void
     */
    public function testGetStatusCode()
    {
        //Realizamos uma requisição do tipo GET na URL informada
        $response = $this->http->request('GET', 'https://api.github.com/users/satellasoft');

        //Através do método getStatusCode(), conseguimos saber qual o status de resposta. 
        //Verificamos se o status de resposta é 200, caso informamos um usuário inválido, o status seria 400.
        $this->assertEquals(200, $response->getStatusCode());

        //Obtemos o JSON da resposta e decodificamos para objeto.
        $body = json_decode($response->getBody()->getContents());

        //Verificamos se contém o indice id ao mesmo tempo que validamos se é um inteiro válido
        $this->assertIsInt($body->id);
    }
}

 Você pode assistir nossa videoaula abaixo, nela recriamos o conteúdo deste artigo.

Continue aprendendo mais sobre PHPUnit

Agora que você aprendeu como fazer uma requisição HTTP com PHPUnit e Guzzle, te convidamos a conferir nosso curso Escrevendo testes automatizados com PHPUnit. Durante as aulas você aprenderá a escrever testes, configurar o Composer, PHPUnit, além de ter vários outros aprendizados.
 
✔ Aulas em vídeo;
✔ Apostila complementar;
✔ Códigos disponível para download;
✔ Acesso vitalício;
✔ Grupo de estudos;
✔ Aprenderá sobre Composer e PHP;
✔ Aprenderá sobre testes unitários.
 
Matricule-se: https://s.satellasoft.com/HeN6x-as