1. 项目概述与核心价值

如果你已经跟着这个系列,一步步从零开始用 Python 和 Selenium 写好了 Web UI 自动化测试脚本,并且已经把它们放到了 Git 仓库里,那么恭喜你,你已经完成了从“手工测试”到“自动化脚本”的质变。但不知道你有没有这样的感觉:脚本写好了,每次想跑一下看看结果,还得手动打开 IDE 或者命令行,敲下 python run_tests.py 。这感觉,就像买了一台全自动咖啡机,但每次想喝咖啡还得自己按开关、倒豆子、接杯子——自动化得不够彻底。

这就是我们今天要解决的问题:让测试脚本自己“动”起来。通过配置 Jenkins,我们将搭建一个“测试机器人”。这个机器人会按照你设定的时间表(比如每天凌晨2点,或者每次代码提交后),自动去 Git 仓库拉取最新的测试代码,然后在指定的机器上默默地执行所有测试用例,最后把测试报告发给你看。整个过程,无需人工干预。这不仅仅是“偷懒”,更是现代软件工程中保证质量、快速反馈的核心实践——持续集成/持续交付(CI/CD)中的关键一环。

对于测试工程师、开发工程师或者 DevOps 工程师来说,掌握 Jenkins 的配置,意味着你能将自动化测试的价值最大化,让它从个人工具升级为团队基础设施。接下来,我们就手把手地,在 Jenkins 中创建一个新项目,并配置它定时自动执行我们的 Python Web UI 测试代码。

2. Jenkins 项目创建与基础配置

在开始配置之前,请确保你已经有一台安装好 Jenkins 的服务器(可以是本地虚拟机、云服务器等),并且能够通过浏览器正常访问 Jenkins 的管理界面。我们的目标是从无到有,创建一个专属于我们自动化测试任务的“工作空间”。

2.1 创建新的 Jenkins 项目(Item)

登录 Jenkins 后,你会看到主面板。点击左侧的“新建 Item”,这是创建任何自动化任务的起点。

  1. 输入项目名称 :给它起一个见名知意的名字,例如 Web-UI-AutoTest-Daily 。名称最好能体现项目类型和执行频率。
  2. 选择项目类型 :这里有多种选择,对于我们的 Python 测试任务,最常用、最灵活的是 “构建一个自由风格的软件项目” 。它提供了图形化界面来配置构建步骤、触发器、后置动作等,对新手非常友好。Pipeline(流水线)虽然更强大,但需要编写 Jenkinsfile,我们可以在后续进阶中再接触。
  3. 点击“确定” :进入详细的项目配置页面。

注意 :项目名称中避免使用空格和特殊字符,尽量使用连字符(-)或下划线(_),这在后续的目录路径和脚本引用中会更方便。

2.2 通用基础配置解析

项目配置页面有很多选项卡,我们先从“General”(通用设置)开始。

  • 描述 :填写一段关于此项目的描述,例如“用于每日定时执行主站核心业务流程的 Web UI 自动化测试,使用 Python + Selenium”。
  • 丢弃旧的构建 :这是一个非常重要的设置。每次 Jenkins 执行任务(构建)都会产生日志、报告等数据。如果不加限制,磁盘很快会被塞满。建议勾选此选项,并设置策略。例如:
    • 策略 :选择“Log Rotation”(日志轮转)。
    • 保持构建的天数 :例如 7 ,表示只保留最近7天的构建记录。
    • 保持构建的最大个数 :例如 10 ,表示最多只保留10次构建记录,超过则删除最旧的。
    • 两者可以同时设置 ,Jenkins 会取两者中先达到的条件来删除旧构建。我通常设置“保持构建的最大个数”为20,这对于回溯问题已经足够。
  • GitHub 项目 :如果你的代码仓库在 GitHub 上,可以在这里填入项目 URL,方便快速跳转。这不是必填项。

这些基础设置就像给我们的“测试机器人”建立一个档案和清理规则,让管理更有序。

3. 源码管理与构建触发器配置

这是 Jenkins 项目的“大脑”和“闹钟”部分。“大脑”告诉它代码从哪里来,“闹钟”告诉它什么时候开始工作。

3.1 源码管理(Source Code Management)

我们的代码放在 Git 仓库里(如 GitHub, GitLab, Gitee),所以这里选择 Git

  • Repository URL :填写你的 Git 仓库的 HTTPS 或 SSH 地址。例如 https://github.com/yourname/web-ui-autotest.git
  • Credentials(凭据) :如果仓库是私有的,需要添加凭据。点击“添加” -> “Jenkins”。
    • 种类 :选择“Username with password”(用户名密码)或“SSH Username with private key”(SSH密钥)。对于公开仓库,可以留空。
    • 填写你的仓库用户名和密码(或上传私钥)。添加后,在下拉框中选择刚刚创建的凭据。
  • Branches to build :指定拉取哪个分支的代码。通常我们监控主分支,例如 */main */master 。你也可以配置多个分支。

实操心得 :强烈建议使用 SSH 密钥 的方式连接私有仓库,比账号密码更安全。在 Jenkins 服务器上生成 SSH 密钥对,将公钥添加到 Git 仓库的部署密钥(Deploy Keys)中,私钥添加到 Jenkins 凭据里。这样可以避免密码过期或变更带来的问题。

3.2 构建触发器(Build Triggers)

这里配置“闹钟”,即何时自动启动一次构建(执行测试)。我们主要使用两种:

  1. 定时构建(Build periodically) :这就是我们标题中提到的“定时自动执行”。它使用 Cron 表达式来定义时间表。
    • 勾选“Build periodically”。
    • 在日程表(Schedule)中输入 Cron 表达式。例如:
      • H 2 * * * :每天凌晨2点(某个分钟)执行一次。 H 代表“Hash”,是为了让大量任务错峰执行,避免在整点产生负载峰值。它会在2点左右的某个随机分钟执行。
      • H */4 * * * :每4小时执行一次。
      • H 9,18 * * 1-5 :每周一到周五的上午9点和下午6点各执行一次。
    • Cron 表达式有5个字段,空格分隔: 分钟(0-59) 小时(0-23) 日期(1-31) 月份(1-12) 星期(0-7,0和7都代表周日) * 表示任意值, / 表示间隔, , 表示列表, - 表示范围。
  2. 轮询 SCM(Poll SCM) :定期检查 Git 仓库是否有新的提交,如果有则触发构建。这可以实现“代码提交即测试”。它的日程表也是 Cron 表达式,例如 H/5 * * * * 表示每5分钟检查一次仓库。

注意事项 :对于团队协作项目,“轮询 SCM”是更即时的反馈方式。但对于每日巡检或压力测试,“定时构建”更合适。 不要同时启用多个过于频繁的触发器 ,以免给 Jenkins 服务器和测试环境带来不必要的负担。我通常将每日构建放在业务低峰期(如凌晨),而轮询 SCM 则针对特性分支,频率设置为每15或30分钟一次。

4. 构建环境与构建步骤详解

这是 Jenkins 项目的“双手”,它定义了具体要执行哪些操作。对于 Python 测试项目,核心是准备环境和执行命令。

4.1 构建环境(Build Environment)

这里可以设置一些构建前的全局环境。对于我们这个项目,可能用到的有:

  • Delete workspace before build starts :在构建开始前删除工作空间。这能确保每次构建都是从零开始拉取最新代码,避免旧文件干扰。 慎用 ,因为每次都要重新拉取所有依赖,会延长构建时间。对于 Python 项目,如果依赖很稳定,可以不勾选。
  • Provide Node & npm bin/ folder to PATH :如果是前端项目需要 Node.js,可以勾选。对于纯 Python 后端测试,不需要。
  • Set Jenkins user’s environment variables :可以设置一些自定义的环境变量,供后续的脚本使用。

一个更常见的做法是: 不在这里做复杂的清理,而是在构建步骤(Execute shell)的开头,用脚本进行有选择的清理

4.2 构建步骤(Build Steps)—— 核心中的核心

点击“增加构建步骤”,选择“Execute shell”(Linux/Unix)或“Execute Windows batch command”(Windows)。我们的测试服务器通常是 Linux,所以以 Shell 为例。

这里输入的脚本,就是 Jenkins “机器人”在拉取代码后,要在其工作目录(workspace)中执行的命令。一个典型的 Python Web UI 测试构建步骤可能如下:

#!/bin/bash
# 1. 进入项目目录(Jenkins 默认就在工作空间根目录,但显式声明是好习惯)
cd $WORKSPACE

# 2. 打印环境信息,便于调试
echo "当前工作目录:$(pwd)"
echo "Python 版本:$(python3 --version)"
echo "Pip 版本:$(pip3 --version)"

# 3. 创建并激活虚拟环境(强烈推荐,避免污染系统环境)
if [ ! -d "venv" ]; then
  echo "创建虚拟环境..."
  python3 -m venv venv
fi
echo "激活虚拟环境..."
source venv/bin/activate

# 4. 升级pip并安装依赖
echo "安装项目依赖..."
pip install --upgrade pip
# 假设你的项目依赖定义在 requirements.txt 中
if [ -f "requirements.txt" ]; then
  pip install -r requirements.txt
else
  # 如果没有 requirements.txt,直接安装核心包
  pip install selenium webdriver-manager pytest pytest-html allure-pytest
fi

# 5. 执行测试用例
echo "开始执行自动化测试..."
# 使用 pytest 运行 tests/ 目录下的所有测试,并生成多种报告
# a) 生成 JUnit XML 格式报告(Jenkins 可以解析并展示趋势图)
pytest tests/ --junitxml=test-results.xml -v
# b) 生成 HTML 报告(更易读)
pytest tests/ --html=report.html --self-contained-html
# c) 如果你使用了 Allure,可以生成 Allure 结果数据
# pytest tests/ --alluredir=./allure-results

# 6. 检查测试结果,非0退出码会让 Jenkins 认为构建失败
TEST_EXIT_CODE=$?
if [ $TEST_EXIT_CODE -ne 0 ]; then
  echo "警告:部分测试用例失败,退出码:$TEST_EXIT_CODE"
  # 这里不直接 exit 1,因为可能还想继续生成报告、发送通知
fi

# 7. 停用虚拟环境(可选,脚本结束后环境自动失效)
deactivate

echo "构建步骤执行完毕。"

关键点解析:

  1. 虚拟环境 :使用 venv 为每次构建创建独立的 Python 环境至关重要。这确保了依赖隔离,避免了不同项目或同一项目不同版本间的依赖冲突。
  2. 依赖安装 requirements.txt 文件是 Python 项目的依赖清单。在团队协作中,务必保证这个文件准确且完整。可以使用 pip freeze > requirements.txt 来生成。
  3. 测试执行器 :我们使用 pytest ,因为它功能强大、插件丰富。 --junitxml 参数生成的 XML 报告可以被 Jenkins 的 “JUnit Plugin” 插件解析,从而在 Jenkins 页面上形成漂亮的测试结果趋势图和历史记录。
  4. 退出码 :Shell 脚本中,最后一个命令的退出码( $? )决定了 Jenkins 构建的成功(0)与失败(非0)。我们通过 TEST_EXIT_CODE=$? 捕获 pytest 的退出码,可以进行更灵活的处理(比如失败后仍执行归档操作)。

5. 后置构建操作与报告归档

测试执行完了,我们需要收集“战利品”——测试报告和日志,并可能根据结果做一些事情,比如发送通知。

5.1 后置构建操作(Post-build Actions)

点击“增加后置构建步骤”。

  1. 归档构件(Archive the artifacts)

    • 这是用来保存测试生成的报告、日志等文件,以便在 Jenkins 页面上直接下载或查看。
    • 在“要归档的文件”中,填写报告路径,例如 report.html, test-results.xml, logs/*.log 。可以使用通配符。
    • 归档后,在每次构建的页面左侧,会出现“构建产物”链接,可以直接下载 report.html 查看详细的 HTML 报告。
  2. 发布 JUnit 测试结果报告(Publish JUnit test result report)

    • 如果你在构建步骤中使用了 --junitxml 生成了 XML 报告,一定要配置这一步。
    • 在“测试报告 XMLs”中填写路径,例如 test-results.xml
    • 效果 :配置后,Jenkins 项目主页和每次构建详情页,都会出现“测试结果”栏目。你可以看到历史通过率趋势图、本次测试的通过/失败/跳过详情,并且可以直接点击失败的用例查看错误堆栈。这是 Jenkins 集成测试最核心的功能之一。
  3. Allure 报告(如果需要)

    • 如果你使用了 Allure,需要先安装 “Allure Jenkins Plugin” 插件。
    • 在后置步骤中选择 “Allure Report”,并指定结果目录(如 ./allure-results )和报告生成路径。
    • Allure 报告比原生 HTML 报告更美观、交互性更强。
  4. 构建后操作(Editable Email Notification)

    • 这是发送邮件通知的插件(需要安装 “Email Extension Plugin”)。
    • 你可以配置当构建失败、由失败转为成功、或不稳定时,自动发送邮件给相关责任人。
    • 邮件内容可以自定义模板,包含构建信息、变更记录、测试结果摘要等,非常实用。

5.2 一个完整的后置构建流程示例

理想的后置流程应该是:

  • 无论成功失败,都归档 HTML 报告和日志 :方便随时查看。
  • 解析 JUnit XML 报告 :让 Jenkins 掌握测试趋势。
  • 根据构建状态发送邮件 :失败时@开发团队,成功时@测试团队或只记录。

6. 项目保存与首次构建验证

完成所有配置后,滚动到页面底部,点击“保存”。

保存后,你会进入这个项目的主页面。现在,我们可以手动触发一次构建,来验证所有配置是否正确。

  1. 立即构建 :点击左侧菜单的“立即构建”。下方会开始出现构建历史(如 #1)。
  2. 查看控制台输出 :点击构建历史编号(如 #1),进入该次构建详情页。再点击“控制台输出”,你将看到实时(或已结束)的构建日志。这是 排错最重要的依据
  3. 检查关键节点
    • 查看日志中 Git 克隆是否成功。
    • 查看虚拟环境创建和依赖安装是否顺利(有无网络超时、版本冲突)。
    • 查看 pytest 是否正常启动并执行了测试用例。
    • 最后查看构建状态是蓝色(成功)还是红色(失败)。

常见首次构建问题与排查:

问题现象 可能原因 排查步骤
控制台输出 Command ‘git‘ not found Jenkins 服务器未安装 Git 登录 Jenkins 服务器,运行 git --version 确认。通过包管理器安装,如 yum install git apt-get install git
python3: command not found 服务器未安装 Python3 或未在 PATH 中 确认 Python3 安装。在 Jenkins 系统管理 -> 全局工具配置中,可以指定 Python 解释器的绝对路径,然后在构建环境中选择。
pip install 超时或失败 网络问题,或默认源速度慢 在构建脚本中为 pip 换源: pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
虚拟环境激活失败( source: not found Shell 语法问题。Jenkins 可能使用 sh 而非 bash 在构建步骤最顶端显式指定 #!/bin/bash 。或在 Jenkins 项目配置的 Shell 路径中指定 /bin/bash
测试执行时报错,找不到浏览器驱动 服务器是纯命令行环境,无图形界面,或驱动未正确安装/配置 Web UI 测试需要浏览器和驱动。方案一:使用 xvfb 创建虚拟显示帧缓冲。方案二:使用无头模式(Headless)的 Chrome/Firefox。 推荐方案二 ,在构建脚本中安装驱动: pip install webdriver-manager ,并在测试代码中使用 WebDriverManager 自动管理驱动。
构建成功但看不到测试趋势图 未配置“发布 JUnit 测试结果报告”后置步骤 检查构建步骤中是否生成了 test-results.xml 文件,以及后置步骤中路径是否配置正确。

避坑技巧 始终优先查看“控制台输出”日志 。95%的问题都能从日志中找到线索。对于复杂的 Shell 脚本,可以先在 Jenkins 服务器的相同用户环境下手动执行一遍,确保每一条命令都能成功。

7. 进阶配置与优化建议

当基础功能跑通后,可以考虑以下优化,让整个流程更健壮、更高效。

7.1 参数化构建

有时我们可能想手动触发构建时传入一些参数,比如测试不同的环境(测试环境、预发布环境)或运行不同的测试套件。

  1. 在项目配置的“General”部分,勾选“参数化构建过程”。
  2. 添加参数,例如:
    • 选项参数(Choice Parameter) :名称 TARGET_ENV ,选项 test/preprod/prod ,描述“选择测试环境”。
    • 字符串参数(String Parameter) :名称 TEST_TAGS ,默认值 smoke ,描述“pytest 的 -k 标签,用于筛选用例”。
  3. 在构建的 Shell 脚本中,就可以通过 $TARGET_ENV $TEST_TAGS 来使用这些参数。例如:
    echo "目标环境:$TARGET_ENV"
    pytest tests/ -k "$TEST_TAGS" --junitxml=test-results.xml
    
  4. 保存后,“立即构建”按钮会变成“Build with Parameters”,点击后可以先选择或输入参数再执行。

7.2 多分支流水线(Pipeline)简介

自由风格项目简单直观,但当项目复杂、有多个分支需要不同构建策略时,“流水线”(Pipeline)是更好的选择。它使用一个名为 Jenkinsfile 的文本文件(通常放在项目根目录)来定义整个构建、测试、部署流程,实现了“Pipeline as Code”。

一个极简的 Jenkinsfile 示例(声明式语法):

pipeline {
    agent any // 在任何可用代理上执行
    triggers {
        cron('H 2 * * *') // 定时触发器
    }
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/yourname/web-ui-autotest.git'
            }
        }
        stage('Test') {
            steps {
                sh '''
                    python3 -m venv venv
                    source venv/bin/activate
                    pip install -r requirements.txt
                    pytest tests/ --junitxml=test-results.xml --html=report.html
                '''
            }
        }
        stage('Report') {
            steps {
                junit 'test-results.xml'
                archiveArtifacts artifacts: 'report.html'
            }
        }
    }
}

在 Jenkins 中创建一个“流水线”项目,在配置里指定 Jenkinsfile 的路径(如从 SCM 获取),它就会按照文件定义的流程执行。这种方式将构建逻辑和代码一起版本化,更利于维护和复用。

7.3 分布式构建与节点管理

如果测试任务很重,或者需要在特定环境(如特定操作系统、有特殊软件的机器)下运行,可以使用 Jenkins 的节点(Agent)功能。

  • 主节点(Master) :负责 UI 展示、任务调度。
  • 代理节点(Agent) :实际执行构建任务的机器。 你可以在“系统管理”->“节点管理”中新增节点,将测试任务分配到专门的测试服务器上执行,减轻主节点压力,并适应不同的环境需求。在项目配置的“General”里,可以限制项目在哪个标签的节点上运行。

7.4 环境变量与凭据安全管理

不要在构建脚本中硬编码密码、密钥等敏感信息。Jenkins 提供了“凭据(Credentials)”绑定功能。

  1. 在 Jenkins 首页 -> “凭据” -> “系统” -> “全局凭据”中,添加一个“Secret text”或“Username with password”类型的凭据,记下它的 ID(如 prod-db-password )。
  2. 在项目配置的“构建环境”中,勾选“Use secret text(s) or file(s)”,将凭据绑定到一个环境变量名(如 DB_PASS )上。
  3. 在构建脚本中,就可以通过 $DB_PASS 安全地使用这个密码了。在控制台输出中,Jenkins 会自动将其替换为 **** ,防止泄露。

8. 维护与监控

项目配置好并稳定运行后,并非一劳永逸。需要定期维护和监控。

  1. 监控构建历史 :定期查看项目主页,关注构建的成功率。如果近期频繁失败,需要分析是环境问题、测试用例问题还是脚本问题。
  2. 分析测试趋势图 :利用 JUnit 插件生成的趋势图,观察测试用例数量、通过率、失败率的变化。如果通过率持续下降,说明新代码可能引入了回归缺陷。
  3. 清理旧数据 :定期检查 Jenkins 服务器的磁盘空间,确保“丢弃旧的构建”策略生效。也可以手动进入项目工作空间目录进行清理。
  4. 更新依赖 :定期检查并更新 requirements.txt 中的第三方库版本,特别是 Selenium 和浏览器驱动,以兼容新版本的浏览器。
  5. 日志管理 :如果测试脚本会产生大量日志,考虑在构建脚本中加入日志轮转或清理旧日志的指令,避免工作空间无限膨胀。

配置 Jenkins 自动执行测试,就像为你的质量保障体系安装了一个永不停歇的哨兵。它把我们从重复的手工触发中解放出来,提供了及时、客观的反馈。从创建一个自由风格项目开始,配置源码、触发器、构建脚本和后置动作,再到解决无头浏览器、环境隔离等实际问题,这个过程本身也是对自动化测试框架和持续集成理念的一次深度实践。当你在凌晨收到一封“构建成功”的邮件,或者早上打开电脑看到一张清晰的测试通过率图表时,你会觉得这一切的配置都是值得的。

更多推荐