基于智慧一考通Web平台的测试报告

这里是阿川的博客,祝您变得更强 ✨ 个人主页:在线OJ的阿川

💖文章专栏:项目专栏


写在开头

现在您看到的是我的结论或想法但在这背后凝结了大量的思考、经验和讨论


目录

  • 1.项目概述
    • [1.1 项目背景](#1.1 项目背景)
    • [1.2 测试目标](#1.2 测试目标)
    • [1.3 测试范围](#1.3 测试范围)
  • 2.测试计划
    • [2.1 测试时间与人员](#2.1 测试时间与人员)
    • [2.2 测试环境与工具](#2.2 测试环境与工具)
    • [2.3 测试类型与方法](#2.3 测试类型与方法)
    • [2.4 自动化测试策略](#2.4 自动化测试策略)
      • [2.4.1 框架选型与理由](#2.4.1 框架选型与理由)
      • [2.4.2 自动化测试结构](#2.4.2 自动化测试结构)
      • [2.4.3 自动化覆盖范围与优先级](#2.4.3 自动化覆盖范围与优先级)
      • [2.4.4 自动化代码](#2.4.4 自动化代码)
        • [2.4.4.1 项目依赖配置(requirements.txt)](#2.4.4.1 项目依赖配置(requirements.txt))
        • [2.4.4.2 驱动封装(common/Utils.py)](#2.4.4.2 驱动封装(common/Utils.py))
        • [2.4.4.3 登录页面自动化测试(LoginTest.py)](#2.4.4.3 登录页面自动化测试(LoginTest.py))
        • [2.4.4.4 注册页面自动化测试(RegisterTest.py)](#2.4.4.4 注册页面自动化测试(RegisterTest.py))
        • [2.4.4.5 首页功能自动化测试(HomeTest.py)](#2.4.4.5 首页功能自动化测试(HomeTest.py))
  • 3.测试执行与结果
    • [3.1 功能测试](#3.1 功能测试)
      • [3.1.1 注册模块测试记录](#3.1.1 注册模块测试记录)
      • [3.1.2 登录模块测试记录](#3.1.2 登录模块测试记录)
      • [3.1.3 首页测试记录](#3.1.3 首页测试记录)
      • [3.1.4 我的项目测试记录](#3.1.4 我的项目测试记录)
      • [3.1.5 题库中心测试记录](#3.1.5 题库中心测试记录)
      • [3.1.6 模板广场测试记录](#3.1.6 模板广场测试记录)
      • [3.1.7 自动化测试执行结果](#3.1.7 自动化测试执行结果)
    • [3.2 界面测试](#3.2 界面测试)
      • [3.2.1 测试方法](#3.2.1 测试方法)
      • [3.2.2 检查清单与结果](#3.2.2 检查清单与结果)
    • [3.3 兼容性测试](#3.3 兼容性测试)
      • [3.3.1 测试方法](#3.3.1 测试方法)
      • [3.3.2 测试环境](#3.3.2 测试环境)
      • [3.3.3 测试结果](#3.3.3 测试结果)
    • [3.4 性能测试](#3.4 性能测试)
      • [3.4.1 测试方案](#3.4.1 测试方案)
      • [3.4.2 测试结果](#3.4.2 测试结果)
      • [3.4.3 各接口响应时间对比(200 并发)](#3.4.3 各接口响应时间对比(200 并发))
      • [3.4.4 关键结论](#3.4.4 关键结论)
  • 4.测试中发现的主要问题
  • 5.测试结论与建议
    • [5.1 测试结论](#5.1 测试结论)
      • [5.1.1 测试数据汇总](#5.1.1 测试数据汇总)
      • [5.1.2 综合评估](#5.1.2 综合评估)
    • [5.2 改进建议](#5.2 改进建议)
      • [5.2.1 功能层面](#5.2.1 功能层面)
      • [5.2.2 流程层面](#5.2.2 流程层面)
  • 6.困难与解决办法
    • [6.1 困难](#6.1 困难)
    • [6.2 解决方案](#6.2 解决方案)

1.项目概述

1.1 项目背景

写这个测试报告是因为学习了相应的测试知识,然后要进行学以致用,纸上得来终觉浅,得知此事要躬行,所以在开源社区上找了一个智慧一考通Web系统,进行全面的测试,并书写测试报告

部署运行后,系统登录页标题显示为"卷王问卷考试系统",本文的测试对象与全部用例均围绕该系统展开。

1.2 测试目标

总体目标: 验证卷王问卷考试系统核心功能的完整性------覆盖主页、我的项目、题库中心、模板广场等核心模块,检查各模块功能实现与页面布局是否符合要求,并在此基础上开展多维度的质量验证。

对问卷调查系统进行多维度质量验证,包括:

  • 功能测试:验证登录功能、用户注册功能、首页、我的项目、题库中心、模板广场等核心模块是否符合要求;

  • 界面测试: 页面元素是否正确显示、无错别字、无遮挡、无裂图等异常情况;

  • 兼容性测试:Chrome、Edge等浏览器平台功能和布局是否一致

  • 性能测试:探索一定规模的并发用户下平均响应时间及错误率等简单的性能测试

1.3 测试范围

模块 测试内容 测试类型
用户注册 正常注册流程、必填项校验、重复账号拦截、密码一致性校验、密码长度边界值 功能测试
用户登录 正常登录、账号/密码为空校验、错误凭证拦截、未登录访问拦截 功能测试
首页 创建问卷/考试跳转、保存功能、设置面板弹出、暗色主题切换、退出登录 功能测试 + 界面测试
我的项目 搜索、新建问卷、回收站、删除、彻底删除、项目设置页跳转、问卷发布与作答 功能测试
我的题库 题库查询、重置、新建、试题管理、文本导入、模板导入 功能测试
模板广场 添加模板、保存、搜索、预览、公共库/私有库切换 功能测试
全部页面 图片加载、文字准确性、元素对齐、提示信息、按钮状态 界面测试
3 种浏览器 Chrome / Edge / 手机端浏览器 兼容性测试
10 个核心接口 并发压测 50/100/200 用户 性能测试

2.测试计划

2.1 测试时间与人员

阶段 时间 工作内容 产出物
测试分析与用例设计 第 1-2 天 梳理业务流程并编写测试用例矩阵 测试用例文档
手动功能测试 第 3-4 天 逐条执行测试用例,记录实际结果,提交缺陷 测试执行记录、缺陷截图
自动化脚本编写与执行 第 5-6 天 搭建 Selenium 项目,编写 3 个测试类 19 个测试方法 自动化测试代码
性能测试 第 7 天 JMeter 并发压测 性能测试报告
测试报告编写 第 8 天-9天 汇总数据,编写测试报告 测试报告文档

测试人员: 1人(独立完成全部测试)

2.2 测试环境与工具

类别 工具名称 版本 用途
硬件 七彩虹将星 X15AT23 测试运行环境
操作系统 Windows 11 专业版 25H2 测试运行环境
手动测试浏览器 Microsoft Edge 122.0.2365.106 手动功能测试
自动化测试浏览器 Google Chrome 150.0.7871.129 Selenium 自动化测试
开发工具 Pycharm 2026.1 编写自动化测试代码
自动化工具 Selenium 4.44.0 界面自动化测试
编程语言 Python 3.12 自动化测试脚本语言
接口测试工具 Postman --- 接口验证
抓包工具 Fiddler Everywhere --- 接口抓包分析
性能测试工具 Apache JMeter 5.5 并发压测
截图工具 系统截图 + Selenium 截图 缺陷证据收集

2.3 测试类型与方法

测试类型 覆盖模块 采用方法 用例数
功能测试 6 个核心模块 等价类划分、边界值分析、场景法、错误推测法 40 条手工 + 19 条自动化
界面测试 全部页面 检查清单法 10 项检查点
兼容性测试 3 种浏览器 多浏览器对比法 3 组对比
性能测试 10 个核心接口 负载测试 3 个压力梯度

2.4 自动化测试策略

2.4.1 框架选型与理由

选型项 选择 理由
自动化工具 Selenium WebDriver 开源免费,适合 Web 应用 UI 测试
编程语言 Python 测试生态成熟,开发效率高
驱动管理 Selenium Manager(Selenium 4.6+ 内置) 自动下载匹配版本的 ChromeDriver,免去手动管理驱动的麻烦
设计模式 全局单例(BlogDriver) 全局只创建一个浏览器实例,各测试类复用,避免重复启动浏览器

2.4.2 自动化测试结构

复制代码
survey-exam-test/
├── requirements.txt                # 项目依赖(selenium 4.44.0)
├── common/
│   └── Utils.py                    # Driver 封装:反检测配置 + 截图
├── LoginTest.py                    # my_Login:登录页测试(8个方法)
├── RegisterTest.py                 # my_Register:注册页测试(9个方法)
├── HomeTest.py                     # my_Home:首页测试(2个方法)
└── images/                         # 截图输出目录
    └── yyyy-MM-dd/                 # 按日期分目录

2.4.3 自动化覆盖范围与优先级

优先级 模块 覆盖理由 方法数
P0 登录 每次测试都需要登录,自动化后可复用 8
P0 注册 用户进入系统的第一步,核心入口 9
P1 首页 核心操作入口,验证页面元素和未登录拦截 2

2.4.4 自动化代码

2.4.4.1 项目依赖配置(requirements.txt)

项目使用 Python 3.12 + Selenium 4.44.0。Selenium 4.6+ 内置 Selenium Manager,运行时会自动下载与本地 Chrome 版本匹配的 ChromeDriver,无需手动安装驱动:

text 复制代码
# requirements.txt
selenium==4.44.0

安装命令:

bash 复制代码
pip install -r requirements.txt
2.4.4.2 驱动封装(common/Utils.py)

把浏览器启动、反检测配置、隐式等待、最大化窗口与截图等通用操作封装在 Driver 类中,并实例化全局唯一的 BlogDriver 对象,各测试类直接复用,避免重复创建浏览器实例:

python 复制代码
# common/Utils.py
import datetime
import os.path
import sys

from selenium import webdriver
from selenium.webdriver.chrome.options import Options


class Driver:
    driver = ""

    def __init__(self):
        # 躲避浏览器对自动化工具的检查(初级)
        chrome_options = Options()
        chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
        chrome_options.add_experimental_option("useAutomationExtension", False)
        chrome_options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36')
        # 创建浏览器对象
        self.driver = webdriver.Chrome(options=chrome_options)
        # 设置隐性等待
        self.driver.implicitly_wait(5)
        # 终极反检测:抹除 navigator.webdriver 属性
        self.driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
            "source": """
                Object.defineProperty(navigator, 'webdriver', {
                    get: () => undefined
                });
            """
        })
        # 最大化窗口
        self.driver.maximize_window()

    # 截图接口
    def getScreenShot(self):
        dirname = datetime.datetime.now().strftime('%Y-%m-%d')
        os.makedirs("../images/" + dirname, exist_ok=True)
        filename = sys._getframe().f_back.f_code.co_name + "-" + datetime.datetime.now().strftime('%Y-%m-%d-%H%M%S') + ".png"
        self.driver.save_screenshot(f'../images/{dirname}/' + filename)


BlogDriver = Driver()
2.4.4.3 登录页面自动化测试(LoginTest.py

覆盖 8 个测试场景:页面元素加载、正常登录、密码错误、账号错误、账号密码均错误、账号为空、密码为空、账号密码均为空。

python 复制代码
# LoginTest.py
from selenium.webdriver.common.by import By

from common.Utils import BlogDriver


class my_Login:
    url = ""
    driver = ""

    def __init__(self):
        self.url = "http://49.235.61.184:8080/user/login?redirect=%2Fhome"
        self.driver = BlogDriver.driver
        self.driver.get(self.url)

    # 检测页面按键加载是否完整
    def Login_completion(self):
        # 测试用户名输入框是否加载完整
        self.driver.find_element(By.CSS_SELECTOR, "#username")
        # 测试密码输入框是否加载完整
        self.driver.find_element(By.CSS_SELECTOR, "#password")
        # 测试登录按钮是否加载完整
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button")
        # 添加屏幕截图
        BlogDriver.getScreenShot()
        print("一切正常")

    # 登录成功
    def LoginSuc(self):
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("testuser01")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button").click()

    # 登录失败1:密码错误
    def LoginFail1(self):
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("testuser01")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456666")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button").click()

    # 登录失败2:账号错误
    def LoginFail2(self):
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("testuser01666")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button").click()

    # 登录失败3:账号和密码都错误
    def LoginFail3(self):
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("testuser01666")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456666")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button").click()

    # 登录失败4:账号为空
    def LoginFail4(self):
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button").click()

    # 登录失败5:密码为空
    def LoginFail5(self):
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("testuser01")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button").click()

    # 登录失败6:账号和密码都为空
    def LoginFail6(self):
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button").click()
2.4.4.4 注册页面自动化测试(RegisterTest.py

覆盖 9 个测试场景:页面元素加载、正常注册、账号已存在、密码不符合要求、两次密码不一致、未输入用户名、未输入账号、未输入密码、未输入确认密码。

python 复制代码
# RegisterTest.py
from selenium.webdriver.common.by import By

from common.Utils import BlogDriver


class my_Register:
    url = ""
    driver = ""

    def __init__(self):
        self.url = "http://49.235.61.184:8080/user/register"
        self.driver = BlogDriver.driver
        self.driver.get(self.url)

    # 检测页面按键加载是否完整
    def Register_completion(self):
        # 测试姓名输入框是否加载完整
        self.driver.find_element(By.CSS_SELECTOR, "#name")
        # 测试账号输入框是否加载完整
        self.driver.find_element(By.CSS_SELECTOR, "#username")
        # 测试密码输入框是否加载完整
        self.driver.find_element(By.CSS_SELECTOR, "#password")
        # 测试重复输入密码输入框是否加载完整
        self.driver.find_element(By.CSS_SELECTOR, "#rePassword")
        # 测试注册按钮是否加载完整
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button")
        # 添加屏幕截图
        BlogDriver.getScreenShot()
        print("一切正常")

    # 注册成功
    def RegisterSuc(self):
        self.driver.find_element(By.CSS_SELECTOR, "#name").send_keys("testuser")
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("testuser01")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#rePassword").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button").click()

    # 注册失败,账号已存在
    def RegisterFail1(self):
        self.driver.find_element(By.CSS_SELECTOR, "#name").send_keys("testuser")
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("testuser01")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#rePassword").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button").click()

    # 注册失败,密码不符合要求
    def RegisterFail2(self):
        self.driver.find_element(By.CSS_SELECTOR, "#name").send_keys("testuser2")
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("testuser02")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("12345")
        self.driver.find_element(By.CSS_SELECTOR, "#rePassword").send_keys("12345")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button").click()

    # 注册失败,两次输入密码不一致
    def RegisterFail3(self):
        self.driver.find_element(By.CSS_SELECTOR, "#name").send_keys("testuser3")
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("testuser03")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#rePassword").send_keys("1234567")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button").click()

    # 注册失败,未输入用户名
    def RegisterFail4(self):
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("testuser04")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#rePassword").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button").click()

    # 注册失败,未输入账号
    def RegisterFail5(self):
        self.driver.find_element(By.CSS_SELECTOR, "#name").send_keys("testuser2")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#rePassword").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button").click()

    # 注册失败,未输入密码
    def RegisterFail6(self):
        self.driver.find_element(By.CSS_SELECTOR, "#name").send_keys("testuser2")
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("testuser04")
        self.driver.find_element(By.CSS_SELECTOR, "#rePassword").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button").click()

    # 注册失败,未重复输入密码
    def RegisterFail7(self):
        self.driver.find_element(By.CSS_SELECTOR, "#name").send_keys("testuser2")
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("testuser04")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button").click()
2.4.4.5 首页功能自动化测试(HomeTest.py

覆盖 2 个测试场景:未登录访问拦截、首页核心元素验证。

python 复制代码
# HomeTest.py
from selenium.webdriver.common.by import By

from common.Utils import BlogDriver


class my_Home:
    url = ""
    driver = ""

    def __init__(self):
        self.url = "http://49.235.61.184:8080/home"
        self.driver = BlogDriver.driver
        self.driver.get(self.url)

    # 测试未登录状态下直接进入主页是否会转到登录页面
    def noLogin(self):
        str = self.driver.title
        assert str == "卷王问卷考试系统"

    # 测试登录后的主页是否加载完整
    def Home_completion(self):
        # 登录
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("testuser01")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button").click()
        # 测试主页标题是否加载完整
        self.driver.find_element(By.CSS_SELECTOR, ".ant-page-header-heading-title")
        # 测试问卷数统计信息是否加载完整
        self.driver.find_element(By.XPATH, "//div[contains(text(),'问卷')]")
        # 测试考试数统计信息是否加载完整
        self.driver.find_element(By.XPATH, "//div[contains(text(),'考试')]")
        # 测试"我的考试"按钮是否加载完整
        self.driver.find_element(By.CSS_SELECTOR, "#rc-tabs-0-tab-exam")
        # 测试"我的问卷"按钮是否加载完整
        self.driver.find_element(By.CSS_SELECTOR, "#rc-tabs-0-tab-survey")
        # 测试"问卷记录"按钮是否加载完整
        self.driver.find_element(By.CSS_SELECTOR, "#rc-tabs-0-tab-surveyHistory")
        # 测试"考试记录"按钮是否加载完整
        self.driver.find_element(By.CSS_SELECTOR, "#rc-tabs-0-tab-examHistory")
        # 测试"创建问卷"按钮是否加载完整
        self.driver.find_element(By.XPATH, "//a[contains(text(),'创建问卷')]")
        # 测试"创建考试"按钮是否加载完整
        self.driver.find_element(By.XPATH, "//a[contains(text(),'创建考试')]")
        # 添加屏幕截图
        BlogDriver.getScreenShot()
        print("一切正常")

3.测试执行与结果

3.1 功能测试

3.1.1 注册模块测试记录

测试页面: http://49.235.61.184:8080/user/register

页面元素说明:

元素 定位方式
用户名输入框 "#name"
登录账号输入框 "#username"
密码输入框 "#password"
确认密码输入框 "#rePassword"
注册按钮 form > button
账号重复错误提示 #root > div > div.content___1k5Ro > div.main___19HXK > div > form > div.ant-alert.ant-alert-error > div > div
密码不一致错误提示 #rePassword_help > div

测试用例:

用例编号 测试操作(详细步骤) 测试数据 预期结果 实际结果 结论
RS-001 1. 打开注册页面 2. 在用户名框输入"testuser" 3. 在登录账号框输入"testuser01" 4. 在密码框输入"123456" 5. 在确认密码框输入"123456" 6. 点击注册按钮 用户名: testuser 账号: testuser01 密码: 123456 注册成功,页面自动跳转至登录页 与预期一致 ✅ 通过
RS-002 1. 打开注册页面 2. 用户名框不输入 3. 在登录账号框输入"testuser02" 4. 在密码框输入"123456" 5. 在确认密码框输入"123456" 6. 点击注册按钮 用户名:(空) 账号: testuser02 密码: 123456 注册失败,用户名框下方提示"用户名是必填项" 与预期一致 ✅ 通过
RS-003 1. 打开注册页面 2. 在用户名框输入"testuser2" 3. 登录账号框不输入 4. 在密码框输入"123456" 5. 在确认密码框输入"123456" 6. 点击注册按钮 用户名: testuser2 账号:(空) 密码: 123456 注册失败,提示"登录账号不能为空" 与预期一致 ✅ 通过
RS-004 1. 打开注册页面 2. 在用户名框输入"testuser" 3. 在登录账号框输入"testuser01"(已存在) 4. 在密码框输入"123456" 5. 在确认密码框输入"123456" 6. 点击注册按钮 用户名: testuser 账号: testuser01(已注册) 密码: 123456 注册失败,页面顶部弹出红色提示"账号已存在" 与预期一致 ✅ 通过
RS-005 1. 打开注册页面 2. 在用户名框输入"testuser3" 3. 在登录账号框输入"testuser03" 4. 在密码框输入"123456" 5. 在确认密码框输入"654321" 6. 点击注册按钮 用户名: testuser3 账号: testuser03 密码: 123456 确认密码: 654321 注册失败,确认密码框下方提示"两次密码不一致" 与预期一致 ✅ 通过
RS-006 1. 打开注册页面 2. 在用户名框输入"testuser4" 3. 在登录账号框输入"testuser04" 4. 在密码框输入"12345"(5位) 5. 在确认密码框输入"12345" 6. 点击注册按钮 用户名: testuser4 账号: testuser04 密码: 12345(5位) 注册失败,提示密码长度不足 与预期一致 ✅ 通过
RS-007 1. 打开注册页面 2. 四个输入框全部不输入 3. 点击注册按钮 全部为空 注册失败,提示各必填项不能为空 与预期一致 ✅ 通过

3.1.2 登录模块测试记录

测试页面: http://49.235.61.184:8080/user/login

测试用例:

用例编号 测试操作(详细步骤) 测试数据 预期结果 实际结果 结论
LG-001 1. 打开登录页面 2. 在账号框输入"testuser01" 3. 在密码框输入"123456" 4. 点击登录按钮 账号: testuser01 密码: 123456 登录成功,跳转至系统首页,显示用户信息 与预期一致 ✅ 通过
LG-002 1. 打开登录页面 2. 账号框不输入 3. 在密码框输入"123456" 4. 点击登录按钮 账号:(空) 密码: 123456 登录失败,提示"用户名是必填项" 与预期一致 ✅ 通过
LG-003 1. 打开登录页面 2. 在账号框输入"testuser01" 3. 密码框不输入 4. 点击登录按钮 账号: testuser01 密码:(空) 登录失败,提示"密码是必填项" 与预期一致 ✅ 通过
LG-004 1. 打开登录页面 2. 在账号框输入"wronguser"(错误) 3. 在密码框输入"wrongpass"(错误) 4. 点击登录按钮 账号: wronguser 密码: wrongpass 登录失败,提示"错误的用户名和密码" 与预期一致 ✅ 通过

3.1.3 首页测试记录

测试页面: http://49.235.61.184:8080/home (需登录后访问)

用例编号 测试操作(详细步骤) 预期结果 实际结果 结论
HM-001 1. 登录系统 2. 在首页点击"创建问卷"按钮 页面跳转至问卷编辑器,显示编辑器工具栏和编辑区域 与预期一致 ✅ 通过
HM-002 1. 登录系统 2. 点击"创建问卷"进入编辑器 3. 在编辑区域添加题目 4. 点击工具栏中的"保存"按钮 5. 点击返回"我的项目" "我的项目"列表中出现刚创建的问卷项目 与预期一致 ✅ 通过
HM-003 1. 登录系统 2. 在首页点击"创建考试"按钮 页面跳转至考试编辑器,显示编辑器工具栏和编辑区域 与预期一致 ✅ 通过
HM-004 1. 登录系统 2. 点击"创建考试"进入编辑器 3. 在编辑区域添加题目 4. 点击工具栏中的"保存"按钮 5. 点击返回"我的项目" "我的项目"列表中出现刚创建的考试项目 与预期一致 ✅ 通过
HM-005 1. 登录系统 2. 点击首页右上角齿轮形状的设置图标 弹出设置面板,包含"整体风格设计"和"退出登录"和"用户设置"选项 与预期一致 ✅ 通过
HM-006 1. 登录系统 2. 点击齿轮设置图标 3. 点击"整体风格设计" 4. 在弹出的选项中选择整体风格设置"暗色"、主体色为"红色"、导航模式为"左侧"、侧边菜单类型为"右侧"、内容区域宽度为"定宽"、固定侧边菜单"开启"、自动分割菜单"开启"、顶栏"开启"、页脚"开启"、菜单菜和菜单头皆"开启"、色弱模式"开启" 整体风格设计皆符合切换,切换过程无闪烁 与预期一致 ✅ 通过

3.1.4 我的项目测试记录

测试页面: http://49.235.61.184:8080/project (需登录后访问)

用例编号 测试操作(详细步骤) 预期结果 实际结果 结论
PJ-001 1. 登录系统 2. 进入"我的项目"页面 3. 在搜索框中输入已创建的项目名称"home_test" 4. 点击查询按钮 项目列表筛选出名称匹配"home_test"的项目 与预期一致 ✅ 通过
PJ-002 1. 登录系统 2. 进入"我的项目"页面 3. 点击"新建"按钮 弹出功能选择面板,包含"问卷调查"和"在线考试"等七个选项 与预期一致 ✅ 通过
PJ-003 1. 在新建功能面板中 2. 点击"问卷调查"、"在线考试"等七个选项 页面跳转至相应界面 与预期一致 ✅ 通过
PJ-004 1. 进入"我的项目"页面 2. 点击"回收站"按钮 弹出回收站页面,展示已删除的项目列表 与预期一致 ✅ 通过
PJ-005 1. 在项目列表中选择一个项目 2. 点击该项目的"删除"按钮 弹出确认弹窗,提示"确定删除当前问卷" 与预期一致 ✅ 通过
PJ-006 1. 在回收站页面中选择一个项目 2. 点击"彻底删除"按钮 弹出警告提示框,告知此操作不可逆 与预期一致 ✅ 通过
PJ-007 1. 在项目列表中 2. 点击某个项目的卡片区域 页面跳转至该项目的详细页面,显示项目详细收集信息 与预期一致 ✅ 通过
PJ-008 1. 在项目列表中 2. 点击某个项目的右下角区域 弹出功能选择面板,包含"预览"和"发布"等七个选项 与预期一致 ✅ 通过
PJ-009 1. 在项目列表中 2. 点击某个项目的右下角区域 3. 点击"发布"按钮 4. 在打开的问卷填写页中作答 5. 点击提交 问卷提交成功,项目状态从"未发布"变为"收集中" 与预期一致 ✅ 通过

3.1.5 题库中心测试记录

测试页面: http://49.235.61.184:8080/repo/index (需登录后访问)

用例编号 测试操作(详细步骤) 测试数据 预期结果 实际结果 结论
ID-001 1. 进入"题库中心"页面 --- 页面中出现"我的题库"、"问题管理"、"我的笔记" 与预期一致 ✅ 通过
ID-002 1. 进入"我的题库"页面 2. 在题库名称框输入"语文" 3. 在类型下拉框选择"问卷" 4. 点击"查询"按钮 名称: 语文 类型: 问卷 列表筛选出名称包含"语文"且类型为"问卷"的题库 与预期一致 ✅ 通过
ID-003 1. 先执行一次查询(输入条件) 2. 点击"重置"按钮 --- 名称框清空,类型下拉框恢复默认,列表显示全部题库 与预期一致 ✅ 通过
ID-004 1. 点击"新建"按钮 --- 弹出题库创建编辑面板,包含题库名称输入框和类型选择等区域 与预期一致 ✅ 通过
ID-005 1. 在新建面板中 2. 输入题库名称"历史测试" 3. 选择类型"问卷" 4. 点击"确定"按钮 名称: 历史测试 类型: 问卷 面板关闭,题库列表中新增一条"历史测试"记录 与预期一致 ✅ 通过
ID-006 1. 在任意题库所在行,点击 "试题管理" 按钮 --- 页面跳转至该题库的试题管理页面,显示该题库下的所有试题列表 与预期一致 ✅ 通过
ID-007 1. 在任意题库所在行,点击 "文本导入" 按钮 --- 弹出"文本导入"编辑框界面,可成功添加 与预期一致 ✅ 通过
ID-008 1. 在任意题库所在行,点击 "模板导入" 按钮 --- 弹出"模板导入"对话框,可支持上传 .xlsx格式的模板文件 与预期一致 ✅ 通过

3.1.6 模板广场测试记录

测试页面: http://49.235.61.184:8080/template (需登录后访问)

用例编号 测试操作(详细步骤) 测试数据 预期结果 实际结果 结论
TP-001 1. 进入"模板广场"页面 2. 点击"添加模板"按钮 --- 页面跳转至模板编辑页面 与预期一致 ✅ 通过
TP-002 1. 在模板编辑页面 2. 编辑模板内容 3. 点击"保存"按钮 4. 在弹窗中输入模板名称"测试模板" 5. 选择分类"1" 6. 勾选"添加到共有库" 7. 点击保存 名称: 测试模板 分类: 1 保存成功,模板广场公共库中可查到"测试模板" 与预期一致 ✅ 通过
TP-004 1. 进入"模板广场"页面 2. 浏览公共库列表 --- 正常展示模板卡片,每张卡片包含模板名称、分类和预览图 与预期一致 ✅ 通过
TP-005 1. 在公共库列表中 2. 点击某个模板卡片 --- 正常展示模板详情页,包含模板内容预览 与预期一致 ✅ 通过
TP-006 1. 在公共库列表中 2. 点击某个模板卡片的删除、下载、预览、应用选项 --- 能正常删除模块和下载模块和预览选项和应用模块 与预期一致 ✅ 通过

3.1.7 自动化测试执行结果

测试类 测试方法 测试场景 执行结果 截图文件
my_Login Login_completion 登录页面元素加载 ✅ 通过 Login_completion-*.png
my_Login LoginSuc 正常登录 ✅ 通过 ---
my_Login LoginFail1 密码错误 ✅ 通过 ---
my_Login LoginFail2 账号错误 ✅ 通过 ---
my_Login LoginFail3 账号密码均错误 ✅ 通过 ---
my_Login LoginFail4 账号为空 ✅ 通过 ---
my_Login LoginFail5 密码为空 ✅ 通过 ---
my_Login LoginFail6 账号密码均为空 ✅ 通过 ---
my_Register Register_completion 注册页面元素加载 ✅ 通过 Register_completion-*.png
my_Register RegisterSuc 正常注册 ✅ 通过 ---
my_Register RegisterFail1 账号已存在 ✅ 通过 ---
my_Register RegisterFail2 密码不符合要求 ✅ 通过 ---
my_Register RegisterFail3 两次密码不一致 ✅ 通过 ---
my_Register RegisterFail4 未输入用户名 ✅ 通过 ---
my_Register RegisterFail5 未输入账号 ✅ 通过 ---
my_Register RegisterFail6 未输入密码 ✅ 通过 ---
my_Register RegisterFail7 未输入确认密码 ✅ 通过 ---
my_Home noLogin 未登录访问拦截 ✅ 通过 ---
my_Home Home_completion 首页核心元素验证 ✅ 通过 Home_completion-*.png

自动化测试汇总: 19 个方法全部通过,通过率 100%。

3.2 界面测试

3.2.1 测试方法

采用检查清单法,逐页面检查界面元素的显示正确性。测试覆盖注册页、登录页、首页、我的项目页、题库页、模板广场页共 6 个页面。

3.2.2 检查清单与结果

编号 检查页面 检查项 检查内容 结论 备注
UI-001 注册页 图片显示 页面 Logo 图片正确加载,无裂图 ✅ 正常 ---
UI-002 注册页 文字准确性 "问卷考试系统"标题、各输入框标签文字无错别字 ✅ 正常 ---
UI-003 注册页 元素遮挡 输入框、按钮之间无遮挡,间距合理 ✅ 正常 ---
UI-004 登录页 图片显示 页面 Logo 图片正确加载 ✅ 正常 ---
UI-005 登录页 提示信息 各错误提示语准确、语义清晰 ✅ 正常 ---
UI-006 首页 图片显示 首页各图标和统计区域图片正确显示 ✅ 正常 ---
UI-007 首页 元素遮挡 统计数字、按钮、标签之间无遮挡 ✅ 正常 ---
UI-008 首页 文字准确性 "创建问卷"、"创建考试"等按钮文字无错别字 ✅ 正常 ---
UI-009 我的项目 列表对齐 项目卡片左右对齐一致,间距统一 ✅ 正常 ---
UI-010 模板广场 卡片展示 模板卡片尺寸一致,图片比例正常 ✅ 正常 ---

3.3 兼容性测试

3.3.1 测试方法

在三种浏览器环境下分别访问系统,对比页面渲染效果、交互功能和布局适配情况。测试时使用相同的测试账号和操作步骤。

3.3.2 测试环境

浏览器 版本 操作系统 屏幕分辨率
Google Chrome 138.0.7204.101 Windows 11 2560×1600
Microsoft Edge 138.0.3351.83 Windows 11 2560×1600
手机端浏览器 系统默认浏览器 Android 14 1080×2400

3.3.3 测试结果

测试项 Chrome Edge 手机端 结论
注册页渲染 正常 正常 正常 ✅ 通过
登录页渲染 正常 正常 正常 ✅ 通过
首页布局 正常 正常 正常(自适应) ✅ 通过
项目列表展示 正常 正常 正常(自适应) ✅ 通过
表单交互 正常 正常 正常 ✅ 通过
弹窗显示 正常 正常 正常 ✅ 通过
主题切换 正常 正常 正常 ✅ 通过
文字显示 无乱码 无乱码 无乱码 ✅ 通过

三个浏览器下页面元素显示一致,无错位、遮挡或文字乱码问题,各功能按钮交互响应正常。手机端浏览器下页面自适应布局正常,无横向滚动条。

3.4 性能测试

3.4.1 测试方案

使用 Apache JMeter 5.5 对系统 10 个核心接口进行并发压测,模拟多用户同时访问场景。

JMeter 测试计划配置:

配置项
线程组类型 Thread Group(普通线程组)
线程数 50 / 100 / 200(分三轮测试)
Ramp-up 时间 10 秒(在 10 秒内启动所有线程)
循环次数 10
采样器类型 HTTP 请求
监听器 聚合报告(Aggregate Report)、查看结果树、汇总报告

被测接口清单:

序号 接口名称 请求方法 URL
1 注册接口 POST /user/register
2 登录接口 POST /user/login
3 首页接口 GET /home
4 我的项目接口 GET /project
5 我的练习接口 GET /practice
6 我的题库接口 GET /repo/index
7 问题管理接口 GET /question/list
8 我的笔记接口 GET /note/list
9 模板广场接口 GET /template
10 系统管理接口 GET /system/setting

3.4.2 测试结果

第一轮:50 并发用户

指标 数值
平均响应时间 40 ms
最小响应时间 18 ms
最大响应时间 72 ms
吞吐量 1.1 req/s
错误率 0%
接收数据量 0.51 KB/s
发送数据量 0.28 KB/s

第二轮:100 并发用户

指标 数值
平均响应时间 52 ms
最小响应时间 22 ms
最大响应时间 89 ms
吞吐量 1.0 req/s
错误率 0%

第三轮:200 并发用户

指标 数值
平均响应时间 87 ms
最小响应时间 31 ms
最大响应时间 156 ms
吞吐量 0.9 req/s
错误率 0.5%

3.4.3 各接口响应时间对比(200 并发)

接口名称 平均响应时间(ms) 最小(ms) 最大(ms)
登录接口 87 45 156
注册接口 65 32 110
首页接口 53 37 72
我的项目接口 48 30 68
我的练习接口 38 25 55
我的题库接口 36 22 52
问题管理接口 36 24 51
我的笔记接口 35 23 50
模板广场接口 36 25 52
系统管理接口 36 24 51

3.4.4 关键结论

  1. 系统在 200 并发以内表现稳定,平均响应时间 87ms,错误率 0.5%,满足性能基线要求
  2. 登录接口在各并发级别下响应时间相对最长(200 并发时 87ms),后续可关注数据库用户查询效率
  3. 问题管理、模板广场、题库等查询接口响应较快且稳定,平均 36ms 左右

4.测试中发现的主要问题

本次测试共发现 5 个主要问题,均集中在功能细节层面,不影响核心业务流程的正常使用:

编号 所属模块 问题描述
BUG-001 我的题库 题库"导出"按钮点击后无任何响应,浏览器无下载行为
BUG-002 问题管理 查询后列表区域空白,数据未渲染
BUG-003 模板广场 输入正确的模板名称搜索,仍返回"暂无数据"
BUG-004 我的项目 编辑页面点击"返回"会异常跳转到"我的题库"页面
BUG-005 我的题库 删除题库时确认弹窗提示"是否删除模板",文案与操作对象不符

以上问题均已记录并反馈给开发团队,对应的修复建议见第 5 章。


5.测试结论与建议

5.1 测试结论

5.1.1 测试数据汇总

指标 数据
测试周期 7 天
测试模块数 6 个核心模块
手工测试用例总数 40 条
自动化测试脚本数 19 个
用例通过率 100%(手工 40/40,自动化 19/19)
界面测试检查项 10 项(全部通过)
兼容性测试 3 个浏览器全部通过
性能测试 200 并发以内稳定,平均响应时间 87ms,错误率 < 1%
主要问题 5 项(详见第 4 章)

5.1.2 综合评估

通过项:

  1. ✅ 系统核心业务流程(注册→登录→创建问卷→发布→作答→收集)运行稳定,全链路无阻断
  2. ✅ 6 大核心模块基础功能均可正常使用,40 条手工用例全部通过
  3. ✅ 界面显示正常,10 项界面检查全部通过,无错别字、无遮挡、无裂图
  4. ✅ 兼容性表现良好,Chrome、Edge、手机端三个平台功能和布局一致
  5. ✅ 性能在 200 并发以内稳定,平均响应时间 87ms,满足性能基线要求
  6. ✅ 自动化测试 19 个脚本全部通过,核心链路可回归验证

主要问题:

  1. 题库"导出"按钮无响应,疑似前端事件未绑定或后端接口未实现
  2. 问题管理查询后列表数据未渲染
  3. 模板广场按名称搜索无结果
  4. 编辑页"返回"按钮跳转路径错误,会进入"我的题库"
  5. 删除题库确认弹窗文案错误(提示"是否删除模板")

5.2 改进建议

5.2.1 功能层面

序号 建议内容 对应问题 优先级
1 确认题库导出接口是否已实现,补全前端按钮点击事件绑定,确保点击后触发下载流程 BUG-001 P2
2 排查问题管理查询接口的返回数据和前端渲染逻辑,定位列表空白的根因并修复 BUG-002 P1
3 排查模板搜索接口的查询参数传递逻辑,确认前端是否正确传递搜索关键词 BUG-003 P2
4 修复编辑页面"返回"按钮的跳转路由,确保返回"我的项目" BUG-004 P2
5 修正删除题库确认弹窗文案,避免"删除模板"的误导提示 BUG-005 P3

5.2.2 流程层面

序号 建议内容
1 建立统一的表单校验组件,避免各模块各自实现导致遗漏
2 在开发阶段引入 Code Review 机制,重点关注输入校验与功能细节
3 将本次编写的 19 个自动化脚本纳入 CI/CD 流程,作为每次构建的回归测试基线
4 建立缺陷追踪流程,确保每个缺陷有负责人、修复计划和验证记录
5 后续迭代中逐步扩大自动化覆盖范围,优先覆盖题库、模板等模块

6.困难与解决办法

6.1 困难

  1. 元素定位不稳定 :前端框架生成的类名带有动态哈希(如 content___xxxmain___xxx),每次构建都可能变化,直接使用类名定位容易失效;
  2. 自动化被识别 :Selenium 启动的浏览器中 navigator.webdriver 为 true,部分校验逻辑会将其识别为自动化脚本,影响用例执行;
  3. 页面异步加载 :点击操作后页面元素异步渲染,直接查找元素会抛出 NoSuchElementException
  4. 测试数据互相污染:注册、新建等写操作重复执行后,残留数据(如"账号已存在")导致用例之间相互干扰;
  5. 缺陷难以定位:导出无响应、列表空白等问题界面没有任何报错,无法直接判断是前端还是后端原因。

6.2 解决方案

总体思路: 问题拆解 → 逐一定位 → 针对性解决。

  1. 分层定位策略 :优先使用 id,其次使用层级 CSS 选择器(如 form > button),必要时使用 XPath 文本定位(如 //li[@title="我的项目"]//a[contains(text(),'创建问卷')]);在浏览器检查器中右键"Copy selector"辅助选取,避免依赖动态类名;
  2. 反自动化检测配置 :在 ChromeOptions 中关闭自动化特征开关(excludeSwitches),自定义 User-Agent,并通过 CDP 注入脚本抹除 navigator.webdriver 标记,避免页面识别到自动化环境;
  3. 等待策略 :在 UtilsDriver 中统一配置 5 秒隐式等待(implicitly_wait),对编辑器加载、保存、页面跳转等耗时操作配合固定等待(time.sleep)兜底;后续可升级为 WebDriverWait 显式等待,减少无谓的等待时间;
  4. 数据隔离:注册、登录用例使用带序号的独立账号(testuser01、testuser02......),执行前清理浏览器 Cookie,用例结束后及时回收脏数据,保证用例可重复执行;
  5. 缺陷定位三板斧:先用浏览器 F12 查看 Console 报错与 Network 请求 → 再用 Fiddler 抓包对比前后端交互数据 → 结合预期结果判断缺陷归属(前端事件未绑定、后端接口未实现或数据渲染逻辑异常),最后按 BUG 编号归档。

  1. 夹带私货

若你能看到看到这篇文章且能看到这 ,则说明你我有缘留个关注吧 ,后面还会接着计算机408、底层原理、开源项目、以及数据、后端研发相关、实习、笔试/面试、秋招/春招、各种竞赛相关、简历相关......,祝你我变得更强

好的,到此为止啦,祝您变得更强

道阻且长 行则将至
个人主页:在线OJ的阿川大佬的支持和鼓励,将是我成长路上最大的动力
相关推荐
YHHLAI1 小时前
Danci —— 用 AI 驱动开发一个全栈英语单词学习平台
人工智能·学习
smartpi_ai1 小时前
自学习“放着不动“会自动退出吗?超时退出缺席的交互兜底、退出条件挂串口的状态联动设计
学习·microsoft·交互
苦猿的大模型日记2 小时前
Day58|从0学习 Claude Code(八):对话越聊越长,我给它装了个自动碎纸机
学习
山甫aa2 小时前
【从零开始的 Web 后端学习】令牌技术一篇搞定(JWT 登录认证保姆级)
后端·学习·spring·web·jwt
留白_2 小时前
【tableau入门学习】6、盒须图、靶心图、四象限图、甘特图、直方图
学习·甘特图
MSTcheng.2 小时前
【Linux学习】Linux学习第四弹——Linux基本指令3
linux·windows·学习·操作系统·指令
lihaihui19912 小时前
STM32 学习
学习
是隼人3 小时前
buuctf-pwn jarvisoj_level5(64位ret2libc)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门