genesis/behat-api-spec

使用快照测试轻松维护您的API。


README

拥有API但没有时间编写自动化测试?已经有自动化测试但难以维护?这里有一个有效的自动化解决方案,可以防止回归并在需要时自我维护。

发行说明

主要

  • 快照测试。

次要

  • 使用 'snapshot pattern' 步骤定义产生正则表达式快照。
  • 使用一个步骤定义检查响应中的多个json键。

修复

  • 运行单个场景不会影响其他场景的快照。

安装

composer require genesis/behat-api-spec

behat.yml 文件

default:
  suites:
    default:
      contexts:
        - Genesis\BehatApiSpec\Context\ApiSpecContext
  extensions:
    Genesis\BehatApiSpec\Extension:
      baseUrl: <Your API Url>
      specMappings:
        endpoint: <Namespace to folder to autoload - leading backslash>

基本概述

您可以使用 --endpoint-generate 选项生成端点文件。只需运行以下命令即可获得交互式shell:

./vendor/bin/behat --endpoint-generate

手动创建端点文件

<?php

namespace ...;

use Genesis\BehatApiSpec\Contracts\Endpoint;

class User implements Endpoint
{
    public static function getEndpoint(): string
    {
        return '/users';
    }

    public static function getRequestHeaders(): array
    {
        return [
            'accept-language' => 'en',
            'accept' => 'text/html',
        ];
    }
}

将步骤定义添加到功能文件

Scenario: 200 user response
    When I make a POST request to the "User" endpoint
    Then I expect a 500 "User" response
    And the response should match the snapshot
    And I expect the following content in the JSON response:
       | key1.subkey1 | value1 |
       | key1.subkey2 | value2 |

“当我向 "用户" 端点发送POST请求”将最初自动使用响应生成模式并插入到您声明的端点文件中。在后续调用中,该模式将用于验证响应,提供防止回归的保护。一个示例模式可以是以下GET请求200响应的响应 {"success": false, "error": "Something went wrong."}

<?php

namespace ...;

use Genesis\BehatApiSpec\Contracts\Endpoint;

class User implements Endpoint
{
    ...

    public function getResponseSchema(): array
    {
        'GET' => [
            500 => [
                'headers' => [
                    'Host' => [
                        'value' => 'localhost:8090',
                        'type' => self::TYPE_STRING,
                    ],
                    'Connection' => [
                        'value' => 'close',
                        'type' => self::TYPE_STRING,
                    ],
                    'X-Powered-By' => [
                        'value' => 'PHP/7.2.26-1+ubuntu18.04.1+deb.sury.org+1',
                        'type' => self::TYPE_STRING,
                    ],
                    'content-type' => [
                        'value' => 'application/json',
                        'type' => self::TYPE_STRING,
                    ],
                ],
                'body' => [
                    'success' => [
                        'type' => self::TYPE_BOOLEAN,
                        'optional' => false,
                    ],
                    'error' => [
                        'type' => self::TYPE_STRING,
                        'optional' => false,
                        'pattern' => null,
                    ],
                ],
            ]
        ]
    }
}

相应地进行调整。

快照

在此基础上,"并且响应应与快照匹配"将自动生成快照,将响应存储在场景标题中。这将存储在测试相同的目录中。该文件应与代码一起提交,以便进行同行评审。在后续请求中,响应将与该快照进行匹配,任何差异都将生成失败。您可以选择使用 --update-snapshots 或 -u 标志自动更新快照,或者修复API中的问题。任何过时的快照都将被识别并相应地更新。示例快照

<?php return [

    '500 user response' =>
        '{"success":false,"error":"Something went wrong."}',

];

占位符

所有请求都调用 PlaceHolderService::resolveInString 方法,使用正文和URL替换您可能使用默认 preRequestCallable 钩子设置的任何占位符(格式 - {{placeholder_name}}),该钩子是可以覆盖的(见钩子部分)。要添加占位符,您可以像这样使用 PlaceholderService

    public function ...
    {
        $value = ...;
        PlaceholderService::add($name, $value);

        PlaceHolderService::getValue($name); // returns $value;
    }

占位符在每个场景结束后重置,以防止测试会话泄露。功能文件中的示例用法

    Scenario: 200 user response
        When I make a POST request to the "User" endpoint with body:
            """
                {"status": "{{status_failed}}"}
            """

在上面的示例中,如果您已设置 PlaceHolderService::add('status_failure', -1),则期望发送的正文是 {"status": "-1"}。注意值必须是标量才能成为正文的一部分。

多个版本

您可以从功能文件或通过创建新的端点文件设置要使用的API版本。要从功能文件设置

    ...
    Given I use version "1" of the API
    ...

这将允许您通过 ApiSpecContext::getVersion() 方法在任何文件中检索设置的版本。例如,在 Endpoint getRequestHeaders 方法中设置它。该方法还接受默认API版本,如果未设置。版本也可作为占位符 {{API_VERSION}}

钩子

可以在 behat.yml 文件中为每个上下文配置配置请求前和请求后钩子,如下所示

#behat.yml file

default:
  suites:
    default:
      contexts:
        - Genesis\BehatApiSpec\Context\ApiSpecContext:
            preRequestCallable: 'MyClass::preRequestStaticCallable'
            postRequestCallable: 'MyClass::postRequestStaticCallable'

生成示例请求

如果您使用步骤定义 When I make a POST request to "User" endpoint 来向API发送请求,您可以使用 --sample-request=<format> 标志通过命令行快速生成示例请求。一个例子是

vendor/bin/behat --sample-request=curl

    Scenario: 200 user response
        Given I set the following headers:
          | content-type | application/json |
          | accept       | en               |
        When I make a GET request to "User" endpoint
          │ curl -X GET --header 'content-type: application/json' --header 'accept: text/html' --header 'accept-language: en' 'http://localhost:8090/index.php/users'

注意步骤定义下生成的curl命令。

步骤定义

更多步骤定义作为上下文文件的一部分提供,用于验证API响应。使用 vendor/bin/behat -dl 查找。