pipeline { agent any parameters { choice( name: 'TEST_SCOPE', choices: ['smoke', 'full', 'all', 'miniapp'], description: '测试范围: smoke=仅冒烟测试, full=完整E2E, all=所有测试含性能, miniapp=仅小程序' ) choice( name: 'BROWSER', choices: ['chromium', 'all'], description: '目标浏览器: chromium=单浏览器快速, all=全浏览器' ) string( name: 'BASE_URL', defaultValue: 'http://localhost:3002', description: '测试目标URL' ) } environment { PLAYWRIGHT_HEADLESS = 'true' CI = 'true' NODE_ENV = 'test' JEST_JUNIT_OUTPUT_DIR = 'test-results' JEST_JUNIT_OUTPUT_NAME = 'junit.xml' } stages { stage('环境准备') { parallel { stage('安装Web端依赖') { steps { dir('gym-manage-web') { bat 'npm ci' bat 'npx playwright install chromium --with-deps' } } } stage('安装小程序端依赖') { steps { dir('gym-manage-uniapp') { bat 'npm ci' } } } } } stage('启动后端服务') { steps { dir('gym-manage-api') { bat 'mvn spring-boot:run -pl manage-app -DskipTests &' bat 'mvn spring-boot:run -pl manage-gateway -DskipTests &' } // 等待后端健康检查 script { retry(10) { sleep(10) try { def response = httpRequest 'http://localhost:8084/actuator/health' print "后端健康状态: ${response.content}" } catch (err) { error "后端尚未就绪: ${err.message}" } } } } } stage('冒烟测试') { steps { dir('gym-manage-web') { bat 'npm run test:e2e:smoke' } } post { failure { echo '冒烟测试失败,跳过后续测试' } } } stage('Web E2E 测试') { when { expression { params.TEST_SCOPE != 'smoke' } } steps { dir('gym-manage-web') { script { def projectFilter = params.TEST_SCOPE == 'all' ? '' : '--project=root --project=journeys' bat "npx playwright test ${projectFilter}" } } } } stage('性能测试') { when { expression { params.TEST_SCOPE == 'all' } } steps { dir('gym-manage-web') { bat 'npm run test:e2e:perf' } } } stage('角色边界测试') { when { expression { params.TEST_SCOPE == 'all' } } steps { dir('gym-manage-web') { bat 'npx playwright test --grep "权限|角色|边界|boundary"' } } } stage('小程序编译') { when { anyOf { expression { params.TEST_SCOPE == 'all' } expression { params.TEST_SCOPE == 'miniapp' } } } steps { dir('gym-manage-uniapp') { bat 'npm run build:mp-weixin' } } } stage('小程序 E2E 测试') { when { anyOf { expression { params.TEST_SCOPE == 'all' } expression { params.TEST_SCOPE == 'miniapp' } } } environment { WECHAT_DEVTOOLS_CLI = 'D:\\微信web开发者工具\\cli.bat' } steps { dir('gym-manage-uniapp') { script { try { // 使用一键脚本:自动启动 IDE → 运行测试 → 关闭 IDE bat 'node e2e/run-tests.js --close --verbose' } catch (err) { echo "小程序 E2E 测试失败:${err.message}" // 失败也继续(IDE 可能不可用) unstable('小程序 E2E 测试未通过') } } } } } } post { always { // 归档测试报告 dir('gym-manage-web') { archiveArtifacts artifacts: 'test-results/**/*', allowEmptyArchive: true archiveArtifacts artifacts: 'playwright-report/**', allowEmptyArchive: true junit 'test-results/junit.xml' } // 归档小程序测试报告 dir('gym-manage-uniapp') { archiveArtifacts artifacts: 'test-results/**/*', allowEmptyArchive: true } } failure { // 失败通知 script { def failedTests = currentBuild.rawBuild.getLog(50) emailext( subject: "[测试失败] ${env.JOB_NAME} - Build #${env.BUILD_NUMBER}", body: """
Job: ${env.JOB_NAME}
Build: #${env.BUILD_NUMBER}
分支: ${env.BRANCH_NAME}
日志: ${env.BUILD_URL}
${failedTests}
""",
mimeType: 'text/html',
to: 'dev-team@gym-manage.com'
)
}
}
success {
echo "全部 UI 测试通过!"
}
}
}