Laravel测试在流水线中怎么跑

wen PHP项目 1

本文目录导读:

Laravel测试在流水线中怎么跑

  1. 核心准备
  2. GitLab CI 配置
  3. GitHub Actions 配置
  4. Docker 方式(更稳妥)
  5. 优化建议
  6. 常见问题解决
  7. 完整示例(Jenkins Pipeline)

在CI/CD流水线中运行Laravel测试,通常需要以下几个关键步骤,这里以最流行的 GitLab CIGitHub Actions 为例,提供完整的配置方案。

核心准备

# 基础依赖
- php 8.1+
- composer
- node & npm (如果前端有测试)
- mysql / postgresql / sqlite (测试数据库)

GitLab CI 配置

# .gitlab-ci.yml
stages:
  - test
variables:
  MYSQL_DATABASE: laravel_test
  MYSQL_ROOT_PASSWORD: secret
  DB_HOST: mysql
  DB_DATABASE: laravel_test
  DB_USERNAME: root
  DB_PASSWORD: secret
cache:
  paths:
    - vendor/
    - node_modules/
laravel-tests:
  stage: test
  image: edbizarro/gitlab-ci-pipeline-php:8.1
  services:
    - mysql:8.0
  before_script:
    # 安装 PHP 扩展
    - docker-php-ext-install pdo_mysql
    # 复制环境配置
    - cp .env.example .env
    # 生成应用密钥
    - php artisan key:generate
    # 安装依赖
    - composer install --no-interaction --prefer-dist
    # 数据库迁移
    - php artisan migrate --force
  script:
    # 运行单元测试
    - php vendor/bin/phpunit
    # 或运行特定测试套件
    - php artisan test --testsuite=Feature
    # 检查代码风格
    - ./vendor/bin/phpcs --standard=PSR2 app/ tests/
  after_script:
    - php artisan migrate:reset --force
  artifacts:
    paths:
      - storage/logs/
    when: on_failure
    expire_in: 1 week

GitHub Actions 配置

# .github/workflows/tests.yml
name: Laravel Tests
on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]
jobs:
  laravel-tests:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ROOT_PASSWORD: secret
          MYSQL_DATABASE: laravel_test
        ports:
          - 3306:3306
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
    steps:
    - uses: actions/checkout@v3
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: '8.1'
        extensions: mbstring, dom, fileinfo, mysql
        coverage: xdebug
    - name: Copy .env
      run: |
        cp .env.example .env
        php artisan key:generate
    - name: Install Dependencies
      run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
    - name: Generate key
      run: php artisan key:generate
    - name: Directory Permissions
      run: chmod -R 777 storage bootstrap/cache
    - name: Run Migrations
      run: php artisan migrate --force
    - name: Execute tests
      run: |
        php vendor/bin/phpunit
        # 或使用 Laravel 的测试工具
        # php artisan test
      env:
        DB_CONNECTION: mysql
        DB_DATABASE: laravel_test
        DB_USERNAME: root
        DB_PASSWORD: secret
        DB_HOST: 127.0.0.1
    - name: Upload test results
      if: always()
      uses: actions/upload-artifact@v3
      with:
        name: test-results
        path: |
          storage/logs/
          tests/_output/

Docker 方式(更稳妥)

# Dockerfile.test
FROM php:8.1-cli
# 安装系统依赖
RUN apt-get update && apt-get install -y \
    git \
    unzip \
    libpq-dev \
    libzip-dev \
    && docker-php-ext-install pdo_mysql zip
# 安装 Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /app
COPY . .
# 安装项目依赖
RUN composer install --no-interaction --prefer-dist
# 运行测试
CMD ["php", "vendor/bin/phpunit"]
# .gitlab-ci.yml 中使用 Docker
test-docker:
  stage: test
  image: docker:latest
  services:
    - docker:dind
    - mysql:8.0
  script:
    - docker build -t laravel-test -f Dockerfile.test .
    - docker run --rm \
        --env DB_HOST=mysql \
        --env DB_DATABASE=laravel_test \
        --env DB_USERNAME=root \
        --env DB_PASSWORD=secret \
        laravel-test

优化建议

1 并行测试

# 拆分测试任务
parallel:
  matrix:
    - TEST_TYPE: [Unit, Feature]
      PHP_VERSION: ['8.0', '8.1']

2 仅测试变更

# 只运行与变更文件相关的测试
composer test -- --filter="$(git diff --name-only HEAD~1 | xargs -I {} basename {} .php)"

3 使用 SQLite 加速

# 在测试环境中使用 SQLite
env:
  DB_CONNECTION: sqlite
  DB_DATABASE: :memory:

常见问题解决

1 数据库连接失败

# 检查 MySQL 服务是否就绪
until mysqladmin ping -h "$DB_HOST" --silent; do
  echo 'waiting for mysql...'
  sleep 2
done

2 内存不足

# 增加 PHP 内存限制
- echo "memory_limit=512M" > /usr/local/etc/php/conf.d/memory.ini

3 测试超时

# 设置超时时间
timeout: 30m

完整示例(Jenkins Pipeline)

// Jenkinsfile
pipeline {
    agent any
    tools {
        php 'php8.1'
        composer 'composer2'
    }
    stages {
        stage('Prepare') {
            steps {
                sh 'cp .env.example .env'
                sh 'php artisan key:generate'
                sh 'composer install --no-interaction --prefer-dist'
            }
        }
        stage('Test') {
            parallel {
                stage('Unit Tests') {
                    steps {
                        sh 'php vendor/bin/phpunit --testsuite=Unit'
                    }
                }
                stage('Feature Tests') {
                    environment {
                        DB_CONNECTION = 'sqlite'
                        DB_DATABASE = ':memory:'
                    }
                    steps {
                        sh 'php artisan migrate --force'
                        sh 'php vendor/bin/phpunit --testsuite=Feature'
                    }
                }
            }
        }
        stage('Code Quality') {
            steps {
                sh './vendor/bin/phpcs --standard=PSR12 app/ tests/'
                sh './vendor/bin/phpstan analyse app/'
            }
        }
    }
    post {
        always {
            archiveArtifacts artifacts: 'storage/logs/*.log', onlyIfSuccessful: false
            junit 'storage/logs/*.xml'
        }
    }
}
  1. 环境隔离:使用 Docker 或 CI 提供的服务容器
  2. 数据库策略:推荐 SQLite 内存数据库(最快),或 MySQL 服务
  3. 缓存依赖:缓存 vendor/ 和 node_modules/ 加速构建
  4. 并行执行:拆分 Unit 和 Feature 测试并行运行
  5. 失败处理:保存日志和测试报告便于调试
  6. 安全性:不要在配置中硬编码密码,使用 CI 变量

选择合适的 CI/CD 平台,根据项目规模和团队需求调整配置,建议从简单的配置开始,逐步增加并行测试、代码质量检查等功能。

抱歉,评论功能暂时关闭!