承接 cerbero/octane-testbench 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

cerbero/octane-testbench

Composer 安装命令:

composer require --dev cerbero/octane-testbench

包简介

Set of utilities to test Laravel applications powered by Octane.

README 文档

README

Author PHP Version Laravel Version Octane Compatibility Build Status Coverage Status Quality Score Latest Version Software License PSR-12 Total Downloads

Set of utilities to test Laravel applications powered by Octane.

Install

Via Composer:

composer require --dev cerbero/octane-testbench

In tests/TestCase.php, use the TestsOctaneApplication trait:

use Cerbero\OctaneTestbench\TestsOctaneApplication;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    use TestsOctaneApplication;
}

Now all tests extending this class, even previously created tests, can run on Octane.

Usage

In a nutshell, Octane Testbench

  1. is progressive: existing tests keep working, making Octane adoption easier for existing Laravel apps
  2. stubs out workers and clients: tests don't need a Swoole or RoadRunner server to run
  3. preserves the application state after a request, so assertions can be performed after the response
  4. offers fluent assertions tailored to Octane:
public function test_octane_application()
{
    $this
        ->assertOctaneCacheMissing('foo')
        ->assertOctaneTableMissing('example', 'row')
        ->assertOctaneTableCount('example', 0)
        ->expectsConcurrencyResults([1, 2, 3])
        ->get('octane/route')
        ->assertOk()
        ->assertOctaneCacheHas('foo', 'bar')
        ->assertOctaneTableHas('example', 'row.votes', 123)
        ->assertOctaneTableCount('example', 1);
}

Requests and responses

HTTP requests are performed with the same methods we would normally call to test any Laravel application, except they will work for both standard and Octane routes:

Route::get('web-route', fn () => 123);

Octane::route('POST', '/octane-route', fn () => new Response('foo'));


public function test_web_route()
{
    $this->get('web-route')->assertOk()->assertSee('123');
}

public function test_octane_route()
{
    $this->post('octane-route')->assertOk()->assertSee('foo');
}

Responses are wrapped in a ResponseTestCase instance that lets us call response assertions, any assertion of the Laravel testing suite and the following exception assertions:

$this
    ->get('failing-route')
    ->assertException(Exception::class) // assert exception instance
    ->assertException(new Exception('message')) // assert exception instance and message
    ->assertExceptionMessage('message'); // assert exception message

Furthermore, responses and exceptions can be debugged by calling the dd() and dump() methods:

$this
    ->get('failing-route')
    ->dump() // dump the whole response/exception
    ->dump('original') // dump only a specific property
    ->dd() // dump-and-die the whole response/exception
    ->dd('headers'); // dump-and-die only a specific property

Concurrency

Concurrency works fine during tests. However, PHP 8 forbids the serialization of reflections (hence mocks) and concurrent tasks are serialized before being dispatched. If tasks involve mocks, we can fake the concurrency:

// code to test:
Octane::concurrently([
    fn () => $mockedService->run(),
    fn () => 123,
]);

// test:
$this
    ->mocks(Service::class, ['run' => 'foo'])
    ->expectsConcurrency()
    ->get('route');

In the test above we are running tasks sequentially without serialization, allowing mocked methods to be executed (we will see more about mocks later).

If we need more control over how concurrent tasks run, we can pass a closure to expectsConcurrency(). For example, the test below runs only the first task:

$this
    ->expectsConcurrency(fn (array $tasks) => [ $tasks[0]() ])
    ->get('route');

To manipulate the results of concurrent tasks, we can use expectsConcurrencyResults():

$this
    ->expectsConcurrencyResults([$firstTaskResult, $secondTaskResult])
    ->get('route');

Finally we can make concurrent tasks fail to test our code when something wrong happens:

$this
    ->expectsConcurrencyException() // tasks fail due to a generic exception
    ->get('route');

$this
    ->expectsConcurrencyException(new Exception('message')) // tasks fail due to a specific exception
    ->get('route');

$this
    ->expectsConcurrencyTimeout() // tasks fail due to a timeout
    ->get('route');

Cache

Octane Testbench provides the following assertions to test the Octane cache:

$this
    ->assertOctaneCacheMissing($key) // assert the key is not set
    ->get('route')
    ->assertOctaneCacheHas($key) // assert the key is set
    ->assertOctaneCacheHas($key, $value); // assert the key has the given value

Tables

Octane tables can be tested with the following assertions:

$this
    ->assertOctaneTableMissing($table, $row) // assert the row is not present in the table
    ->assertOctaneTableCount($table, 0) // assert the number of rows in the table
    ->get('route')
    ->assertOctaneTableHas($table, $row) // assert the row is present in the table
    ->assertOctaneTableHas($table, 'row.column' $value) // assert the column in the row has the given value
    ->assertOctaneTableCount($table, 1);

Events

By default listeners for the Octane RequestReceived event are disabled to perform assertions on the application state. However we can register listeners for any Octane event if need be:

$this
    ->listensTo(RequestReceived::class, $listener1, $listener2) // register 2 listeners for RequestReceived
    ->get('route');

$this
    ->stopsListeningTo(TaskReceived::class, $listener1, $listener2) // unregister 2 listeners for TaskReceived
    ->get('route');

Container

Octane Testbench also introduces the following helpers to bind and mock services at the same time while preserving a fluent syntax:

$this
    ->mocks(Service::class, ['expectedMethod' => $expectedValue]) // mock with simple expectations
    ->mocks(Service::class, fn ($mock) => $mock->shouldReceive('method')->twice()) // mock with advanced expectations
    ->partiallyMocks(Service::class, ['expectedMethod' => $expectedValue]) // same as above but partial
    ->partiallyMocks(Service::class, fn ($mock) => $mock->shouldReceive('method')->twice())
    ->get('route');

Change log

Please see CHANGELOG for more information on what has changed recently.

Testing

composer test

Contributing

Please see CONTRIBUTING and CODE_OF_CONDUCT for details.

Security

If you discover any security related issues, please email andrea.marco.sartori@gmail.com instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

cerbero/octane-testbench 适用场景与选型建议

cerbero/octane-testbench 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 4.25k 次下载、GitHub Stars 达 43, 最近一次更新时间为 2021 年 06 月 07 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「testing」 「test」 「laravel」 「octane」 「laravel-octane」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 cerbero/octane-testbench 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 cerbero/octane-testbench 我们能提供哪些服务?
定制开发 / 二次开发

基于 cerbero/octane-testbench 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 4.25k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 43
  • 点击次数: 13
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 43
  • Watchers: 1
  • Forks: 2
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2021-06-07