后端测试流程(自动化测试完整流程)

后端测试流程(自动化测试完整流程)
自动化测试完整流程

Conda+Git+Docker+Jenkins+TypeScript+Playwright 构建 CI/CD + 自动化测试完整流程

本次方案在原有Git+Docker+Jenkins+TS+Playwright基础上融入Conda,核心解决Python 环境隔离与依赖管理问题(适配 TS/Playwright 主工程中嵌入 Python 模块、多版本 Python 依赖、Python 侧辅助脚本 / 服务等场景),全程保持容器化统一环境核心设计,实现「代码提交→环境构建→TS 编译→自动化测试→镜像打包→容器部署」的端到端 CI/CD 流水线,同时保证 Python/Conda、Node.js/TS 两大环境互不冲突、独立隔离。

一、技术栈说明(核心作用 + 版本建议 + 协同关系)

各技术栈分工明确,Conda 作为 Python 专属环境管理工具,不替代 Node.js(TS/Playwright 的基础),二者在容器内协同运行,Docker 实现全环境容器化,Jenkins 负责流水线编排,形成「版本管理 + 双环境隔离 + 容器化 + 流水线 + 自动化测试」的完整体系:

技术栈

核心作用

版本建议

协同关系

Git

代码版本管理、分支控制、Jenkins 构建触发(WebHook)

后端测试流程(自动化测试完整流程)

GitLab/GitHub/Gitee

托管所有代码 + 配置文件(含 Conda/TS/ 流水线配置)

Conda(Miniconda3)

Python 环境隔离、Python 依赖安装 / 版本管理,支持多 Python 环境切换

Miniconda3-py310_23.10.0

与 Node.js 共存于容器,仅管理 Python 侧依赖

Docker

全环境容器化打包(Conda+Node.js + 应用 + 测试),解决环境不一致问题

24.0+

作为所有环节的统一运行载体,包含 Conda/Node.js 基础环境

Docker Compose

编排多容器服务(Jenkins+Docker-daemon、带 Conda 的应用容器)

2.24+

简化 Jenkins 和应用容器的部署与管理

Jenkins

CI/CD 流水线核心编排,串联所有环节,将自动化测试作为强制卡点

2.450+(LTS)

无需内置 Conda/Node.js,通过 Docker 调用容器内环境

TypeScript

主工程开发语言(前端 Vue/React、后端 Node.js/Express),强类型保证代码质量

5.2+

基于 Node.js 运行,与 Conda 环境完全隔离

Playwright

自动化测试框架,支持多浏览器 E2E 测试 / 接口测试,TS 原生支持,可测试 Python/TS 混合服务

1.40+

基于 Node.js 运行,可调用 Conda 管理的 Python 服务接口

Node.js

TS 编译运行、Playwright 执行的基础,提供 npm/yarn 包管理

18.x/20.x(LTS)

与 Conda 共存于容器,通过环境变量隔离

Python

工程辅助模块开发(如数据处理、接口代理、自动化脚本)

3.9+/3.10+

由 Conda 统一管理版本和依赖

核心设计思路

  1. 双环境隔离共存:Conda 管理 Python 环境(含版本、依赖),Node.js 管理 TS/Playwright 环境,二者在同一 Docker 镜像中通过环境变量隔离,互不干扰;
  2. 容器化贯穿全程:Jenkins、Conda+Node.js 运行环境、目标应用、Playwright 测试均基于 Docker 运行,彻底消除「本地能跑、远端失败」的环境问题;
  3. Conda 配置代码化:通过environment.yml定义 Conda 环境(Python 版本、依赖),实现「Python 环境即代码」,与项目代码一起托管到 Git;
  4. 测试强制卡点:Playwright 自动化测试覆盖 TS 主服务和 Conda 管理的 Python 辅助服务,测试不通过则终止流水线,禁止镜像构建和部署;
  5. Jenkins 轻量编排:Jenkins 本身不安装 Conda/Node.js,仅通过 Docker 命令调用项目专属镜像中的环境,简化 Jenkins 配置,提升流水线可移植性。

二、环境前置配置(服务器端,核心:Docker+Jenkins + 基础权限)

前提条件

  1. 一台 Linux 服务器(Ubuntu 20.04/22.04 推荐,内存≥4G、硬盘≥50G,因新增 Conda 环境,需略增加磁盘空间);
  2. 本地开发机安装:Git、Miniconda3、Node.js、Docker、VSCode(TS/Python 开发);
  3. 服务器端仅需提前安装 Docker+Docker Compose,Conda/Node.js 无需服务器手动安装,全部在项目 Docker 镜像中构建。

步骤 1:服务器端安装 Docker+Docker Compose(基础)

与原有方案一致,核心是配置 Docker 免 sudo,避免后续 Jenkins 操作 Docker 权限问题,执行以下命令:

# 1. 卸载旧版本(如有)sudo apt-get remove docker docker-engine docker.io containerd runc# 2. 安装依赖sudo apt-get update && sudo apt-get install -y ca-certificates curl gnupg lsb-release# 3. 添加Docker官方GPG密钥curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg# 4. 添加Docker软件源echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null# 5. 安装Docker Engine+Containerd+Docker Composesudo apt-get update && sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin# 6. 验证安装docker --version && docker compose version# 7. 配置免sudo(核心,避免Jenkins操作Docker权限错误)sudo usermod -aG docker $USERnewgrp docker  # 权限立即生效,无需重启

步骤 2:Docker 化部署 Jenkins(带 Docker 权限挂载,无修改)

Jenkins 仍采用容器化部署,核心是挂载宿主机 Docker 套接字,让 Jenkins 容器能执行docker build/push/run命令,无需内置 Conda/Node.js,配置与原有方案一致,保证轻量性。

2.1 新建 Jenkins 持久化目录

mkdir -p ~/jenkins/{home,workspace}sudo chmod -R 777 ~/jenkins  # 赋予读写权限,避免容器操作失败

2.2 编写 Jenkins 专属 docker-compose.yml

在~/jenkins目录下创建docker-compose.yml:

version: '3.8'services:  jenkins:    image: jenkins/jenkins:lts-jdk17  # 基于JDK17,兼容后续所有操作    container_name: jenkins-ci-cd    restart: always    ports:      - "8080:8080"  # Jenkins前端访问端口      - "50000:50000"  # Jenkins代理节点通信端口    volumes:      - ~/jenkins/home:/var/jenkins_home  # 持久化Jenkins配置/插件      - ~/jenkins/workspace:/var/jenkins_workspace  # 流水线工作空间      - /var/run/docker.sock:/var/run/docker.sock  # 核心:挂载Docker套接字      - /usr/bin/docker:/usr/bin/docker  # 挂载Docker命令行工具      - /usr/libexec/docker/cli-plugins:/usr/libexec/docker/cli-plugins  # 挂载Docker Compose插件    environment:      - TZ=Asia/Shanghai  # 配置时区,避免构建时间错乱

2.3 启动 Jenkins 并完成初始化

cd ~/jenkinsdocker compose up -d# 查看启动日志,获取初始化密码docker logs -f jenkins-ci-cd

浏览器访问http://服务器IP:8080,按提示完成初始化:输入日志中的初始化密码→安装推荐插件→创建管理员账户→确认访问地址,步骤与原有方案一致,无额外配置。

步骤 3:Jenkins 安装必备插件(无新增,保留原有)

因 Conda/Node.js 环境在项目 Docker 镜像中管理,Jenkins 无需新增插件,仅保留原有核心插件即可,安装完成后重启 Jenkins:

  1. 登录 Jenkins → 系统管理 → 插件管理 → 可选插件;
  2. 搜索并安装以下插件(勾选后直接安装): Git Plugin(Git 代码拉取) NodeJS Plugin(备用,若需 Jenkins 直接调用 Node.js) Docker Plugin(Docker 管理) Docker Pipeline Plugin(Pipeline 执行 Docker 命令) Pipeline Plugin(声明式流水线基础) HTML Publisher Plugin(Playwright 测试报告归档) Generic Webhook Trigger Plugin(Git WebHook 触发,可选)
  3. 重启 Jenkins:docker restart jenkins-ci-cd。

步骤 4:Jenkins 全局工具配置(极简,仅保留 Git)

核心变化:无需在 Jenkins 中配置 Node.js/Conda,所有环境均在项目 Docker 镜像中构建,Jenkins 仅需识别 Git 即可,简化配置:

  1. 登录 Jenkins → 系统管理 → 全局工具配置;
  2. Git 配置:填写名称(如Git-2.39),路径留空(容器内已内置 Git);
  3. 无需配置 Node.js/Conda,直接点击「保存」。

三、核心实施步骤(从本地开发到 Jenkins 流水线,核心融合 Conda)

整体流程概览

本地开发(Conda+TS+Playwright)→ 编写Conda/TS/测试配置 → Git提交代码到远程仓库 → Jenkins(手动/WebHook)触发构建 → 流水线执行(拉取代码→Docker构建(含Conda+Node.js环境)→ 启动容器内服务 → Playwright自动化测试 → 重新打包生产镜像 → 部署容器)→ 测试报告归档/构建结果通知

核心变化:将「Conda 环境创建、Node.js 依赖安装、TS 编译」全部移入Docker 构建阶段,Jenkins 流水线仅负责调用 Docker 命令,大幅简化流水线逻辑,提升环境一致性。

步骤 1:本地开发环境初始化(Conda+TS+Playwright)

本地需同时配置 CondaPython 环境和 Node.jsTS 环境,先完成本地验证,再提交代码,避免远端流水线失败。

1.1 本地创建项目目录并初始化 Conda 环境

Conda 环境通过environment.yml配置,实现代码化管理,替代手动conda create/install命令,方便 Git 托管和远端构建。

# 1. 创建项目根目录mkdir conda-ts-playwright-ci-cd && cd conda-ts-playwright-ci-cd# 2. 编写Conda环境配置文件environment.yml(核心)touch environment.yml# 3. 初始化Conda环境(本地测试用)conda env create -f environment.yml# 4. 激活Conda环境conda activate ts-py-env  # 环境名与environment.yml中一致

关键:environment.yml 配置文件(Python 版本 + 依赖)

定义 Conda 环境名称、Python 版本、需要安装的 Python 依赖(如requests/flask/pandas等,根据项目需求调整),示例:

name: ts-py-env  # Conda环境名称,本地和远端一致channels:  # Conda镜像源,提升下载速度  - defaults  - conda-forgedependencies:  # 依赖列表,版本可指定  - python=3.10  # Python版本,建议3.9+  - pip=24.0     # pip版本  - flask=2.3.3  # 示例:Python Web框架(若有Python辅助服务)  - requests=2.31.0  # 示例:Python请求库  - pip:  # 额外pip安装的依赖(可选)    - pyyaml==6.0.1

1.2 本地初始化 TS+Playwright 项目

与原有方案一致,安装 TS 核心依赖和 Playwright,编写业务代码和测试用例,注意:Node.js 环境与 Conda 环境完全隔离,无需激活 Conda 即可运行

# 1. 初始化npm项目npm init -y# 2. 安装TS开发依赖npm i -D typescript @types/node ts-node @types/express# 3. 初始化TS配置文件npx tsc --init# 4. 安装Playwright并初始化测试环境npm i -D @playwright/testnpx playwright install --with-deps  # 安装浏览器和依赖npx playwright init  # 生成tests目录和playwright.config.ts# 5. 安装TS业务依赖(示例:Express)npm i express

1.3 调整 tsconfig.json(适配 Node.js,无修改)

修改核心配置,编译 TS 到dist目录,示例:

{  "compilerOptions": {    "target": "ES2020",    "module": "CommonJS",    "outDir": "./dist",    "rootDir": "./src",    "strict": true,    "esModuleInterop": true,    "skipLibCheck": true  },  "include": ["./src/**/*"],  "exclude": ["./node_modules", "./tests", "./playwright-report", "./conda-env"]}

1.4 编写混合业务代码(TS 主服务 + Python 辅助服务,示例)

适配「TS 为主、Python 为辅」的典型场景,编写简单服务代码,用于后续自动化测试:

  1. TS 主服务(src/index.ts):Node.js/Express 接口
  2. typescript
  3. 运行
  4. import express, { Request, Response } from 'express'; const app = express(); const TS_PORT = 3000; // TS核心接口 app.get('/ts/api', (req: Request, res: Response) => { res.send({ code: 200, type: 'ts', msg: 'TS主服务正常运行', data: { title: 'Conda+TS CI/CD Demo' } }); }); app.listen(TS_PORT, () => { console.log(`TS服务运行在:http://localhost:${TS_PORT}`); }); export default app;
  5. Python 辅助服务(py/app.py):Flask 接口(由 Conda 管理)
  6. python
  7. 运行
  8. from flask import Flask import os app = Flask(__name__) PY_PORT = 5000 # Python辅助接口 @app.route('/py/api') def py_api(): return { "code": 200, "type": "python", "msg": "Python辅助服务正常运行(Conda管理)", "conda_env": os.environ.get('CONDA_DEFAULT_ENV', 'ts-py-env') } if __name__ == '__main__': app.run(host='0.0.0.0', port=PY_PORT, debug=False)

1.5 编写 Playwright 自动化测试用例(覆盖 TS+Python 服务)

在tests目录下创建mixed.spec.ts,测试TS 主服务和 Python 辅助服务的可用性,实现全链路测试:

import { test, expect } from '@playwright/test';test('全链路测试:TS服务+Python辅助服务', async ({ request }) => {  // 测试TS主服务接口  const tsResponse = await request.get('http://localhost:3000/ts/api');  expect(tsResponse.status()).toBe(200);  const tsData = await tsResponse.json();  expect(tsData.code).toBe(200);  expect(tsData.type).toBe('ts');  // 测试Python辅助服务接口(Conda管理)  const pyResponse = await request.get('http://localhost:5000/py/api');  expect(pyResponse.status()).toBe(200);  const pyData = await pyResponse.json();  expect(pyData.code).toBe(200);  expect(pyData.type).toBe('python');  expect(pyData.conda_env).toBe('ts-py-env'); // 验证Conda环境激活成功});

1.6 配置 package.json 脚本(本地开发 / 测试)

封装 TS 编译、服务启动、测试命令,本地验证使用:

{  "scripts": {    "dev:ts": "ts-node src/index.ts", // 启动TS服务    "build": "tsc",                    // 编译TS到dist目录    "start:ts": "node dist/index.js",  // 运行TS生产服务    "test": "playwright test",         // 执行Playwright测试    "test:report": "playwright show-report" // 查看测试报告  }}

1.7 本地全流程验证(必做)

本地同时启动 TS 服务和 Python 服务,执行 Playwright 测试,验证所有环节正常:

# 1. 激活Conda环境,启动Python服务(后台运行)conda activate ts-py-envpython py/app.py > py-service.log 2>&1  2. 编译TS代码,启动TS服务(后台运行)npm run buildnpm run start:ts > ts-service.log 2>&1  3. 等待服务就绪,执行Playwright测试sleep 5 && npm run test# 4. 本地查看测试报告npm run test:report

验证通过标准:Conda 环境激活正常、Python/TS 服务均启动、Playwright 测试用例 100% 通过、生成playwright-reportHTML 报告。

步骤 2:Git 仓库配置(新增 Conda 相关忽略文件)

编写.gitignore,排除 Conda 环境、Node.js 依赖、编译产物等无用文件,减少仓库体积:

# Conda环境相关(本地环境,不提交)conda-env/env/.conda/conda-meta/pkgs/*.conda# Node.js依赖node_modules/# TS编译产物dist/# Playwright测试相关playwright-report/test-results/playwright/.cache/# 环境变量和配置.env.env.*.DS_Store# IDE配置.idea/.vscode/*.swp# Docker相关.dockerignore# 日志文件*.log

完成后,将所有代码和配置文件提交到远程 Git 仓库(GitHub/GitLab/Gitee):

git initgit remote add origin 你的Git仓库地址git add .git commit -m "init: Conda+TS+Playwright项目,完成基础服务和自动化测试"git push -u origin main

步骤 3:编写 Dockerfile(核心,融合 Conda+Node.js 环境)

这是本次方案的核心:基于Miniconda3 官方镜像构建基础环境,在同一镜像中安装 Node.js,创建 CondaPython 环境,安装 Python/Node.js 依赖,编译 TS 代码,实现「Conda+Node.js 双环境共存且隔离」,最终生成包含完整运行环境的应用镜像。

采用多阶段构建,分为「构建阶段」(包含所有开发依赖,用于编译、测试)和「运行阶段」(仅包含生产依赖,轻量),示例 Dockerfile(项目根目录):

# 阶段1:构建阶段(Conda+Node.js+开发依赖,用于编译TS和测试)FROM continuumio/miniconda3:latest AS builderLABEL maintainer="CI/CD Demo"WORKDIR /app# 步骤1:配置Conda环境,安装Python依赖COPY environment.yml .# 创建Conda环境(与本地一致),并激活RUN conda env create -f environment.yml && \    echo "conda activate ts-py-env" >> ~/.bashrc  # 写入bashrc,自动激活环境# 配置Conda环境变量(核心,让容器内任意命令行可调用conda环境)ENV PATH /opt/conda/envs/ts-py-env/bin:$PATHENV CONDA_DEFAULT_ENV ts-py-env# 步骤2:安装Node.js(LTS 20.x,与本地一致)RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \    apt-get update && apt-get install -y nodejs && \    node -v && npm -v  # 验证Node.js安装# 步骤3:复制Node.js依赖配置,安装所有依赖(含开发依赖)COPY package*.json .RUN npm ci  # 比npm install更快,更严格,适配CI/CD# 步骤4:复制所有项目代码,编译TS代码COPY . .RUN npm run build  # 编译TS到dist目录# 阶段2:运行阶段(仅包含生产依赖,轻量,用于最终部署)FROM continuumio/miniconda3:latest AS runnerWORKDIR /appENV PYTHONUNBUFFERED=1ENV PATH /opt/conda/envs/ts-py-env/bin:$PATHENV CONDA_DEFAULT_ENV ts-py-env# 步骤1:从构建阶段复制Conda环境(核心,避免重新安装)COPY --from=builder /opt/conda/envs/ts-py-env /opt/conda/envs/ts-py-env# 步骤2:从构建阶段复制Node.js环境COPY --from=builder /usr/bin/node /usr/bin/nodeCOPY --from=builder /usr/lib/node_modules /usr/lib/node_modulesRUN ln -s /usr/lib/node_modules/npm/bin/npm-cli.js /usr/bin/npm# 步骤3:复制TS编译产物、Python代码、生产依赖配置COPY --from=builder /app/dist ./distCOPY --from=builder /app/py ./pyCOPY --from=builder /app/package*.json .# 安装Node.js生产依赖(移除开发依赖)RUN npm ci --only=production# 步骤4:暴露端口(TS服务3000 + Python服务5000)EXPOSE 3000 5000# 步骤5:编写启动脚本(核心,同时启动TS和Python服务)COPY start.sh .RUN chmod +x start.sh  # 赋予执行权限# 启动命令CMD ["./start.sh"]

关键配套文件:start.sh(启动脚本,同时运行 TS+Python 服务)

因需要同时启动TS 主服务Python 辅助服务,编写 Shell 脚本作为容器启动命令,替代手动启动,确保容器启动后所有服务正常运行:

#!/bin/bashset -e  # 任意命令失败则终止脚本# 激活Conda环境source /opt/conda/bin/activate ts-py-env# 后台启动Python辅助服务echo "启动Python辅助服务(Conda管理)..."python py/app.py  前台启动TS主服务(容器主进程,保证容器不退出)echo "启动TS主服务..."node dist/index.js

将start.sh放在项目根目录,与 Dockerfile 同级,确保本地赋予执行权限:chmod +x start.sh。

编写.dockerignore 文件(优化 Docker 构建)

排除 Docker 构建时无需复制的文件,提升构建速度,减少镜像体积:

# Conda相关environment.ymlconda-env/# Node.js相关node_modules/# TS相关src/tsconfig.json# 测试相关tests/playwright.config.tsplaywright/# Git相关.git/.gitignore# 其他Jenkinsfilestart.sh.bak*.log

步骤 4:编写 Jenkinsfile(声明式流水线,简化版)

核心变化:流水线逻辑大幅简化,将「Conda 环境创建、Node.js 依赖安装、TS 编译」全部移入 Docker 构建阶段,Jenkins 仅负责拉取代码→构建测试镜像→运行容器→执行 Playwright 测试→构建生产镜像→部署容器,所有环境相关操作均在容器内完成,提升流水线稳定性。

Jenkinsfile(项目根目录,声明式,带详细注释):

groovy

// 声明式流水线pipeline {    agent any  // 运行在Jenkins本地节点    // 环境变量配置    environment {        APP_NAME = "conda-ts-playwright-ci-cd"  // 应用名称        TEST_IMAGE = "${APP_NAME}:test"         // 测试镜像标签(含开发依赖)        PROD_IMAGE = "${APP_NAME}:latest"       // 生产镜像标签(轻量)        CONTAINER_NAME = "${APP_NAME}-container"// 容器名称        TS_PORT = 3000                          // TS服务端口        PY_PORT = 5000                          // Python服务端口    }    // 流水线阶段(核心)    stages {        // 阶段1:拉取Git仓库代码        stage('拉取代码') {            steps {                echo "===== 拉取Git仓库${env.GIT_URL}的${env.BRANCH_NAME}分支代码 ====="                git url: "${env.GIT_URL}", branch: "${env.BRANCH_NAME}", credentialsId: '' // 私有仓库填写凭证ID            }        }        // 阶段2:构建Docker测试镜像(含Conda+Node.js+开发依赖)        stage('构建测试镜像') {            steps {                echo "===== 构建Docker测试镜像:${env.TEST_IMAGE} ====="                sh "docker build -t ${env.TEST_IMAGE} ."                // 验证镜像构建成功                sh "docker images | grep ${env.TEST_IMAGE} || (echo '测试镜像构建失败' && exit 1)"            }        }        // 阶段3:运行测试容器+执行Playwright自动化测试(强制卡点)        stage('自动化测试(Playwright)') {            steps {                echo "===== 启动测试容器并执行Playwright自动化测试 ====="                // 停止并删除旧容器(若存在)                sh "docker stop ${env.CONTAINER_NAME} || true && docker rm ${env.CONTAINER_NAME} || true"                // 启动测试容器(端口映射、后台运行,挂载项目目录用于获取测试报告)                sh "docker run -d --name ${env.CONTAINER_NAME} \                    -p ${env.TS_PORT}:${env.TS_PORT} -p ${env.PY_PORT}:${env.PY_PORT} \                    -v \$(pwd):/app \                    ${env.TEST_IMAGE} \                    /bin/bash -c 'source /opt/conda/bin/activate ts-py-env && npm run test'"                // 等待测试完成,查看容器日志                sh "docker logs -f ${env.CONTAINER_NAME}"                // 验证测试是否通过(容器退出码为0则通过)                sh "docker inspect ${env.CONTAINER_NAME} --format='{{.State.ExitCode}}' | grep 0 || (echo '自动化测试失败' && exit 1)"            }            post {                // 无论测试成功/失败,归档Playwright测试报告                always {                    echo "===== 归档自动化测试报告 ====="                    publishHTML(                        target: [                            allowMissing: false,                            alwaysLinkToLastBuild: true,                            reportDir: 'playwright-report',                            reportFiles: 'index.html',                            reportName: 'Conda+TS Playwright自动化测试报告'                        ]                    )                    // 清理测试容器                    sh "docker stop ${env.CONTAINER_NAME} || true && docker rm ${env.CONTAINER_NAME} || true"                }                // 测试失败,终止流水线                failure {                    error "===== 自动化测试用例执行失败,禁止构建生产镜像和部署 ====="                }            }        }        // 阶段4:构建Docker生产镜像(轻量,仅含生产依赖)        stage('构建生产镜像') {            steps {                echo "===== 构建Docker生产镜像:${env.PROD_IMAGE} ====="                sh "docker build -t ${env.PROD_IMAGE} --target runner ." // 指定运行阶段                // 验证生产镜像构建成功                sh "docker images | grep ${env.PROD_IMAGE} || (echo '生产镜像构建失败' && exit 1)"            }        }        // 阶段5:部署生产容器(最终部署)        stage('部署生产容器') {            steps {                echo "===== 部署生产容器:${env.CONTAINER_NAME} ====="                // 停止并删除旧生产容器(若存在)                sh "docker stop ${env.CONTAINER_NAME} || true && docker rm ${env.CONTAINER_NAME} || true"                // 启动生产容器(后台运行、自动重启、端口映射)                sh "docker run -d --name ${env.CONTAINER_NAME} \                    -p ${env.TS_PORT}:${env.TS_PORT} -p ${env.PY_PORT}:${env.PY_PORT} \                    --restart always \                    ${env.PROD_IMAGE}"                // 验证容器启动成功                sh "docker ps | grep ${env.CONTAINER_NAME} || (echo '生产容器启动失败' && docker logs ${env.CONTAINER_NAME} && exit 1)"                echo "===== 部署成功!TS服务:http://${env.JENKINS_URL%:*}:${env.TS_PORT}/ts/api | Python服务:http://${env.JENKINS_URL%:*}:${env.PY_PORT}/py/api ====="            }        }    }    // 流水线后置操作    post {        success {            echo "===== 流水线执行成功!✅ Conda+TS+Playwright应用已完成构建、测试、部署 ====="        }        failure {            echo "===== 流水线执行失败!❌ 请查看控制台日志和测试报告排查问题 ====="        }        always {            // 清理工作空间,避免磁盘占用            cleanWs()        }    }}

步骤 5:Jenkins 创建 Pipeline 任务(关联 Git+Jenkinsfile)

Jenkins 端创建流水线任务,关联远程 Git 仓库,拉取 Jenkinsfile 并执行,步骤与原有方案一致,无额外配置:

  1. 登录 Jenkins → 新建任务 → 输入任务名称(如conda-ts-playwright-pipeline)→ 选择「流水线」→ 确定;
  2. 配置任务核心参数: 通用:勾选「丢弃旧的构建」,设置最大保留数为 10(避免磁盘占用); 流水线: 定义:选择「从 SCM 获取」; SCM:选择 Git; 仓库 URL:填写你的远程 Git 仓库地址; 凭证:私有仓库添加「用户名 + 密码」凭证并选择; 分支指定:*/main(或你的开发分支); 脚本路径:Jenkinsfile(项目根目录);
  3. 点击「保存」,完成 Pipeline 任务配置。

四、流水线触发与验证(与原有方案一致)

方式 1:手动触发(测试阶段,首选)

  1. 进入创建的 Pipeline 任务页面 → 左侧「立即构建」;
  2. 点击构建编号(如 #1)→ 「控制台输出」,实时查看流水线执行日志;
  3. 执行完成后,通过 Jenkins 页面查看「Conda+TS Playwright 自动化测试报告」,验证所有用例通过。

方式 2:Git WebHook 自动触发(生产阶段,推荐)

配置 Git 仓库 WebHook 后,本地git push或合并分支到 main 时,Jenkins 自动触发流水线,实现「代码提交即构建测试部署」。

  • GitHub:WebHook 地址为http://服务器IP:8080/github-webhook/(末尾斜杠必加),触发事件选择「Just the push event」;
  • GitLab:WebHook 地址为http://服务器IP:8080/project/任务名称,触发事件勾选「推送事件」,取消 SSL 验证(若无证书)。

流水线成功验证标准(新增 Python 服务验证)

  1. Jenkins 所有阶段显示蓝色对勾,控制台输出无报错,最后显示「Pipeline succeeded」;
  2. 访问 TS 服务:http://服务器IP:3000/ts/api,正常返回 TS 接口数据;
  3. 访问 Python 服务:http://服务器IP:5000/py/api,正常返回 Python 接口数据,且conda_env字段为ts-py-env(验证 Conda 环境激活成功);
  4. Jenkins 页面可查看 Playwright 测试报告,TS+Python 服务用例 100% 通过
  5. 执行docker ps,生产容器正常运行,无退出;
  6. 执行docker exec 容器名称 conda info --envs,验证 Conda 环境正常存在且激活。

五、常见问题排查(新增 Conda 相关高频问题)

问题 1:Docker 构建时报错「conda: command not found」

原因:未使用 Miniconda3 官方镜像,或镜像中 conda 命令未加入环境变量;

解决方案:Dockerfile 基础镜像必须使用continuumio/miniconda3:latest,无需额外配置 conda 路径。

问题 2:容器内 Python 服务启动成功,但接口访问报「模块找不到」

原因:未激活 Conda 环境,Python 依赖未安装到指定环境;

解决方案

  1. 检查 Dockerfile 中是否执行conda env create -f environment.yml;
  2. 启动脚本中添加source /opt/conda/bin/activate ts-py-env,确保激活 Conda 环境后再启动 Python 服务。

问题 3:Playwright 测试报错「Python 服务连接拒绝」

原因:Python 服务启动晚于 TS 服务,或服务未绑定到0.0.0.0;

解决方案

  1. Python 服务代码中,Flask 启动需指定host='0.0.0.0'(允许容器外部访问);
  2. 启动脚本中,Python 服务后台运行后,添加sleep 3等待服务就绪,再启动 TS 服务。

问题 4:Jenkins 执行docker run时报错「权限不足」

原因:Jenkins 容器内用户无 Docker 操作权限;

解决方案:宿主机执行sudo chmod 666 /var/run/docker.sock,重启 Jenkins 容器。

问题 5:Conda 环境创建时报错「Solving environment: failed」

原因:environment.yml中依赖版本冲突,或 Conda 镜像源网络问题;

解决方案

  1. 简化environment.yml,指定兼容的依赖版本;
  2. 在environment.yml中添加国内镜像源:
  3. yaml
  4. channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ - conda-forge

问题 6:容器启动后,TS 服务正常,Python 服务未运行

原因:启动脚本中 Python 服务未后台运行,或脚本无执行权限;

解决方案

  1. 启动脚本中 Python 启动命令后加&(后台运行);
  2. Dockerfile 中添加RUN chmod +x start.sh,赋予脚本执行权限。

六、扩展优化(生产环境建议)

  1. Conda 环境缓存:Docker 构建时,将/opt/conda/pkgs目录挂载为卷,缓存 Conda 依赖包,提升后续构建速度;
  2. 多环境隔离部署:通过 Jenkins 参数化构建,配合不同的environment.yml和docker-compose.yml,实现 dev/test/prod 环境的 Conda/TS 依赖隔离;
  3. Python/TS 服务监控:在生产容器中集成supervisord,替代 Shell 启动脚本,实现服务监控和自动重启;
  4. 私有镜像仓库:搭建 Harbor,将生产镜像推送到私有仓库,避免镜像保存在单台服务器;
  5. 测试分层:将 Playwright 测试拆分为「冒烟测试」「回归测试」,流水线中可指定执行,提升测试效率;
  6. Conda 环境精简:生产阶段的 Conda 环境仅保留必要依赖,通过conda clean -a清理缓存,减小镜像体积。

总结

本次方案在原有 CI/CD 体系中无缝融入Conda,核心解决了「TS/Playwright 主工程中 Python 环境管理」的问题,实现了Conda+Node.js 双环境的容器化隔离与协同,关键亮点如下:

  1. 环境统一:所有环节(Conda/Node.js/ 测试 / 部署)均基于 Docker 运行,彻底消除环境不一致问题;
  2. 配置代码化:Conda 环境通过environment.yml管理,流水线通过Jenkinsfile管理,与项目代码一起托管到 Git,便于版本控制和团队协作;
  3. 轻量高效:Jenkins 无需内置任何业务环境,仅负责流水线编排,所有环境操作均在项目 Docker 镜像中完成,简化 Jenkins 配置;
  4. 全链路测试:Playwright 自动化测试覆盖 TS 主服务和 Conda 管理的 Python 辅助服务,测试作为强制卡点,保证交付质量;
  5. 可扩展性强:适配「TS 为主、Python 为辅」的各类项目,仅需调整environment.yml和 Dockerfile 中的依赖,即可快速迁移。

整套方案保持了原有 CI/CD 流程的简洁性和可落地性,同时弥补了 Python 环境管理的空白,适用于前端、后端、全栈(TS+Python)等各类项目的 CI/CD + 自动化测试需求。

文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有

相关阅读