启用由消费者驱动的合同测试,遵循PACT基金会原则。

10.0.0 2024-09-04 11:12 UTC

README

logo

Pact PHP

Code Analysis & Test Coverage Status Compatibility Suite Packagist

Downloads Downloads This Month

为您的API和微服务提供快速、简单且可靠的测试。


Pact PHP Demo


----------

文档

本README提供了对库的基本介绍。Pact PHP和整个框架的完整文档可在https://docs.pact.io/找到。

需要帮助

安装

composer require pact-foundation/pact-php --dev

# 🚀 now write some tests!

寻找之前的稳定9.x.x版本

要求

PHP 8.1+ 自pact-php v10起

不跟踪

为了获得关于谁在使用Pact的更好统计数据,我们在Pact首次安装时触发一个匿名跟踪事件。我们所跟踪的只有您的操作系统类型和正在安装的软件包的版本信息。此请求不发送任何PII数据。您可以通过设置环境变量PACT_DO_NOT_TRACK=1来禁用跟踪。

----------

使用方法

编写消费者测试

namespace App\Tests;

use App\Service\HttpClientService;
use PhpPact\Consumer\InteractionBuilder;
use PhpPact\Consumer\Matcher\Matcher;
use PhpPact\Consumer\Model\ConsumerRequest;
use PhpPact\Consumer\Model\ProviderResponse;
use PhpPact\Standalone\MockService\MockServerConfig;
use PHPUnit\Framework\TestCase;

class ConsumerServiceHelloTest extends TestCase
{
    public function testGetHelloString(): void
    {
        $matcher = new Matcher();

        // Create your expected request from the consumer.
        $request = new ConsumerRequest();
        $request
            ->setMethod('GET')
            ->setPath('/hello/Bob')
            ->addHeader('Content-Type', 'application/json');

        // Create your expected response from the provider.
        $response = new ProviderResponse();
        $response
            ->setStatus(200)
            ->addHeader('Content-Type', 'application/json')
            ->setBody([
                'message' => $matcher->term('Hello, Bob', '(Hello, )[A-Za-z]+')
            ]);

        // Create a configuration that reflects the server that was started. You can create a custom MockServerConfigInterface if needed.
        $config = new MockServerConfig();
        $config
            ->setConsumer('jsonConsumer')
            ->setProvider('jsonProvider')
            ->setPactDir(__DIR__.'/../../../pacts');
        if ($logLevel = \getenv('PACT_LOGLEVEL')) {
            $config->setLogLevel($logLevel);
        }
        $builder = new InteractionBuilder($config);
        $builder
            ->uponReceiving('A get request to /hello/{name}')
            ->with($request)
            ->willRespondWith($response); // This has to be last. This is what makes FFI calls to register the interaction and start the mock server.

        $service = new HttpClientService($config->getBaseUri()); // Pass in the URL to the Mock Server.
        $helloResult = $service->getHelloString('Bob'); // Make the real API request against the Mock Server.
        $verifyResult = $builder->verify(); // This will verify that the interactions took place.

        $this->assertTrue($verifyResult); // Make your assertions.
        $this->assertEquals('Hello, Bob', $helloResult);
    }
}

您可以在./examples/json中看到(并运行)此版本的完整内容,以及父文件夹中的其他示例。

运行示例

  1. 克隆存储库 git@github.com:pact-foundation/pact-php.git
  2. 进入存储库 cd pact-php
  3. 安装所有依赖项 composer install

运行单个示例

  1. 进入所需的示例文件夹 cd examples/json
  2. 运行示例 - phpunit

运行所有示例

  1. 进入示例文件夹 cd examples
  2. 安装所有示例 phpunit

----------

验证提供者

提供者测试接受一个或多个pact文件(合同)作为输入,Pact验证您的提供者是否遵守合同。在 simplest case中,您可以使用本地pact文件验证提供者,尽管在实际情况中,您通常会使用Pact Broker来管理您的合同和CI/CD工作流程。

namespace App\Tests;

use GuzzleHttp\Psr7\Uri;
use PhpPact\Standalone\ProviderVerifier\Model\VerifierConfig;
use PhpPact\Standalone\ProviderVerifier\Verifier;
use PhpPactTest\Helper\PhpProcess;
use PHPUnit\Framework\TestCase;

class PactVerifyTest extends TestCase
{
    private PhpProcess $process;

    protected function setUp(): void
    {
        $this->process = new PhpProcess(__DIR__ . '/path/to/public/');
        $this->process->start();
    }

    protected function tearDown(): void
    {
        $this->process->stop();
    }

    /**
     * This test will run after the web server is started.
     */
    public function testPactVerifyConsumer()
    {
        $config = new VerifierConfig();
        $config->getProviderInfo()
            ->setName('jsonProvider') // Providers name to fetch.
            ->setHost('localhost')
            ->setPort($this->process->getPort());
        $config->getProviderState()
            ->setStateChangeUrl(new Uri(sprintf('http://localhost:%d/pact-change-state', $this->process->getPort())))
        ;
        if ($level = \getenv('PACT_LOGLEVEL')) {
            $config->setLogLevel($level);
        }

        $verifier = new Verifier($config);
        $verifier->addFile(__DIR__ . '/path/to/pacts/jsonConsumer-jsonProvider.json');

        $verifyResult = $verifier->verify();

        $this->assertTrue($verifyResult);
    }
}

最好将Pact验证测试作为您单元测试套件的一部分运行,这样您就可以方便地访问存根、IaC和其他有用的工具。

----------

兼容性

版本

* v3支持仅限于启用语言互操作性消息支持所需的功能子集。

支持的平台

* 对于9.x及以下版本,通过一个解决方案支持Ruby Standalone与Alpine

路线图

Pact 和 Pact PHP 的路线图概述在我们的主网站上。

贡献

请参阅 贡献指南