【校园星愿抽奖互动平台全维度测试报告:功能与自动化双轨验证】

|------------|------|-----------|---|
| 项目名称 | 抽奖 | 版本号 | / |
| 发布类型 | 分级发布 | 测试负责人 | |
| 测试完成日期 | 3.15 | 联系方式 | |

项目背景:

项目背景与意义:

• 随着互联网的发展,博客平台成为技术交流、知识分享的重要载体。CSDN作为国内知名的技术社区,为广大开发者提供了丰富的学习与交流资源。作为一名CSDN博主,我在日常写作和交流中深刻体会到一个高效、便捷、安全的博客系统对于个人成长和技术传播的重要性。因此,我以CSDN为参考,设计并开发了**"校园星愿抽奖互动平台"**项目,旨在打造一个简洁易用、功能完善的个人博客平台,便于回顾所学的知识。
• 本项目的创建不仅是对抽奖平台功能的实践和复现,更是对Web开发全流程的系统学习和能力提升。通过项目开发,我深入掌握了Java、Spring Boot、前端技术、JWT 令牌加密等关键技能,并在实际应用中强化了对安全性、用户体验、系统可维护性的理解,实现将自己所学的知识融会贯通到项目中,加深自己对技术的理解。

若有不足或改进之处,也希望大家指出☺️~

项目概述

本项目实现了一个基于前后端分离架构的校园星愿抽奖互动平台,采用 MySQL 存储用户、活动及抽奖记录数据,结合 Redis 实现防重复抽奖与幂等性控制,通过 RabbitMQ 异步处理抽奖结果通知等任务,并部署在本地开发环境中。系统前端主要由活动管理、奖品管理、人员管理等核心页面组成,后端基于 Spring Boot 构建,支持用户认证、高并发抽奖、库存扣减与消息推送等能力,整体模拟实现了一个稳定、安全的企业级抽奖互动平台。

已实现的主要功能包括:
  • 用户认证与权限控制基于 JWT 实现用户登录、身份校验与权限管控,未登录状态无法访问核心抽奖与管理接口。
  • 抽奖活动管理支持后台新增、编辑、上下线抽奖活动,配置活动时间、参与限制、奖品池与中奖规则。
  • 奖品管理与库存控制实现奖品创建、状态管理、库存扣减与防超卖逻辑,保证高并发下奖品数据一致。
  • 幂等性与防重复抽奖通过 Redis + 唯一请求 ID 实现幂等性保障,同一用户在同一活动内只能抽奖一次,防止重复请求与恶意刷奖。
  • 高并发与性能优化利用 Redis 缓存热点数据、异步消息队列(RabbitMQ)削峰,提升系统在高并发抽奖场景下的稳定性与响应速度。
  • 接口测试与兼容性验证基于 Postman 完成接口自动化测试,使用 JMeter 模拟高并发场景,确保接口层与业务层的正确性与兼容性。
当前系统存在的不足:
  • 安全防护不够全面尚未实现完整的风控与频率限制,对恶意高频请求、脚本刷奖的防御能力较弱。
  • 前端页面未完全完善前端页面框架已搭建,但部分页面(如活动统计、抽奖结果可视化、数据大屏)尚未实现动态展示与交互美化
  • 数据统计较基础后端统计仅满足基本业务需求,未做更细粒度的日活、参与率、中奖率、渠道分析等数据统计。

校园星愿抽奖互动平台 - 系统功能说明

1. 登录功能

  • 用户需输入已存在于数据库中的用户名和密码进行登录
  • 登录成功后跳转至活动管理页
  • 未登录状态下点击 "活动管理""奖品管理" 等菜单,将强制跳转至登录页

2. 注册功能

  • 未登录状态下可访问注册页面,登录状态下点击 "注册用户" 也可进入
  • 用户需输入用户名、密码、确认密码、角色(普通用户 / 管理员)等信息
  • 用户名需满足唯一性校验,密码需符合复杂度要求(如长度≥6 位、包含数字 / 字母)
  • 点击 "提交注册" 按钮后,信息验证通过则完成注册,跳转至登录页;验证失败则提示具体错误(如用户名已存在、密码不一致)
  • 注册成功后,用户信息将同步至人员管理列表

3. 活动管理页

  • 展示活动列表,包括活动名称、活动时间、参与限制、状态等信息
  • 左侧显示当前登录用户的操作菜单(活动列表、新建抽奖活动等)
  • 右上角提供核心操作按钮:
    • 新建活动:跳转至新建抽奖活动页
    • 编辑:修改当前活动配置,编辑后返回活动列表页
    • 删除:删除当前活动,删除后返回活动列表页
    • 注销:退出当前用户,返回登录页

4. 新建抽奖活动页

  • 登录状态下点击 "新建抽奖活动" 按钮进入编辑页
  • 用户可输入活动名称、活动起止时间、每人限抽次数、奖品池配置等信息
  • 点击 "保存活动" 按钮后,活动将被保存并发布,随后跳转至活动列表页

5. 奖品管理页

  • 展示奖品列表,包括奖品名称、库存、中奖概率、关联活动等信息
  • 左侧显示当前登录用户的操作菜单(奖品列表、创建奖品等)
  • 右上角提供核心操作按钮:
    • 创建奖品:跳转至创建奖品页
    • 编辑:修改当前奖品信息,编辑后返回奖品列表页
    • 删除:删除当前奖品,删除后返回奖品列表页
    • 注销:退出当前用户,返回登录页

6. 创建奖品页

  • 登录状态下点击 "创建奖品" 按钮进入编辑页
  • 用户可输入奖品名称、库存数量、中奖概率、关联活动等信息
  • 点击 "保存奖品" 按钮后,奖品将被保存,随后跳转至奖品列表页

7. 人员管理页

  • 展示人员列表,包括用户名、角色、注册时间、注册状态等信息
  • 左侧显示当前登录用户的操作菜单(人员列表、注册用户等)
  • 右上角提供核心操作按钮:
    • 注册用户:跳转至注册用户页(与独立注册功能共用页面)
    • 编辑:修改当前用户信息,编辑后返回人员列表页
    • 删除:删除当前用户,删除后返回人员列表页
    • 注销:退出当前用户,返回登录页

测试目标

  • 目标:核心业务模块(抽奖、防重、幂等性)测试覆盖率达到 95%

测试安排

测试分类:

(1)功能测试

  • 功能测试结果:测试用例 100%通过

(2)自动化测试

(1)编写Web测试用例:

配置准备:添加需要的pom.xml依赖

XML 复制代码
<dependency>
  <groupId>io.github.bonigarcia</groupId>
  <artifactId>webdrivermanager</artifactId>
  <version>5.8.0</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-java</artifactId>
  <version>4.0.0</version>
</dependency>

<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.6</version>
</dependency>
(2)页面测试
①登录页面
  • 登录页面的基本功能测试:只有账号和密码匹配才能正常登录,其他情况都登录失败。

检测页面的正常加载

编写测试脚本

java 复制代码
package com.test.tests;

import com.test.common.DriverUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;

public class LoginPage {
    String url = "http://localhost:8080/blogin.html";
    WebDriver driver = DriverUtils.createDriver(url);

    //验证元素是否正确加载
    public void pageElementsLoaded(){
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        try{

            // 验证账号
            WebElement nameInput = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("#phoneNumber")));
            assert nameInput.isDisplayed() : "活动名称输入框未显示" ;

            // 验证密码
            WebElement descInput = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("#password")));
            assert descInput.isDisplayed() : "活动描述文本域未显示";

            // 验证登录按钮
            WebElement login = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#loginForm > button")));
            assert login.isDisplayed() : "登录按钮未显示";

        }catch (Exception e){
            System.out.println("登陆页面功能显示有误");
            e.printStackTrace();
        }finally {
            System.out.println("显示正常");
            driver.quit();
        }
    }

    

}

检测成功登录

java 复制代码
public void LoginRight(){
        try {
            driver.findElement(By.cssSelector("#phoneNumber")).sendKeys("15888888885");
            driver.findElement(By.cssSelector("#password")).sendKeys("123123");
            driver.findElement(By.cssSelector("#loginForm > button")).click();

            //判断页面是否跳转是否
            String title = driver.getTitle();
            assert title.equals("后台管理") : "页面跳转错误";

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 5. 关闭浏览器
            System.out.println("登录功能没有问题");
            driver.quit();
        }

    }

检测失败登录

java 复制代码
/*
    空白账号
     */
    public void LoginfailAccount(){
        try {
            driver.findElement(By.cssSelector("#phoneNumber")).sendKeys("");
            driver.findElement(By.cssSelector("#password")).sendKeys("123123");
            driver.findElement(By.cssSelector("#loginForm > button")).click();

            //获取失败的弹窗内容,将它和预期的错误信息进行比较
            String alertText = driver.switchTo().alert().getText();
            String expectedAlertText = "用户不存在";
            assert alertText.equals(expectedAlertText);
            //接受弹窗
            driver.switchTo().alert().accept();

            //判断页面是否跳转是否
            String title = driver.getTitle();
            assert title.equals("后台管理") : "页面跳转错误";

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 5. 关闭浏览器
            System.out.println("登录功能没有问题");
            driver.quit();
        }
    }
    /*
        空白密码
    */
    public void LoginfailPassword(){
        try {
            driver.findElement(By.cssSelector("#phoneNumber")).sendKeys("15888888885");
            driver.findElement(By.cssSelector("#password")).sendKeys("");
            driver.findElement(By.cssSelector("#loginForm > button")).click();
            
            //获取失败的弹窗内容,将它和预期的错误信息进行比较
            String alertText = driver.switchTo().alert().getText();
            String expectedAlertText = "用户不存在";
            assert alertText.equals(expectedAlertText);
            //接受弹窗
            driver.switchTo().alert().accept();
            //判断页面是否跳转是否
            String title = driver.getTitle();
            assert title.equals("后台管理") : "页面跳转错误";

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 5. 关闭浏览器
            System.out.println("登录功能没有问题");
            driver.quit();
        }
    }
②列表页面测试:

成功登录检测元素是否正常加载和活动列表是否正确显示

java 复制代码
package com.test.tests;

import com.test.common.DriverUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

public class ActivityListPage {
    String url = "http://localhost:8080/blogin.html";
    private static final int WAIT_SECONDS = 10;
    WebDriver driver = DriverUtils.createDriver(url);
    /*
    此方法是为了检测登陆后是否跳转到活动列表这个页面
     */

    //验证元素是否正确加载
    public void pageElementsLoaded(){
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        try{

            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#phoneNumber")))
                    .sendKeys("15888888885");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#password")))
                    .sendKeys("123123");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#loginForm > button")))
                    .click();

            WebElement paginationIframe = wait.until(ExpectedConditions.presenceOfElementLocated(
                    By.xpath("//iframe") // 若有多个iframe,需补充id/name缩小范围,如//iframe[@id='mainFrame']
            ));
            driver.switchTo().frame(paginationIframe);

            // 验证首页按钮
            WebElement firstpage = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > div.pagination > button:nth-child(1)")));
            assert firstpage.isDisplayed() : "活动名称输入框未显示" ;

            // 验证上一页按钮
            WebElement prePage = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > div.pagination > button:nth-child(2)")));
            assert prePage.isDisplayed() : "上一页按钮未显示";

            // 验证第?页按钮
            WebElement pageShow = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#pageInput")));
            assert pageShow.isDisplayed() : "第?页输入框未显示";

            // 验证下一页按钮
            WebElement nextPage = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div > div.pagination > button:nth-child(4)")));
            assert nextPage.isDisplayed() : "下一页按钮未显示";

            // 验证尾页按钮
            WebElement lastPage = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div > div.pagination > button:nth-child(5)")));
            assert lastPage.isDisplayed() : "尾页按钮未显示";

        }catch (Exception e){
            System.out.println("登陆页面功能显示有误");
            e.printStackTrace();
        }finally {
            System.out.println("显示正常");
            driver.quit();
        }
    }

    public void ActivityListPageLoad(){

        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(WAIT_SECONDS));
        try{
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#phoneNumber")))
                    .sendKeys("15888888885");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#password")))
                    .sendKeys("123123");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#loginForm > button")))
                    .click();

            String title = driver.getTitle();
            assert title.equals("后台管理") : "登录失败,页面标题不正确!";
        }
        catch(Exception e){
            e.printStackTrace();
        }finally{
            System.out.println("活动列表页面没有问题");
            driver.quit();
        }

    }

}

不成功登录界面显示

java 复制代码
public void ListNoLogin()
{
    //处理弹窗警告
    Alert alert = driver.switchTo().alert();
    alert.accept();

    //跳转到登录页面,通过获取标题来检查是否跳转成功
    String exceptTitle = driver.getTitle();

    assert exceptTitle.equals("后台管理");

    driver.quit();
}
③新建抽奖活动页面 :
java 复制代码
package com.test.tests;

import com.test.common.DriverUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

public class NewActivityPage {
    String url = "http://localhost:8080/blogin.html";
    WebDriver driver = DriverUtils.createDriver(url);
    private final int TIME_SECOND = 10;
    private final int LONG_TIME_SECOND = 20;
    private WebDriverWait wait;
    private WebDriverWait longWait;
    private boolean isTestPass = true;

    // 构造方法初始化等待器
    public NewActivityPage() {
        wait = new WebDriverWait(driver, Duration.ofSeconds(TIME_SECOND));
        longWait = new WebDriverWait(driver, Duration.ofSeconds(LONG_TIME_SECOND));
    }

    // ========== 001 页面元素加载验证 ==========
    public void testPageElementsLoaded() {
        try {
            // 1. 登录
            login();
            // 2. 进入新建抽奖活动页面
            enterNewActivityPage();
            // 3. 切换iframe
            switchToIframe();

            // 验证页面标题
            WebElement pageTitle = longWait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.xpath("//h1[text()='创建抽奖活动']")));
            assert pageTitle.isDisplayed() : "页面标题「创建抽奖活动」未显示";

            // 验证活动名称输入框
            WebElement activityNameInput = longWait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.id("activityName")));
            assert activityNameInput.isDisplayed() && activityNameInput.isEnabled() : "活动名称输入框不可见或不可编辑";

            // 验证活动描述输入框
            WebElement activityDescInput = longWait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.id("description")));
            assert activityDescInput.isDisplayed() && activityDescInput.isEnabled() : "活动描述输入框不可见或不可编辑";

            // 验证按钮可见可点击
            WebElement selectPrizeBtn = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.xpath("//button[text()='圈选奖品']")));
            assert selectPrizeBtn.isDisplayed() && selectPrizeBtn.isEnabled() : "【圈选奖品】按钮不可见或不可点击";

            WebElement selectUserBtn = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.xpath("//button[text()='圈选人员']")));
            assert selectUserBtn.isDisplayed() && selectUserBtn.isEnabled() : "【圈选人员】按钮不可见或不可点击";

            WebElement createActivityBtn = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.xpath("//button[text()='创建活动']")));
            assert createActivityBtn.isDisplayed() && createActivityBtn.isEnabled() : "【创建活动】按钮不可见或不可点击";

            System.out.println("001 页面元素加载验证通过");
        } catch (Exception e) {
            isTestPass = false;
            System.out.println("001 页面元素加载验证失败:" + e.getMessage());
            e.printStackTrace();
        } finally {
            tearDown();
        }
    }

    // ========== 002 输入框占位符验证 ==========
    public void testInputPlaceholders() {
        try {
            login();
            enterNewActivityPage();
            switchToIframe();

            // 验证活动名称占位符
            WebElement activityNameInput = longWait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.id("activityName")));
            String namePlaceholder = activityNameInput.getAttribute("placeholder");
            assert namePlaceholder.equals("请输入活动名称") : "活动名称占位符错误,实际:" + namePlaceholder;

            // 验证活动描述占位符
            WebElement activityDescInput = longWait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.id("description")));
            String descPlaceholder = activityDescInput.getAttribute("placeholder");
            assert descPlaceholder.equals("请输入活动描述") : "活动描述占位符错误,实际:" + descPlaceholder;

            System.out.println("002 输入框占位符验证通过");
        } catch (Exception e) {
            isTestPass = false;
            System.out.println("002 输入框占位符验证失败:" + e.getMessage());
            e.printStackTrace();
        } finally {
            tearDown();
        }
    }

    // ========== 003 正常创建活动(完整数据) ==========
    public void testCreateActivityWithValidData() {
        try {
            login();
            enterNewActivityPage();
            switchToIframe();

            // 1. 输入活动名称和描述
            WebElement activityNameInput = longWait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.id("activityName")));
            activityNameInput.clear();
            activityNameInput.sendKeys("2026春季抽奖");

            WebElement activityDescInput = longWait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.id("description")));
            activityDescInput.clear();
            activityDescInput.sendKeys("回馈新老用户");

            // 2. 圈选奖品
            WebElement selectPrizeBtn = wait.until(ExpectedConditions.elementToBeClickable(
                    By.xpath("//button[text()='圈选奖品']")));
            selectPrizeBtn.click();
            // 切换到奖品弹窗iframe(如果有)
            // 这里假设弹窗内有可勾选的奖品,替换为实际选择逻辑
            wait.until(ExpectedConditions.elementToBeClickable(
                    By.xpath("//div[contains(@class,'prize-item')][1]//input"))).click();
            wait.until(ExpectedConditions.elementToBeClickable(
                    By.xpath("//button[text()='确认选择']"))).click();

            // 3. 圈选人员
            WebElement selectUserBtn = wait.until(ExpectedConditions.elementToBeClickable(
                    By.xpath("//button[text()='圈选人员']")));
            selectUserBtn.click();
            // 切换到人员弹窗iframe(如果有)
            wait.until(ExpectedConditions.elementToBeClickable(
                    By.xpath("//div[contains(@class,'user-item')][1]//input"))).click();
            wait.until(ExpectedConditions.elementToBeClickable(
                    By.xpath("//button[text()='确认选择']"))).click();

            // 4. 点击创建活动
            WebElement createActivityBtn = wait.until(ExpectedConditions.elementToBeClickable(
                    By.xpath("//button[text()='创建活动']")));
            createActivityBtn.click();

            // 5. 验证创建成功(两种场景)
            try {
                // 场景1:跳转到活动列表页
                wait.until(ExpectedConditions.titleContains("活动列表"));
                System.out.println("003 正常创建活动验证通过(跳转验证)");
            } catch (Exception e) {
                // 场景2:页面显示成功提示
                WebElement successMsg = wait.until(ExpectedConditions.visibilityOfElementLocated(
                        By.xpath("//div[contains(@class,'success-tip')]")));
                assert successMsg.getText().contains("创建成功") : "创建成功提示未显示";
                System.out.println("003 正常创建活动验证通过(提示验证)");
            }
        } catch (Exception e) {
            isTestPass = false;
            System.out.println(" 003 正常创建活动验证失败:" + e.getMessage());
            e.printStackTrace();
        } finally {
            tearDown();
        }
    }

    // ========== 辅助方法 ==========

    // 登录操作
    private void login() {
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#phoneNumber")))
                .sendKeys("15888888885");
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#password")))
                .sendKeys("123123");
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#loginForm > button")))
                .click();
        wait.until(ExpectedConditions.titleContains("活动中心")); // 等待登录后页面加载
    }

    // 进入新建抽奖活动页面
    private void enterNewActivityPage() throws InterruptedException {
        driver.switchTo().defaultContent();
        // 点击活动管理菜单(如果需要展开)
        wait.until(ExpectedConditions.elementToBeClickable(
                By.cssSelector("body > div.cont-box > div.sidebar > ul > li:nth-child(1)"))).click();
        Thread.sleep(500);
        // 点击新建抽奖活动
        wait.until(ExpectedConditions.elementToBeClickable(
                By.xpath("//a[text()='新建抽奖活动']"))).click();
        Thread.sleep(2000); // 等待页面加载
    }

    // 切换到iframe
    private void switchToIframe() {
        try {
            driver.switchTo().frame(0);
            System.out.println("已切换到frame(0)");
        } catch (Exception e) {
            System.out.println("页面无iframe,直接在主页面定位");
        }
    }

    // 清理资源
    private void tearDown() {
        if (driver != null) {
            driver.switchTo().defaultContent();
            driver.quit();
        }
        if (isTestPass) {
            System.out.println("=== 所有测试用例执行完成:全部通过 ===");
        } else {
            System.out.println("=== 所有测试用例执行完成:存在失败用例 ===");
        }
    }
}
④奖品列表
java 复制代码
package com.test.tests;

import com.test.common.DriverUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

public class PrizeListPage {
    String url = "http://localhost:8080/blogin.html";
    private static final int WAIT_SECONDS = 20;
    WebDriver driver = DriverUtils.createDriver(url);
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(WAIT_SECONDS));
    private WebElement paginationIframe;
    private boolean isTestPass = true;

    // 原有方法:页面元素加载验证(-001)
    public void pageElementsLoaded() {
        try {
            // 登录
            login();
            // 进入奖品列表页面
            enterPrizeListPage();
            // 切换iframe
            switchToIframe();

            // 验证表头
            WebElement tableTitle = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > h3")));
            assert tableTitle.getText().equals("奖品列表") : "页面标题「奖品列表」未显示";

            WebElement colId = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > table > thead > tr > th:nth-child(1)")));
            assert colId.getText().equals("奖品id") : "表头「奖品id」未显示";

            WebElement colImg = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > table > thead > tr > th:nth-child(2)")));
            assert colImg.getText().equals("奖品图") : "表头「奖品图」未显示";

            WebElement colName = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > table > thead > tr > th:nth-child(3)")));
            assert colName.getText().equals("奖品名") : "表头「奖品名」未显示";

            WebElement colDesc = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > table > thead > tr > th:nth-child(4)")));
            assert colDesc.getText().equals("奖品描述") : "表头「奖品描述」未显示";

            WebElement colValue = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > table > thead > tr > th:nth-child(5)")));
            assert colValue.getText().equals("奖品价值") : "表头「奖品价值」未显示";

            // 验证分页按钮
            WebElement firstpage = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > div.pagination > button:nth-child(1)")));
            assert firstpage.isDisplayed() && firstpage.isEnabled() : "首页按钮不可见或不可操作";

            WebElement prePage = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > div.pagination > button:nth-child(2)")));
            assert prePage.isDisplayed() && prePage.isEnabled() : "上一页按钮不可见或不可操作";

            WebElement pageShow = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#pageInput")));
            assert pageShow.isDisplayed() && pageShow.isEnabled() : "页码输入框不可见或不可操作";

            WebElement nextPage = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > div.pagination > button:nth-child(4)")));
            assert nextPage.isDisplayed() && nextPage.isEnabled() : "下一页按钮不可见或不可操作";

            WebElement lastPage = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > div.pagination > button:nth-child(5)")));
            assert lastPage.isDisplayed() && lastPage.isEnabled() : "尾页按钮不可见或不可操作";

        } catch (Exception e) {
            isTestPass = false;
            System.out.println("页面元素加载验证失败");
            e.printStackTrace();
        } finally {
            switchToDefaultContent();
            printResult();
            driver.quit();
        }
    }

    // -002 无数据时列表展示
    public void testEmptyDataList() {
        try {
            login();
            enterPrizeListPage();
            switchToIframe();

            // 验证列表区域为空
            WebElement tableBody = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > table > tbody")));
            assert tableBody.findElements(By.tagName("tr")).isEmpty() : "列表区域不为空";

            // 验证分页状态
            WebElement pageInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#pageInput")));
            assert pageInput.getAttribute("value").equals("1") : "分页栏未显示「第1页」";

            WebElement prePage = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > div.pagination > button:nth-child(2)")));
            assert !prePage.isEnabled() : "无数据时上一页按钮应置灰不可点击";

            WebElement nextPage = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > div.pagination > button:nth-child(4)")));
            assert !nextPage.isEnabled() : "无数据时下一页按钮应置灰不可点击";

        } catch (Exception e) {
            isTestPass = false;
            System.out.println("无数据时列表展示验证失败");
            e.printStackTrace();
        } finally {
            switchToDefaultContent();
            printResult();
            driver.quit();
        }
    }

    // -003 分页功能 - 首页
    public void testPaginationFirstPage() {
        try {
            login();
            enterPrizeListPage();
            switchToIframe();

            // 先跳转到第2页(确保有多页数据)
            WebElement nextPageBtn = wait.until(ExpectedConditions.elementToBeClickable(
                    By.cssSelector("body > div > div.pagination > button:nth-child(4)")));
            nextPageBtn.click();
            Thread.sleep(1000);

            // 点击首页按钮
            WebElement firstPageBtn = wait.until(ExpectedConditions.elementToBeClickable(
                    By.cssSelector("body > div > div.pagination > button:nth-child(1)")));
            firstPageBtn.click();
            Thread.sleep(1000);

            // 验证跳转到第1页
            WebElement pageInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#pageInput")));
            assert pageInput.getAttribute("value").equals("1") : "点击首页后未跳转到第1页";

        } catch (Exception e) {
            isTestPass = false;
            System.out.println("分页功能-首页验证失败");
            e.printStackTrace();
        } finally {
            switchToDefaultContent();
            printResult();
            driver.quit();
        }
    }

    // -004 分页功能 - 下一页
    public void testPaginationNextPage() {
        try {
            login();
            enterPrizeListPage();
            switchToIframe();

            // 记录当前页码(默认第1页)
            WebElement pageInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#pageInput")));
            String currentPage = pageInput.getAttribute("value");
            assert currentPage.equals("1") : "初始页面不是第1页";

            // 点击下一页
            WebElement nextPageBtn = wait.until(ExpectedConditions.elementToBeClickable(
                    By.cssSelector("body > div > div.pagination > button:nth-child(4)")));
            nextPageBtn.click();
            Thread.sleep(1000);

            // 验证跳转到第2页
            pageInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#pageInput")));
            assert pageInput.getAttribute("value").equals("2") : "点击下一页后未跳转到第2页";

            // 验证列表加载第2页数据
            WebElement tableBody = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector("body > div > table > tbody")));
            assert !tableBody.findElements(By.tagName("tr")).isEmpty() : "第2页数据未加载";

        } catch (Exception e) {
            isTestPass = false;
            System.out.println("分页功能-下一页验证失败");
            e.printStackTrace();
        } finally {
            switchToDefaultContent();
            printResult();
            driver.quit();
        }
    }

    // ========== 辅助方法 ==========
    private void login() throws InterruptedException {
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#phoneNumber")))
                .sendKeys("15888888885");
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#password")))
                .sendKeys("123123");
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#loginForm > button")))
                .click();
        Thread.sleep(1000);
    }

    private void enterPrizeListPage() throws InterruptedException {
        WebElement prizeMenu = wait.until(ExpectedConditions.elementToBeClickable(
                By.cssSelector("body > div.cont-box > div.sidebar > ul > li:nth-child(2)")));
        prizeMenu.click();
        Thread.sleep(500);

        WebElement prizeListLink = wait.until(ExpectedConditions.elementToBeClickable(
                By.cssSelector("body > div.cont-box > div.sidebar > ul > li:nth-child(2) > ul > li:nth-child(1) > a")));
        prizeListLink.click();
        Thread.sleep(2000);
    }

    private void switchToIframe() {
        paginationIframe = wait.until(ExpectedConditions.presenceOfElementLocated(
                By.xpath("//iframe[@id='contentFrame']") // 建议替换为实际iframe ID
        ));
        driver.switchTo().frame(paginationIframe);
    }

    private void switchToDefaultContent() {
        if (paginationIframe != null) {
            try {
                driver.switchTo().defaultContent();
            } catch (Exception e) {
                System.out.println("切换回主文档失败:" + e.getMessage());
            }
        }
    }

    private void printResult() {
        if (isTestPass) {
            System.out.println("测试通过");
        } else {
            System.out.println("测试失败");
        }
    }
}
java 复制代码
public void testPaginationFunction() {
        try {
            // 1. 登录操作
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#phoneNumber")))
                    .sendKeys("15888888885");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#password")))
                    .sendKeys("123123");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#loginForm > button")))
                    .click();

            // 2. 进入奖品列表页面
            wait.until(ExpectedConditions.elementToBeClickable(
                    By.cssSelector("body > div.cont-box > div.sidebar > ul > li:nth-child(2) > ul > li:nth-child(1) > a")))
                    .click();

            // 3. 切换到分页所在的iframe
            WebElement paginationIframe = wait.until(ExpectedConditions.presenceOfElementLocated(
                    By.xpath("//iframe") // 若有多个iframe,需补充id/name,如//iframe[@id='mainFrame']
            ));
            driver.switchTo().frame(paginationIframe);

            // 4. 测试【首页】按钮
            WebElement firstPageBtn = wait.until(ExpectedConditions.elementToBeClickable(
                    By.cssSelector("body > div > div.pagination > button:nth-child(1)")));
            firstPageBtn.click();
            WebElement currentPageInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#pageInput")));
            assert currentPageInput.getAttribute("value").equals("1") : "点击首页后,当前页不是第1页";

            // 5. 测试【下一页】按钮
            WebElement nextPageBtn = wait.until(ExpectedConditions.elementToBeClickable(
                    By.cssSelector("body > div > div.pagination > button:nth-child(4)")));
            nextPageBtn.click();
            currentPageInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#pageInput")));
            assert currentPageInput.getAttribute("value").equals("2") : "点击下一页后,当前页不是第2页";

            // 6. 测试【上一页】按钮
            WebElement prePageBtn = wait.until(ExpectedConditions.elementToBeClickable(
                    By.cssSelector("body > div > div.pagination > button:nth-child(2)")));
            prePageBtn.click();
            currentPageInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#pageInput")));
            assert currentPageInput.getAttribute("value").equals("1") : "点击上一页后,当前页不是第1页";

            // 7. 测试【尾页】按钮
            WebElement lastPageBtn = wait.until(ExpectedConditions.elementToBeClickable(
                    By.cssSelector("body > div > div.pagination > button:nth-child(5)")));
            lastPageBtn.click();
           
            currentPageInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#pageInput")));
            assert !currentPageInput.getAttribute("value").equals("1") : "点击尾页后,当前页仍为第1页,尾页功能异常";

            // 8. 测试指定页码跳转
            currentPageInput.clear();
            currentPageInput.sendKeys("1");
            currentPageInput.submit(); // 或点击跳转按钮,若有单独跳转按钮需替换为点击操作
            currentPageInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#pageInput")));
            assert currentPageInput.getAttribute("value").equals("1") : "指定页码跳转失败";

        } catch (Exception e) {
            System.out.println("奖品列表翻页功能测试异常");
            e.printStackTrace();
        } finally {
            System.out.println("翻页功能测试完成");
            driver.quit();
        }
    }
⑤创建奖品页面
java 复制代码
/**
     * PRIZE-001:正常创建奖品(合法数据)
     */
    public void testCreatePrizeWithValidData() {
        boolean isSuccess = false;
        try {
            // 前置操作:登录+进入创建奖品页面+切换iframe
            login();
            enterCreatePrizePage();
            switchToPrizeIframe();

            // 清空输入框
            clearAllInputs();

            // 输入合法数据
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#prizeName")))
                    .sendKeys("iPhone 16");
            // 上传图片(替换为你的本地图片路径)
            wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#prizeImageUrl")))
                    .sendKeys("C:\\test\\iphone16.png");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#price")))
                    .sendKeys("5999");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#description")))
                    .sendKeys("最新款苹果手机");

            // 点击创建按钮
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#createPrizeBtn")))
                    .click();

            // 验证创建成功(两种场景适配)
            try {
                // 场景1:跳转到奖品列表页
                wait.until(ExpectedConditions.titleContains("奖品列表"));
                isSuccess = true;
            } catch (Exception e) {
                // 场景2:页面显示成功提示
                WebElement successMsg = wait.until(ExpectedConditions.visibilityOfElementLocated(
                        By.cssSelector(".success-tip")));
                isSuccess = successMsg.isDisplayed() && successMsg.getText().contains("创建成功");
            }

            if (isSuccess) {
                System.out.println(" 正常创建奖品测试通过");
            } else {
                throw new RuntimeException("创建奖品成功验证失败");
            }

        } catch (Exception e) {
            System.out.println(" 正常创建奖品测试失败:" + e.getMessage());
            e.printStackTrace();
        } finally {
            switchToDefaultContent();
            driver.quit();
        }
    }

    /**
     * PRIZE-002:奖品名称为空
     */
    public void testCreatePrizeWithEmptyName() {
        try {
            login();
            enterCreatePrizePage();
            switchToPrizeIframe();
            clearAllInputs();

            // 名称为空,其他字段正常
            wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#prizeImageUrl")))
                    .sendKeys("C:\\test\\iphone16.png");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#price")))
                    .sendKeys("5999");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#description")))
                    .sendKeys("最新款苹果手机");

            // 点击创建按钮
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#createPrizeBtn")))
                    .click();

            // 验证错误提示
            WebElement errorMsg = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector(".error-tip")));
            assert errorMsg.getText().contains("请输入奖品名称") : "奖品名称为空提示错误";
            System.out.println(" 奖品名称为空测试通过");

        } catch (Exception e) {
            System.out.println(" 奖品名称为空测试失败:" + e.getMessage());
            e.printStackTrace();
        } finally {
            switchToDefaultContent();
            driver.quit();
        }
    }

    /**
     * PRIZE-004:奖品价格为空
     */
    public void testCreatePrizeWithEmptyPrice() {
        try {
            login();
            enterCreatePrizePage();
            switchToPrizeIframe();
            clearAllInputs();

            // 价格为空,其他字段正常
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#prizeName")))
                    .sendKeys("iPhone 16");
            wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#prizeImageUrl")))
                    .sendKeys("C:\\test\\iphone16.png");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#description")))
                    .sendKeys("最新款苹果手机");

            // 点击创建按钮
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#createPrizeBtn")))
                    .click();

            // 验证错误提示
            WebElement errorMsg = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector(".error-tip")));
            assert errorMsg.getText().contains("请输入奖品价格") : "奖品价格为空提示错误";
            System.out.println(" 奖品价格为空测试通过");

        } catch (Exception e) {
            System.out.println(" 奖品价格为空测试失败:" + e.getMessage());
            e.printStackTrace();
        } finally {
            switchToDefaultContent();
            driver.quit();
        }
    }

    /**
     * PRIZE-005:奖品价格为非数字
     */
    public void testCreatePrizeWithNonNumericPrice() {
        try {
            login();
            enterCreatePrizePage();
            switchToPrizeIframe();
            clearAllInputs();

            // 价格为非数字,其他字段正常
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#prizeName")))
                    .sendKeys("iPhone 16");
            wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#prizeImageUrl")))
                    .sendKeys("C:\\test\\iphone16.png");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#price")))
                    .sendKeys("abc"); // 非数字价格
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#description")))
                    .sendKeys("最新款苹果手机");

            // 点击创建按钮
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#createPrizeBtn")))
                    .click();

            // 验证错误提示
            WebElement errorMsg = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector(".error-tip")));
            assert errorMsg.getText().contains("数字") || errorMsg.getText().contains("有效的价格") : "价格非数字提示错误";
            System.out.println(" 奖品价格为非数字测试通过");

        } catch (Exception e) {
            System.out.println(" 奖品价格为非数字测试失败:" + e.getMessage());
            e.printStackTrace();
        } finally {
            switchToDefaultContent();
            driver.quit();
        }
    }

    /**
     * PRIZE-008:所有字段为空
     */
    public void testCreatePrizeWithAllEmptyFields() {
        try {
            login();
            enterCreatePrizePage();
            switchToPrizeIframe();
            clearAllInputs();

            // 所有字段为空,直接点击创建
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#createPrizeBtn")))
                    .click();

            // 验证错误提示
            WebElement errorMsg = wait.until(ExpectedConditions.visibilityOfElementLocated(
                    By.cssSelector(".error-tip")));
            assert errorMsg.getText().contains("请输入") || errorMsg.getText().contains("必填") : "所有字段为空无提示";
            System.out.println(" 所有字段为空测试通过");

        } catch (Exception e) {
            System.out.println(" 所有字段为空测试失败:" + e.getMessage());
            e.printStackTrace();
        } finally {
            switchToDefaultContent();
            driver.quit();
        }
    }

    // ========== 新增辅助方法(复用逻辑,减少冗余) ==========

    /**
     * 登录操作(提取为独立方法,方便复用)
     */
    private void login() throws InterruptedException {
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#phoneNumber")))
                .sendKeys("15888888885");
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#password")))
                .sendKeys("123123");
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#loginForm > button")))
                .click();
    }

    /**
     * 进入创建奖品页面(提取为独立方法)
     */
    private void enterCreatePrizePage() throws InterruptedException {
        WebElement prizeMenu = wait.until(ExpectedConditions.elementToBeClickable(
                By.cssSelector("body > div.cont-box > div.sidebar > ul > li:nth-child(2)")));
        prizeMenu.click();
        Thread.sleep(500);

        WebElement createPrizeLink = wait.until(ExpectedConditions.elementToBeClickable(
                By.cssSelector("body > div.cont-box > div.sidebar > ul > li:nth-child(2) > ul > li:nth-child(2) > a")));
        createPrizeLink.click();
        Thread.sleep(2000);
    }

    /**
     * 切换到奖品页面的iframe
     */
    private void switchToPrizeIframe() {
        paginationIframe = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("contentFrame")));
        driver.switchTo().frame(paginationIframe);
    }

    /**
     * 切回主文档
     */
    private void switchToDefaultContent() {
        if (paginationIframe != null) {
            try {
                driver.switchTo().defaultContent();
            } catch (Exception e) {
                System.out.println("切换回主文档失败:" + e.getMessage());
            }
        }
    }

    /**
     * 清空所有输入框
     */
    private void clearAllInputs() {
        try {
            WebElement prizeNameInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#prizeName")));
            prizeNameInput.clear();

            WebElement priceInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#price")));
            priceInput.clear();

            WebElement descInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#description")));
            descInput.clear();
        } catch (Exception e) {
            System.out.println("清空输入框失败:" + e.getMessage());
        }
    }
⑥注册用户页面
java 复制代码
/**
     * 001 正常注册(合法数据)
     */
    private void testNormalRegister() {
        try {
            System.out.println("=== 执行用例001:正常注册(合法数据) ===");
            clearAllInputs();

            // 输入合法数据
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#name")))
                    .sendKeys("张三");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#email")))
                    .sendKeys("zhangsan@test.com");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#phone")))
                    .sendKeys("15888888888");

            // 点击注册按钮
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#registerBtn")))
                    .click();

            // 验证注册成功(页面跳转或提示)
            wait.until(ExpectedConditions.or(
                    ExpectedConditions.titleContains("人员列表"),
                    ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".success-tip"))
            ));
            System.out.println("用例001执行通过");
        } catch (Exception e) {
            isTestPass = false;
            System.out.println("用例001执行失败:" + e.getMessage());
        }
    }

    /**
     * 002 姓名为空
     */
    private void testNameEmpty() {
        try {
            System.out.println("=== 执行用例002:姓名为空 ===");
            clearAllInputs();

            // 姓名留空,只输入邮箱和手机号
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#email")))
                    .sendKeys("zhangsan@test.com");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#phone")))
                    .sendKeys("15888888888");

            // 点击注册按钮
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#registerBtn")))
                    .click();

            // 验证错误提示
            WebElement errorMsg = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".error-tip")));
            assert errorMsg.getText().contains("请输入姓名") : "姓名为空时未提示正确错误信息";
            assert driver.getCurrentUrl().contains("register") : "页面不应跳转";
            System.out.println("用例002执行通过");
        } catch (Exception e) {
            isTestPass = false;
            System.out.println("用例002执行失败:" + e.getMessage());
        }
    }

    /**
     * 003 邮箱格式错误
     */
    private void testEmailFormatError() {
        try {
            System.out.println("=== 执行用例003:邮箱格式错误 ===");
            clearAllInputs();

            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#name")))
                    .sendKeys("张三");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#email")))
                    .sendKeys("zhangsan"); // 错误邮箱格式
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#phone")))
                    .sendKeys("15888888888");

            // 点击注册按钮
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#registerBtn")))
                    .click();

            // 验证错误提示
            WebElement errorMsg = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".error-tip")));
            assert errorMsg.getText().contains("有效的邮箱地址") : "邮箱格式错误提示不正确";
            System.out.println("用例003执行通过");
        } catch (Exception e) {
            isTestPass = false;
            System.out.println("用例003执行失败:" + e.getMessage());
        }
    }

    /**
     * 004 手机号格式错误(位数不足)
     */
    private void testPhoneLengthError() {
        try {
            System.out.println("=== 执行用例004:手机号格式错误(位数不足) ===");
            clearAllInputs();

            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#name")))
                    .sendKeys("张三");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#email")))
                    .sendKeys("zhangsan@test.com");
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#phone")))
                    .sendKeys("158888"); // 仅6位,位数不足

            // 点击注册按钮
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#registerBtn")))
                    .click();

            // 验证错误提示
            WebElement errorMsg = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".error-tip")));
            assert errorMsg.getText().contains("有效的11位手机号") : "手机号位数错误提示不正确";
            System.out.println("用例004执行通过");
        } catch (Exception e) {
            isTestPass = false;
            System.out.println("用例004执行失败:" + e.getMessage());
        }
    }

    /**
     * 清空所有输入框(辅助方法)
     */
    private void clearAllInputs() {
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#name"))).clear();
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#email"))).clear();
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#phone"))).clear();
    }
}

(3)性能测试

①登录页面

    

②列表页面测试:

    

③新建抽奖活动页面 :

    

④奖品列表

    

⑤创建奖品页面

    

⑥人员列表页面
⑦注册用户页面

性能测试结果

测试结论

  • 系统在 1000 并发请求下整体稳定,无异常请求,核心查询接口性能优异,满足高并发场景下的基础性能要求。
  • 写入类接口(创建活动、创建奖品)响应时间偏长,存在优化空间。
相关推荐
乘云数字DATABUFF3 天前
5分钟部署开源APM Databuff:OpenTelemetry全链路追踪入门实战
运维·后端
荣--5 天前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森5 天前
动手实战学 Docker — 从零到集群编排完全指南
运维
Avan_菜菜6 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
SelectDB7 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode8 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220709 天前
如何搭建本地yum源(上)
运维
大树8812 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠12 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质12 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务