引言:为什么在Docker中进行PHP集成测试是必备技能
现代PHP应用程序的开发很少局限于单台服务器。数据库、缓存(Redis、Memcached)、消息队列(RabbitMQ)、外部API——所有这些都需要验证组件间的交互。单元测试(unit tests)虽然能隔离代码,但无法保证类A通过真实数据库与类B正确协作。这时就需要集成测试的介入。
传统方法的问题在于环境配置。开发者需要花费数小时搭建MySQL、配置权限、安装PHP扩展。Docker可以一劳永逸地解决这个问题。本文将详细讲解如何使用Docker和Docker Compose组织PHP应用的集成测试。您将获得现成的配置文件、代码示例以及优化建议。
1. 为PHP测试配置Docker环境
1.1. 基础项目结构
假设我们有一个基于Symfony或Laravel的简单PHP应用(任何框架都适用)。在项目根目录创建docker-compose.yml文件:
version: '3.8'
services: php: build: . volumes: - .:/var/www/html environment: - DATABASE_URL=mysql://test_user:test_pass@db:3306/test_db depends_on: - db
db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root_pass MYSQL_DATABASE: test_db MYSQL_USER: test_user MYSQL_PASSWORD: test_pass ports: - "3307:3306" # 映射到非标准端口,避免与本地数据库冲突
test_runner: image: php:8.2-cli volumes: - .:/var/www/html working_dir: /var/www/html entrypoint: ["vendor/bin/phpunit"] depends_on: - db - php关键要点:
test_runner服务使用独立的PHP CLI容器——这样可以将测试执行与主应用隔离。- 数据库以纯净模式启动。每次运行测试时我们都可以重建数据库。
- MySQL端口映射到
3307,避免干扰开发者的本地数据库。
1.2. PHP应用的Dockerfile
为主服务php创建Dockerfile:
FROM php:8.2-fpm
RUN docker-php-ext-install pdo_mysql mysqli
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
COPY . .
RUN composer install --no-interaction --prefer-dist这个镜像将同时用于开发和测试。必须安装pdo_mysql扩展——否则涉及数据库的测试将会失败。
2. 使用PHPUnit编写集成测试
2.1. PHPUnit基础配置
确保已通过Composer安装PHPUnit。phpunit.xml文件需要指向测试数据库:
<?xml version="1.0" encoding="UTF-8"?><phpunit bootstrap="vendor/autoload.php"> <php> <env name="DATABASE_URL" value="mysql://test_user:test_pass@db:3306/test_db" /> <env name="APP_ENV" value="test" /> </php> <testsuites> <testsuite name="Integration"> <directory>tests/Integration</directory> </testsuite> </testsuites></phpunit>2.2. 集成测试示例:数据库操作
假设我们有一个用户仓库(User Repository)。编写测试验证保存和查询功能:
<?php
namespace App\\Tests\\Integration;
use App\\Entity\\User;use App\\Repository\\UserRepository;use Doctrine\\ORM\\EntityManagerInterface;use Symfony\\Bundle\\FrameworkBundle\\Test\\KernelTestCase;
class UserRepos