Files
gym-manage/Jenkinsfile
T

204 lines
6.5 KiB
Groovy

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: """
<h2>UI 自动化测试失败</h2>
<p><b>Job:</b> ${env.JOB_NAME}</p>
<p><b>Build:</b> #${env.BUILD_NUMBER}</p>
<p><b>分支:</b> ${env.BRANCH_NAME}</p>
<p><b>日志:</b> <a href="${env.BUILD_URL}">${env.BUILD_URL}</a></p>
<h3>最后 50 行日志:</h3>
<pre>${failedTests}</pre>
""",
mimeType: 'text/html',
to: 'dev-team@gym-manage.com'
)
}
}
success {
echo "全部 UI 测试通过!"
}
}
}