Laravel Capítulo 10 Teste e documentação de API

1. Introdução aos testes automatizados de API

Teste automatizado de API

Concluímos todo o desenvolvimento da interface do Larabbs e, em seguida, precisamos entregá-la a outros engenheiros para acoplamento. Ao implantar a interface no ambiente de produção, como garantir que a interface entregue esteja correta e estável? No futuro, adicionaremos novas funções ao projeto. Nesse momento, como podemos garantir que a interface ainda esteja normal após a atualização do código?

Durante o processo de desenvolvimento, usamos PostMan para testar manualmente as interfaces uma por uma, mas quando temos dezenas ou mesmo centenas de interfaces, o teste manual não será aplicável se quisermos testar essas interfaces ao mesmo tempo. A solução são os testes automatizados. Os testes automatizados são uma parte importante para garantir a qualidade do projeto. Nesta seção, vamos entender os conceitos relacionados aos testes.

teste de unidade

Teste de unidade refere-se à inspeção e verificação da menor unidade testável do software. Para PHP, geralmente  testa um determinado método em uma determinada classe ou um único método. O objetivo do teste unitário é primeiro garantir que os  componentes básicos de um sistema  possam funcionar normalmente e que todas as partes básicas funcionem normalmente, para que o software montado não tenha problemas.

O teste de unidade é  um teste em nível de código  e os custos de desenvolvimento e manutenção são altos, por isso não é recomendado para equipes pequenas. Se for uma colaboração entre várias pessoas, minha tarefa é encapsular separadamente algumas funções comuns, como escrever um serviço; ou escrever um pacote de extensão para fornecer algumas interfaces de código subjacentes, como empacotar um SDK para um aplicativo de terceiros e, em seguida, unir testar é muito útil, necessário.

Existem muitos pontos de conhecimento envolvidos em testes unitários. Neste tutorial, não explicaremos os testes unitários separadamente.

Teste de integração de API

No teste de API integrado que vem com o framework Laravel, inicializamos o contexto completo da aplicação e, após preparar os dados de teste no banco de dados, podemos simular facilmente vários métodos de solicitação, chamar a interface para obter o resultado da resposta e, finalmente, afirmar se o o resultado retornado é igual ao   resultado esperado .

Os testes de integração de API   precisam preparar dados de teste, definir usuários, atribuir permissões de usuário e preparar dados associados para a interface de teste. Embora haja um certo custo de manutenção, em comparação com os testes unitários, o custo de manutenção é muito menor e, até certo ponto, pode garantir melhor a robustez do projeto.

Teste PostMan

Use PostMan e outras ferramentas para testes manuais. Esta é a solução de teste mais recomendada. É muito adequada para equipes pequenas, porque pode simular solicitações de usuários de forma mais realista e, na colaboração em equipe, os engenheiros de back-end podem compartilhar a interface de depuração do PostMan com os clientes Engenheiro, se houver algum problema com a interface, o engenheiro do cliente poderá testá-la sozinho.

2. Teste de integração da API Laravel

Crie uma nova pasta Vá para o diretório pai da nova pasta, $mkdir nome da pasta

Nesta seção aprendemos sobre testes de integração de API por meio de vários exemplos.

Se você estiver usando ou atualizando para o Laravel 5.7, a versão do phpunit deve ser 7.*

Unidade PHP

PHPUnit é uma estrutura leve de testes de PHP. O Laravel suporta PHPUnit para testes por padrão e configura o arquivo phpunit.xml para sua aplicação. Você só precisa executá-lo na linha de comando para testar  phpunit .

Há um pequeno erro no projeto Larabbs atual, que causará um erro ao executar o phpunit  PHP Fatal error: Cannot redeclare route_class(). Só porque há alguns problemas com a introdução do nosso método personalizado, modifique-o um pouco:

bootstrap/app.php

.
.
.
require_once __DIR__ . '/helpers.php';
.
.
.

O código anterior costumava  require introduzir um método personalizado, que pode ser introduzido repetidamente, por isso é alterado aqui  require_once.

Tente executar no diretório raiz do larabbs phpunit

$ phpunit


Criar arquivo de teste

Primeiro você precisa criar um arquivo de teste:

$ php artisan make:test TopicApiTest

Este comando criará  tests/Feature arquivos  TopicApiTest.php no diretório. Descobriremos que existem dois diretórios no diretório de testes  Feature .  Unit Como distinguir esses dois diretórios?

  • Unidade - Os testes unitários são escritos do ponto de vista do programador. Eles são usados ​​para garantir que um método específico de uma classe execute um conjunto específico de tarefas.
  • Recurso - Os testes funcionais são escritos do ponto de vista do usuário. Eles garantem que o sistema se comporte conforme o usuário espera, incluindo a interação de diversos objetos, ou até mesmo uma solicitação HTTP completa.

Nossa API de teste é um teste funcional e deve ser criada no  Feature diretório.


tópico de lançamento de teste

testes/Recurso/TopicApiTest.php

<?php

namespace Tests\Feature;

use App\Models\User;
use App\Models\Topic;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class TopicApiTest extends TestCase
{
    protected $user;

    public function setUp()
    {
        parent::setUp();

        $this->user = factory(User::class)->create();
    }

    public function testStoreTopic()
    {
        $data = ['category_id' => 1, 'body' => 'test body', 'title' => 'test title'];

        $token = \Auth::guard('api')->fromUser($this->user);
        $response = $this->withHeaders(['Authorization' => 'Bearer '.$token])
            ->json('POST', '/api/topics', $data);

        $assertData = [
            'category_id' => 1,
            'user_id' => $this->user->id,
            'title' => 'test title',
            'body' => clean('test body', 'user_topic_body'),
        ];

        $response->assertStatus(201)
            ->assertJsonFragment($assertData);
    }
}

setUp será executado antes do início do teste, primeiro criamos um usuário e o teste testará como esse usuário.

testStoreTopic É um usuário de teste, testando e postando tópicos. Usar $this->json pode simular convenientemente várias solicitações HTTP:

  • O primeiro parâmetro é o método de solicitação, o método POST é usado para publicar o tópico;
  • O segundo parâmetro - endereço de solicitação, solicitação  /api/topics;
  • O terceiro parâmetro - parâmetros de solicitação, entrada  ,,,, category_idesses três parâmetros necessários;bodytitle
  • O quarto parâmetro - Request Header, pode ser definido diretamente  headerou usar  withHeaders métodos para atingir o mesmo propósito;

Descobrimos que   o código  gerado Token e configurado  para o usuário não será utilizado apenas  , mas também serão utilizados os casos de teste de outras funções escritas no futuro, então vamos encapsulá-lo.Authorization修改话题删除话题

Adicione uma característica:

$ touch tests/Traits/ActingJWTUser.php 

testes/Traits/ActingJWTUser.php

<?php

namespace Tests\Traits;

use App\Models\User;

trait ActingJWTUser
{
    public function JWTActingAs(User $user)
    {
        $token = \Auth::guard('api')->fromUser($user);
        $this->withHeaders(['Authorization' => 'Bearer '.$token]);

        return $this;
    }
}

Modifique o caso de teste para usar esta característica.

testes/Recurso/TopicApiTest.php

<?php

namespace Tests\Feature;
.
.
.
use Tests\Traits\ActingJWTUser;
.
.
.
class TopicApiTest extends TestCase
{
    use ActingJWTUser;
.
.
.
    public function testStoreTopic()
    {
        $data = ['category_id' => 1, 'body' => 'test body', 'title' => 'test title'];

        $response = $this->JWTActingAs($this->user)
            ->json('POST', '/api/topics', $data);

        $assertData = [
            'category_id' => 1,
            'user_id' => $this->user->id,
            'title' => 'test title',
            'body' => clean('test body', 'user_topic_body'),
        ];

        $response->assertStatus(201)
            ->assertJsonFragment($assertData);
    }
}

Desta forma, podemos facilmente usar  JWTActingAs o método para fazer login de um usuário. A resposta resultante  $response, ao  assertStatus afirmar que o resultado da resposta é  201assertJsonFragment contém  assertData dados ao afirmar que o resultado da resposta é.

Execute o teste:

$ phpunit

O cartão continua reportando um erro aqui: Erro: Chamada para método indefinido Illuminate\Auth\TokenGuard::fromUser()

esperando para ser resolvido


Tópico de modificação de teste

testes/Recurso/TopicApiTest.php

.
.
.
public function testUpdateTopic()
{
    $topic = $this->makeTopic();

    $editData = ['category_id' => 2, 'body' => 'edit body', 'title' => 'edit title'];

    $response = $this->JWTActingAs($this->user)
        ->json('PATCH', '/api/topics/'.$topic->id, $editData);

    $assertData= [
        'category_id' => 2,
        'user_id' => $this->user->id,
        'title' => 'edit title',
        'body' => clean('edit body', 'user_topic_body'),
    ];

    $response->assertStatus(200)
        ->assertJsonFragment($assertData);
}

protected function makeTopic()
{
    return factory(Topic::class)->create([
        'user_id' => $this->user->id,
        'category_id' => 1,
    ]);
}
.
.
.

Adicionamos  testUpdateTopic um caso de teste. Para modificar o tópico, primeiro precisamos criar um tópico para o usuário, então adicionamos  makeTopicum tópico para gerar um tópico para o usuário atualmente testado. O código é semelhante a publicar um tópico, preparar os dados do tópico a serem modificados  $editData, chamar  修改话题 a interface, modificar o tópico recém-criado e, finalmente, afirmar que o código de status da resposta é  200 e o resultado o contém  $assertData.

Execute o teste:

$ phpunit


tópico de visualização de teste

testes/Recurso/TopicApiTest.php

.
.
.
public function testShowTopic()
{
    $topic = $this->makeTopic();
    $response = $this->json('GET', '/api/topics/'.$topic->id);

    $assertData= [
        'category_id' => $topic->category_id,
        'user_id' => $topic->user_id,
        'title' => $topic->title,
        'body' => $topic->body,
    ];

    $response->assertStatus(200)
        ->assertJsonFragment($assertData);
}

public function testIndexTopic()
{
    $response = $this->json('GET', '/api/topics');

    $response->assertStatus(200)
        ->assertJsonStructure(['data', 'meta']);
}
.
.
.

Adicionados dois usuários de teste  testShowTopic e  , test  e  testIndexTopicrespectivamente  . Essas duas interfaces podem ser acessadas sem login do usuário, portanto não há necessidade de passar Token.话题详情话题列表

testShowTopic Primeiro crie um tópico, depois acesse  话题详情 a interface, afirme que o código de status da resposta é  200 e os dados da resposta são consistentes com os dados do tópico recém-criados.

testIndexTopic Acesse diretamente  话题列表 a interface, o código de status da resposta de asserção é  , e há  e  200na estrutura de dados de resposta de asserção  .datameta

Execute o teste:

$ phpunit

Testar exclusão de tópico

testes/Recurso/TopicApiTest.php

.
.
.
public function testDeleteTopic()
{
    $topic = $this->makeTopic();
    $response = $this->JWTActingAs($this->user)
        ->json('DELETE', '/api/topics/'.$topic->id);
    $response->assertStatus(204);

    $response = $this->json('GET', '/api/topics/'.$topic->id);
    $response->assertStatus(404);
}
.
.
.

Primeiro  makeTopic crie um tópico, depois  DELETE chame  删除话题 a interface por meio do método para excluir o tópico e afirme que o código de status da resposta é  204.

Em seguida, solicite a interface de detalhes do tópico e afirme que o código de status da resposta é  404, porque o tópico foi excluído, então ele será obtido  404.

Execute o teste:

$ phpunit

No final, executamos 7 usuários de teste, fizemos 22 afirmações e o teste estava correto.

controle de versão de código

$ git add -A
$ git commit -m 'topic test'

3. Testes de caixa preta de terceiros

Além de testes de unidade e testes de integração, também podem ser usadas ferramentas de terceiros. Nesta seção, aprenderemos como usar o PostMan para testes de caixa preta de terceiros, que é nossa solução de teste mais recomendada.

A vantagem do teste de caixa preta de terceiros é que ele pode testar todo o sistema ao máximo.Para  nossa interface API, a partir da análise do código PHP, os seguintes fatores afetarão a usabilidade da interface:

  1. Erros no nível do código do software;
  2. Erros ocorrem em softwares de terceiros utilizados pelo programa, como: cache Redis e sistema de filas, banco de dados MySQL, etc.;
  3. Software de sistema no servidor API, como Nginx, Cron, etc.;
  4. Problemas físicos no servidor API, como falha no disco rígido;
  5. Problemas de resolução de nomes de domínio, como erros de resolução de DNS;

O teste automatizado no nível do código tem um escopo limitado de teste. O teste de caixa preta de terceiros simula as solicitações de usuários reais e considera o servidor API como um  sistema completo . Qualquer parte quebrada no sistema pode ser detectada. Além disso, este método de teste é completamente dissociado do ambiente do servidor e o custo de manutenção posterior é baixo.

Compartilhe dados da interface

PostMan nos ajuda a exportar a interface salva. Na colaboração em equipe, o engenheiro de back-end pode facilmente compartilhar os dados da interface do PostMan com o engenheiro do cliente, e o engenheiro do cliente pode testar a interface sozinho e simular a solicitação real.

Exportar coleção

Existem muitos formatos de exportação para escolher, escolhemos o recomendado pelo PostMan  Collection v2.1.

Após escolher exportar, você obterá  Larabbs o arquivo de interface com um nome de arquivo semelhante  Larabbs.postman_collection.json.

exportar variáveis ​​de ambiente

Além dos dados da interface, também definimos algumas variáveis ​​de ambiente, como  { {host}}, { {jwt_user1}} etc., também precisamos exportá-las e compartilhá-las com outras pessoas, para que seja um ambiente completo.

Clique em Configurações no canto superior direito e selecione  Manage Environments.

Clique no download atrás do ambiente correspondente.

Os nomes dos arquivos baixados são semelhantes  larabbs-local.postman_environment.json.

Deve-se notar aqui que nosso ambiente atual  larabbs-local é nosso ambiente local. Para facilitar o uso dos engenheiros do cliente, podemos construir um ambiente Larabbs completo em um servidor de teste acessível on-line, aumentar o ambiente do servidor de teste e definir o  larabbs-testambiente variáveis ​​​​do ambiente de teste  { {host}}. { {jwt_user1}} Espere, o ambiente compartilhado desta forma pode ser usado diretamente por outras pessoas.

Coleção de importação e meio ambiente

Compartilharemos os arquivos exportados  Larabbs.postman_collection.json e  larabbs-local.postman_environment.json dois arquivos com os engenheiros do cliente.

Clique no canto superior esquerdo  Import para importar arquivos da coleção.

Manage Environments Clique em  para  Import importar variáveis ​​de ambiente.

Após a importação ser bem-sucedida, podemos depurar diretamente a interface.

Teste automatizado PostMan

PostMan nos fornece a função de teste automatizado, semelhante ao teste de interface do Laravel, PostMan pode solicitar a interface e afirmar o resultado da resposta e os dados de resposta, e então tomaremos as duas interfaces como exemplo para realizar testes  发布话题 automatizados  话题列表 .

tópico de lançamento de teste

Abra  发布话题 a interface, você verá uma  Tests aba, clique nesta aba, aparecerá uma área em branco, aqui podemos adicionar algumas afirmações para julgar o resultado da solicitação.

Preencha o seguinte conteúdo:

pm.test("响应状态码正确", function () { 
    pm.response.to.have.status(201);
});

pm.test("接口响应数据正确", function () { 
    pm.expect(pm.response.text()).to.include("id");
    pm.expect(pm.response.text()).to.include("title");
    pm.expect(pm.response.text()).to.include("body");
    pm.expect(pm.response.text()).to.include("user_id");
    pm.expect(pm.response.text()).to.include("category_id");
});

PostMan nos fornece  pm.test um método que equivale a um caso de teste. O primeiro parâmetro é o texto do prompt após a execução estar correta e o segundo parâmetro é um fechamento para executar nossa asserção.

Para o primeiro usuário de teste, avaliamos o código de status da resposta e pm.response.to.have.status(201); afirmamos que o código de status do resultado da resposta é  201.

Para o segundo usuário de teste, julgamos os dados de resposta afirmando  pm.expect(pm.response.text()).to.include(""); que os dados de resposta devem conter um determinado campo.

Clique  Send para depurar.

Mude para  Test Resultse você verá que ambos os casos de teste foram aprovados.

Lista de tópicos de teste

Da mesma forma,  话题列表 adicionamos casos de teste para a interface:

// example using response assertions
pm.test("响应状态码正确", function () { 
    pm.response.to.have.status(200);
});

pm.test("接口响应数据正确", function () { 
    pm.expect(pm.response.text()).to.include("data");
    pm.expect(pm.response.text()).to.include("meta");
});

Dois casos de teste também são adicionados, afirmando que o código de status da resposta é  200e afirmando que os dados de resposta contêm  data e  meta.

Clique  Send para depurar.

O teste passa.

teste em lote

Depois de concluir o teste do usuário para cada interface, podemos realizar testes automatizados por meio da ferramenta de teste PostMan.

Clique no canto superior esquerdo do PostMan  Runner, podemos ver a interface de teste automatizado do PostMan, podemos optar por testar o projeto inteiro ou testar um determinado diretório. Aqui selecionamos  话题 o diretório, selecionamos  larabbs-local o ambiente e executamos o teste.

Podemos ver que PostMan solicita  话题 todas as interfaces no diretório por sua vez, porque adicionamos   casos de teste e asserções para 发布话题 e  , para que possamos ver que os usuários de teste dessas duas interfaces foram aprovados.话题列表

Podemos adicionar casos de teste para todas as interfaces, de modo que, após a atualização da interface, ela possa ser facilmente testada por meio da ferramenta de teste automatizado do PostMan para localizar rapidamente a interface que não atende às expectativas.

4. Documentação da API

Depois de concluir todas as APIs e testes, precisamos ter um documento de interface para comodidade dos demais. Nesta seção apresentaremos o método de geração rápida de documentos API.

Carteiro

A Coleção exportada pelo PostMan já é um documento básico de interface, que pode complementar ainda mais as informações de descrição dos parâmetros da solicitação.

Claro que existem muitas desvantagens:

  • Os documentos precisam ser compartilhados por meio de importação e exportação;
  • É impossível descrever detalhadamente os resultados da resposta;
  • Não há lugar para adicionar mais explicações sobre a interface;

Claro, usuários pagos podem desfrutar de funções mais convenientes, não discutiremos mais aqui.

Introdução

Apizza  ( apizza - uma ferramenta de gerenciamento de API para geeks ) é uma ferramenta online de gerenciamento de colaboração de API. A interface e o uso são basicamente semelhantes ao PostMan, que pode ser entendido como uma versão online do PostMan.

Mas comparado ao PostMan, as funções são mais abundantes, por exemplo, podemos definir parâmetros de solicitação e tipos de parâmetros com mais detalhes.

Os dados de resposta podem ser descritos com mais detalhes.

Ele suporta arquivos de descrição no formato Markdown e podemos adicionar descrições detalhadas de chamadas para um conjunto de interfaces.

Além disso, Apizza também suporta importação direta de arquivos PostMan Collection.

Observe que atualmente apenas os arquivos de coleção do PostMan v1 são suportados. Exporte um arquivo v1 do PostMan e importe-o para o Apizza.

Depois que a exportação for bem-sucedida, você poderá ver que o documento está consistente com o PostMan.

Claro, também existem funções de colaboração em equipe e compartilhamento de documentos.

Resumir

No estágio de desenvolvimento, definitivamente usaremos o PostMan para depuração da interface, importaremos os arquivos da coleção PostMan para o Apizza e, em seguida, melhoraremos ainda mais os documentos com os membros da equipe e, finalmente, os compartilharemos com outras pessoas, o que é uma coisa conveniente e rápida.

Embora  o APIdoc  e  o swagger  sejam excelentes ferramentas de documentação, eles ainda apresentam um certo custo de aprendizado e de manutenção. Portanto, recomendamos que o PostMan seja usado em combinação com ferramentas online como Apizza para completar rapidamente a documentação da API.

Acho que você gosta

Origin blog.csdn.net/jiangyangll/article/details/89702946
Recomendado
Clasificación