【抽奖活动管理平台】完整质量测试报告:功能 / 自动化 / 性能三大维度总结

文章目录


项目名称 年会抽奖系统 版本号 /
发布类型 全量发布 测试负责人 独断万古他化
测试完成日期 2026/04/02 联系方式

项目背景:

项目背景与意义

公司年会抽奖系统是企业内部活动的核心环节,承载着活跃现场氛围、传递企业文化、提升员工参与感与归属感的重要作用。系统的稳定性、公平性、操作流畅度,直接影响年会的整体体验与员工满意度。

通过项目开发与测试实践,我深入掌握了 Java、Spring Boot、MyBatis、Redis、MySQL 等后端技术栈,以及接口自动化、UI 自动化、性能压测等测试核心技能,并在实际场景中强化了对系统稳定性、数据一致性、并发安全性、用户体验与可维护性的理解,实现了将所学开发与测试知识融会贯通到项目中,加深了自己对全链路质量保障的理解与实践能力。

为保障年会现场抽奖环节的平稳落地,本次针对该系统开展了全维度质量验证工作,覆盖功能流程、接口交互、UI 操作、并发性能多个层面,通过多轮测试提前发现并修复逻辑漏洞、界面异常与性能瓶颈,确保系统在现场高并发、高频操作的压力下依然稳定可靠,实现公平、透明、零故障的抽奖体验,为年会活动的顺利开展保驾护航。

项目概述

> 已实现的主要功能
  • 用户登录与注册
  • 活动列表查看与创建
  • 奖品列表查看与创建
  • 人员列表查看与普通用户创建
  • 抽奖实现与中奖记录查看
> 当前系统存在的不足
  • 权限控制薄弱:无细粒度的权限管理,仅通过身份区分
  • 抽奖过程缺少分布式锁,高并发下可能重复抽奖
  • 缺少数据导出功能,中奖记录等数据无法导出
  • 监控告警确实:无系统监控和异常告警机制

项目系统功能简析

1. 登录功能

  • 用户需输入已注册的手机号和密码进行登录
  • 支持两种登录方式:密码登录、短信验证码登录
  • 登录成功后跳转至后台管理页面
  • 未登录状态下访问受保护页面,将强制跳转至登录页
  • 右下角提供"去注册"链接,可跳转至注册页面

2. 后台管理页

  • 左侧显示导航菜单,包含三大模块:活动管理、奖品管理、人员管理
  • 右上角提供"退出"按钮:退出当前用户,返回登录页
  • 每个模块下包含二级菜单:
    • 活动管理:活动列表、新建抽奖活动
    • 奖品管理:奖品列表、创建奖品
    • 人员管理:人员列表、注册用户

3. 活动列表页

  • 展示已创建的活动列表,包括活动名称、描述、状态
  • 支持分页查询
  • 点击"查看详情"可跳转至抽奖页面
  • 左侧导航栏可切换至其他功能模块

4. 新建活动页

  • 填写活动名称、活动描述
  • 从奖品列表中选择奖品并设置奖品等级、数量
  • 从人员列表中选择参与抽奖的人员
  • 点击"提交"创建活动,创建成功后跳转至活动列表

5. 奖品列表页

  • 展示奖品列表,包括奖品名称、描述、图片、价值
  • 支持分页查询
  • 左侧导航栏可切换至创建奖品页面

6. 创建奖品页

  • 填写奖品名称、描述、价值
  • 支持上传奖品图片
  • 点击"提交"创建奖品,创建成功后跳转至奖品列表

7. 人员列表页

  • 展示已注册用户列表,包括用户名、邮箱、手机号、身份
  • 支持按身份筛选(管理员/普通用户)
  • 左侧导航栏可切换至注册用户页面

8. 注册用户页

  • 填写用户名、邮箱、手机号、密码
  • 系统自动设置为普通用户身份
  • 点击"提交"完成注册,注册成功后跳转至人员列表

9. 抽奖展示页

  • 展示活动名称、奖品信息(等级、名称、数量、图片)
  • 提供两个操作按钮:
    • 查看上一奖项:返回上一个奖项查看
    • 开始抽奖:开始当前奖项的抽奖
  • 抽奖过程展示人员名单滚动效果
  • 点击"点我确定"确定中奖者,保存中奖记录
  • 所有奖项抽完后展示完整中奖名单
  • 提供"分享结果"按钮,可复制链接分享给他人查看

测试项目相关信息

测试安排:

模块 子模块 前端 开发 提测时间 测试 工时 排期 进度 备注
用户管理 注册、密码登录、验证码登录 独断万古他化 独断万古他化 3.20 独断万古他化 1d 3.20-3.21 测试完成
活动管理 活动创建、列表查询、详情查询 独断万古他化 独断万古他化 3.20 独断万古他化 1d 3.20-3.21 测试完成
奖品管理 奖品创建、图片上传、列表查询 独断万古他化 独断万古他化 3.22 独断万古他化 1d 3.22-3.23 测试完成
人员管理 人员列表、用户注册 独断万古他化 独断万古他化 3.22 独断万古他化 0.5d 3.22-3.23 测试完成
抽奖执行 抽奖流程、中奖保存、状态流转 独断万古他化 独断万古他化 3.24 独断万古他化 1.5d 3.24-3.26 测试完成 核心
中奖记录 记录查询、缓存、分享 独断万古他化 独断万古他化 3.24 独断万古他化 1.5d 3.24-3.26 测试完成

测试分类:

(1)功能测试:

  • 功能测试结果:所以测试全部通过,通过率 100%

(2)自动化测试:

本项目自动化测试从接口自动化和UI自动化两个层面进行测试,具体详细的测试详解如下链接:

本测试报告下只做简单总结与描述。

1> UI 自动化测试:
编写Web测试用例
创建自动化架构

测试框架采用分层设计,最底层是公共工具类 ,负责浏览器驱动的创建和管理、截图功能、通用等待方法等。中间层是各个页面的测试类,每个类对应一个页面,封装该页面的所有操作方法。最上层是测试入口类,负责按照业务流程组织测试用例的执行顺序。并且设置了images文件夹,专门存放自动化过程中关键步骤的截图留存,以便后续查看是否有异常问题。

自动化测试工具准备

公共类处理代码:

java 复制代码
/**
 * Selenium WebDriver 工具类
 * 提供浏览器驱动管理、截图、弹窗处理等公共方法
 */
public class Utils {

    /** WebDriver 驱动对象,静态变量保证全局只有一个驱动实例 */
    public static WebDriver driver = null;

    /** 显式等待对象,用于等待特定条件成立 */
    public WebDriverWait wait = null;

    /** 测试基础URL地址 */
    public static String baseUrl = "http://43.143.84.36:8081";

    /**
     * 构造函数,初始化驱动并打开指定URL
     * @param url 要访问的页面地址
     */
    public Utils(String url) {
        driver = createDriver();
        driver.get(url);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    /**
     * 默认构造函数,不打开新页面
     * 用于已经切换到目标页面的场景
     */
    public Utils() {
        if (driver == null) {
            driver = createDriver();
        }
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    /**
     * 创建 WebDriver 驱动对象
     * 使用单例模式,确保整个测试过程只创建一个浏览器实例
     * @return WebDriver 实例
     */
    public static WebDriver createDriver() {
        if (null == driver) {
            // 使用 WebDriverManager 自动下载并配置 ChromeDriver
            // 指定 Chrome 版本号,确保驱动版本匹配
            WebDriverManager.chromedriver().driverVersion("146.0.7680.178").setup();

            // 配置 Chrome 浏览器选项
            ChromeOptions options = new ChromeOptions();
            // 允许远程源访问,解决跨域问题
            options.addArguments("--remote-allow-origins=*");
            // 禁用浏览器通知弹窗
            options.addArguments("--disable-notifications");

            // 创建 Chrome 驱动实例
            driver = new ChromeDriver(options);

            // 设置隐式等待时间(全局等待,查找元素时最多等待5秒)
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
            // 最大化浏览器窗口
            driver.manage().window().maximize();
        }
        return driver;
    }

    /**
     * 屏幕截图方法
     * 将截图保存到 ./src/test/java/images/日期/方法名-时间.png
     * @param str 截图文件名前缀,通常使用测试方法名
     * @throws IOException 文件操作异常
     */
    public void ScreenShot(String str) throws IOException {
        // 日期格式化器,用于生成目录名(年-月-日)
        SimpleDateFormat sim1 = new SimpleDateFormat("yyyy-MM-dd");
        // 时间格式化器,用于生成文件名后缀(时分秒毫秒)
        SimpleDateFormat sim2 = new SimpleDateFormat("HHmmssSS");

        String dirTime = sim1.format(System.currentTimeMillis());
        String fileTime = sim2.format(System.currentTimeMillis());

        // 构建截图文件完整路径
        String fileName = "./src/test/java/images/" + dirTime + "/" + str + "-" + fileTime + ".png";

        // 执行截图并保存到文件
        File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(srcFile, new File(fileName));
    }

    /**
     * 处理 JavaScript Alert 弹窗
     * 等待弹窗出现并点击确定按钮
     */
    public void alertAccept() {
        // 显式等待弹窗出现
        wait.until(ExpectedConditions.alertIsPresent());
        // 切换到弹窗并点击确定
        Alert alert = driver.switchTo().alert();
        alert.accept();
    }

    /**
     * 线程休眠方法
     * 用于在测试过程中添加固定等待时间
     * @param millis 休眠时间(毫秒)
     */
    public void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭浏览器并释放资源
     * 测试结束后调用,清理驱动对象
     */
    public void quit() {
        if (driver != null) {
            driver.quit();
            driver = null;
        }
    }
}
测试用例tests的编写
① 登录页面
  • 检查页面的正常加载:
  • 检查成功登录:
  • 检查登录失败:

脚本测试过程:

② 奖品创建与奖品列表页面
  • 奖品正常创建
  • 奖品异常创建
  • 校验页面元素正常
  • 校验列表内容正常
  • 分页功能是否正常

脚本测试过程:

③ 普通用户注册与人员列表页面
  • 校验页面元素正常
  • 校验列表内容正常
  • 用户异常创建(空/错误/格式异常/已被注册等等)
  • 用户正常创建

脚本测试过程:

④ 创建活动与活动列表页面
  • 校验页面元素
  • 测试 奖品/人员 圈选模态框
  • 创建活动异常(数量异常等等)
  • 创建活动正常(单奖品-单用户/多奖品-多用户)
  • 活动列表各元素展示无误

脚本测试过程:

⑤ 抽奖页面
  • 校验抽奖页
  • 按照抽奖流程脚本执行自动抽奖

脚本测试过程:

2> 接口自动化:
编写接口测试用例

接口自动化测试从不同的模块设计测试用例:选取选择功能复杂、逻辑分支多;对业务影响大、风险高;重复性高的接口进行自动化测试,这部分接口通常都是核心接口,使用率高自然更需要保证这些接口的质量。

创建自动化框架

采用分层设计的思想,将框架划分为测试用例层、业务逻辑层、接口封装层、工具支持层和数据层。

测试用例的编写

完整的测试代码参考码云链接:lottery_system_ApiAutoTest

创建奖品示例:

java 复制代码
class TestCreatePrize:

    url = host + "/prize/create"

    schema = {
      "type": "object",
      "required": ["code","data","msg"],
      "additionalProperties": False,
      "properties": {
        "code": {
          "type": "number"
        },
        "data": {
          "type": ["number","null"]
        },
        "msg": {
          "type": "string"
        }
      }
    }

    # 未登录状态下
    @pytest.mark.order(11)
    def test_create_nologin(self):
        r = Request().post(url=self.url,raise_for_status=False)
        assert r.status_code == 401

    # 登录状态下 ------ 正常创建
    @pytest.mark.order(14)
    def test_cteate_success(self):

        header = {
            "user_token":get_yaml("data.yaml","data.user_token")
        }
        params = {
            "prizeName": "吹风机",
            "description": "吹风机",
            "price": 100
        }
        form_data = {
            "param":json.dumps(params)
        }

        img_path = Path(__file__).resolve().parent.parent / "data" / "images" / "吹风机.png"
        with open(img_path, "rb") as f:
            files = {"prizePic": ("吹风机.png", f, "image/png")}
            r = Request().post(url=self.url, headers=header, data=form_data, files=files, raise_for_status=False)
            validate(r.json(),schema=self.schema)
            assert r.json()["code"] == 200

    # 登录状态下 ------ 异常创建
    @pytest.mark.order(12)
    @pytest.mark.parametrize("prize",[
        {
            "prizeName": "",
            "description": "吹风机",
            "price": 100,
            "msg":"奖品名不能为空"
        },
        {
            "prizeName": "吹风机",
            "description": "吹风机",
            "price": "",
            "msg":"奖品价格不能为空"
        }
    ])
    def test_create_fail(self,prize):

        header = {
            "user_token": get_yaml("data.yaml", "data.user_token")
        }
        params = {
            "prizeName": prize["prizeName"],
            "description": prize["description"],
            "price": prize["price"]
        }
        form_data = {
            "param":json.dumps(params)
        }
        img_path = Path(__file__).resolve().parent.parent / "data" / "images" / "吹风机.png"
        with open(img_path, "rb") as f:
            files = {"prizePic": ("吹风机.png", f, "image/png")}
            r = Request().post(url=self.url, headers=header, data=form_data, files=files, raise_for_status=False)
            validate(r.json(), schema=self.schema)
            assert r.json()["code"] == 500

    @pytest.mark.order(13)
    def test_create_nofile(self):
        header = {
            "user_token": get_yaml("data.yaml", "data.user_token")
        }
        params = {
            "prizeName": "吹风机",
            "description": "吹风机",
            "price": 100
        }
        form_data = {
            "param": json.dumps(params)
        }

        r = Request().post(url=self.url, headers=header, data=form_data, raise_for_status=False)
        validate(r.json(), schema=self.schema)
        assert r.json()["code"] == 500
数据流转

完整数据流转链路:

bash 复制代码
注册成功 → 保存用户数据(手机号、密码、邮箱、用户ID)
    ↓
登录成功 → 保存Token和身份信息
    ↓
用户列表 → 保存NORMAL用户ID和姓名
    ↓
奖品列表 → 保存奖品ID列表
    ↓
创建活动 → 使用奖品ID和用户数据,保存活动ID及关联数据
    ↓
抽奖 → 使用活动ID、奖品ID、用户数据执行抽奖
    ↓
中奖记录/活动详情 → 使用活动ID查询结果

用例执行顺序:

执行顺序的设计原则是:先执行数据生产者,后执行数据消费者。

Order 测试模块 测试内容 数据产出
1-4 注册模块 完成管理员和普通用户注册 用户数据(手机号、密码、邮箱等)
5-6 验证码模块 发送验证码测试
7-8 登录模块 管理员和普通用户登录 Token、身份信息
9-10 用户列表 查询用户列表 NORMAL用户ID和姓名
11-16 奖品模块 创建奖品、获取奖品列表 奖品ID列表
17-21 活动模块 创建活动、获取活动列表 活动ID及关联数据
22-24 抽奖模块 执行抽奖操作 中奖记录
25-30 记录模块 查询中奖记录、活动详情
测试结果

通过allure 生成在线的html 测试报告:测试通过率 100%,涉及92条测试用例,总耗时13秒左右。

脚本优化建议:在数据生产者类执行完毕后,使用多线程的方式同步执行其他消费者类,减少后续消费者类等待耗时。

该测试报告支持查看每一条测试用例的执行,且有日志打印,可以查看该次测试的具体情况。

(3)性能测试:

本项目性能压测以 梯度加压 + 平滑压测 的方式进行测试,也就是负载测试;

具体详细的性能测试详解如下链接:抽奖系统性能负载测试:基于 JMeter 的梯度加压与本地缓存优化全流程

1> 压测架构
2> 压测结果

在优化接口(二级缓存+接口限流)后,200 并发下梯度进行压测,总压测时间近11分钟,表现稳定,所有测试接口响应最大值都在 200ms 以下,且异常值为 0,

聚合报告:

响应时间表:

TPS(吞吐量)表

发现TPS仍能够继续增加,还未到达明显的平滑拐点,说明该系统还能够承受更大的并发数,有待下一步继续加压测试。

3> 压测报告

整体状态: 所有接口请求 100% 成功,无错误,APDEX(应用性能指数)满分(1.000),性能表现优秀。

关键指标:

  • 总请求数:594,855 次
  • 平均响应时间:7.98ms,最慢响应仅 222ms
  • 吞吐量:917.90 TPS,无性能瓶颈
  • 各接口平均响应时间均在 10ms 左右,满足高并发场景需求

性能报告图标页:

在 200 并发梯度压测过程中,所有接口响应稳定、无异常波动,平均和分位延迟均维持在低水平;吞吐量、网络收发量与并发数同步变化,无阻塞,系统和链路状态健康,整体性能表现良好。

测试总结:

本次项目围绕系统全生命周期质量保障,构建了 "功能验证 + 自动化回归 + 性能压测" 三位一体的测试覆盖体系:

  1. 功能测试全覆盖: 完成用户管理、活动管理、奖品管理、人员管理、抽奖流程、中奖记录 6 大核心模块的全流程验证,覆盖正常 / 异常场景,用例通过率 100%,确保业务逻辑无漏洞。
  2. 自动化测试双维度落地: 基于 Selenium 实现 UI 自动化,覆盖核心页面操作流程;基于 3Python+Pytest 搭建接口自动化框架,完成 92 条接口用例验证,实现高频回归场景的自动化覆盖,大幅提升测试效率与可复用性。
  3. 性能测试针对性验证: 针对抽奖等高并发核心场景开展梯度压测,验证 200 并发下系统稳定性,确认接口响应与异常处理能力满足现场使用需求,提前规避性能瓶颈。
相关推荐
志栋智能9 小时前
超自动化巡检:解锁运维数据的深层价值
运维·服务器·数据库·自动化
zhensherlock10 小时前
Protocol Launcher 系列:Tally 快速计数器的深度集成
前端·javascript·typescript·node.js·自动化·github·js
带娃的IT创业者12 小时前
Claude Code Routines 深度解析:重新定义 AI 辅助编程的工作流自动化
运维·人工智能·自动化·ai编程·工作流·anthropic·claude code
疯狂的维修14 小时前
关于几种数据队列的解析和场景比对
自动化
专注VB编程开发20年14 小时前
工控成套控制柜厂家 / 自动化小工厂 对外市场价
运维·自动化·工控·上位机开发
数智化精益手记局17 小时前
什么是安全生产?解读安全生产的基本方针与核心要求
大数据·运维·人工智能·安全·信息可视化·自动化·精益工程
缝艺智研社17 小时前
誉财 YC - 02/18K 自动剪带拉橡筋机测评:服装生产新助力
自动化·新人首发·自动化缝纫机·线上模板机·自动剪带拉橡筋机
沫儿笙18 小时前
焊接机器人二元混合气节气装置
机器人·自动化
lifewange18 小时前
借记来账跟贷记来账在二代支付系统中分别代表什么含义?
功能测试
tiger从容淡定是人生18 小时前
Selenium与Playwright:两大Web自动化框架的深入对比
前端·selenium·测试工具·自动化·web测试·playwright·信息化战略