2025年09月08日/ 浏览 7
在开始编写测试用例前,需要配置专门的测试环境。与普通PHP项目不同,Swoole的常驻内存特性要求测试框架能正确处理协程环境:
bash
composer require --dev phpunit/phpunit
composer require --dev swoole/ide-helper
建议在phpunit.xml中增加Swoole专属配置:
xml
<php>
<ini name="swoole.enable_coroutine" value="true"/>
<env name="APP_ENV" value="testing"/>
</php>
Swoole的测试类需要继承PHPUnit\Framework\TestCase
,但针对协程场景需要特殊处理:
php
class HttpServerTest extends TestCase
{
protected function setUp(): void
{
// 启动测试用HTTP服务
$this->server = new Swoole\Http\Server(‘127.0.0.1’, 9501);
$this->server->on(‘request’, function ($req, $resp) {
$resp->end(json_encode([‘code’ => 200]));
});
$this->server->start();
}
public function testHttpResponse()
{
go(function () {
$cli = new Swoole\Coroutine\Http\Client('127.0.0.1', 9501);
$this->assertTrue($cli->get('/'));
$this->assertEquals(200, json_decode($cli->body)->code);
});
}
protected function tearDown(): void
{
$this->server->shutdown();
}
}
Swoole\Coroutine\run
包裹测试逻辑Swoole\Timer::after
设置测试超时php
public function testCoroutineIsolation()
{
Swoole\Coroutine\run(function () {
$chan = new Swoole\Coroutine\Channel(1);
go(function () use ($chan) {
$chan->push(microtime(true));
});
$this->assertIsFloat($chan->pop());
});
}
针对Swoole服务的Mock需要特殊处理:
php
protected function mockTcpServer(callable $handler): void
{
go(function () use ($handler) {
$server = new Swoole\Coroutine\Server('127.0.0.1', 0);
$server->set(['timeout' => 0.1]);
$server->handle(function ($conn) use ($handler) {
$handler($conn);
});
$server->start();
});
usleep(100000); // 等待服务启动
}
php
public function testDatabaseOperation()
{
$mock = $this->createMock(Swoole\Coroutine\MySQL::class);
$mock->method(‘query’)
->willReturn([‘id’ => 1, ‘name’ => ‘test’]);
Swoole\Coroutine\run(function () use ($mock) {
$result = $mock->query('SELECT * FROM users');
$this->assertEquals('test', $result[0]['name']);
});
}
php
public function testConcurrentRequests()
{
$count = 0;
Swoole\Coroutine\run(function () use (&$count) {
for ($i = 0; $i < 100; $i++) {
go(function () use (&$count) {
$cli = new Swoole\Coroutine\Http\Client('127.0.0.1', 9501);
$cli->get('/');
$count++;
});
}
});
$this->assertEquals(100, $count);
}
php
public function testMemoryLeak()
{
$start = memory_get_usage();
for ($i = 0; $i < 1000; $i++) {
go(function () {
// 测试代码
});
}
$this->assertLessThan($start * 1.1, memory_get_usage());
}
在CI环境中需要特殊配置:yaml
steps:
– name: Start Swoole
run: |
php tests/start_server.php &
sleep 5
– name: Run tests
run: vendor/bin/phpunit
建议使用Docker组合方案:
dockerfile
FROM phpswoole/swoole:php8.2
COPY . /usr/src/app
RUN composer install
CMD ["sh", "-c", "php tests/start_server.php & vendor/bin/phpunit"]
通过以上实践,可以构建完整的Swoole应用测试体系。记住要定期运行测试,特别是在协程逻辑修改后,确保服务的稳定性和可靠性。