大规模考试系统性能优化与风险评估

1.报告概述

1.1项目背景

随着数字化教育及企业调研需求的持续增长,在线问卷考试系统已成为教育培训、人才评估、市场调研等领域的核心基础设施。本系统旨在为用户提供稳定、高效、易用的全流程在线问卷与考试服务,涵盖问卷创建、分发、作答、数据收集与分析等关键环节。

在业务快速发展的背景下,系统面临用户量激增、高并发访问、复杂业务场景等多重挑战。为确保系统在生产环境中能够持续提供优质服务,满足日益增长的性能与稳定性要求,特开展本次全面的质量评估项目。本次评估聚焦于系统的性能表现、功能可靠性及用户体验,为核心业务上线提供关键数据支撑与风险预警。

1.2测试目的

本次质量评估项目旨在达成以下核心目标:

  1. 性能基线评估:通过模拟真实用户行为,建立系统关键业务接口的性能基线数据,包括响应时间、吞吐量及资源利用率。

  2. 容量与瓶颈识别:探测系统在高并发场景下的处理极限,识别性能瓶颈及潜在的单点故障风险。

  3. 稳定性验证:验证系统在持续负载压力下的稳定性与可靠性,确保无内存泄漏、连接池耗尽等问题。

  4. 优化效果验证:为后续架构优化与代码调优提供数据依据,并量化评估优化措施的实际效果

1.3测试核心模块

|---------------|--------------------------|----------------------------|
| 用户认证模块 | 处理用户登录、会话管理及权限验证 | 登录接口并发处理能力、Token下发效率、会话保持 |
| 问卷管理模块 | 实现问卷的创建、编辑、发布与模板管理 | 创建/保存问卷的响应速度、数据一致性、富文本处理性能 |
| 考试执行模块 | 支持考生进入考场、加载试题、实时作答与倒计时管理 | 试题加载速度、作答数据实时提交的并发性能 |
| 答卷提交与收集模块 | 处理答案的最终提交、加密存储与即时统计 | 高并发提交的数据一致性、事务处理能力、数据入库性能 |
| 后台管理模块 | 提供数据看板、答卷批阅、成绩导出等功能 | 大数据量查询与导出的响应效率、报表生成的资源消耗 |

1.4测试环境

1、硬件环境

普通 PC 机(满足日常软件运行的基础硬件配置即可,如 Intel i5 及以上处理器、8GB 及以上内存、256GB 及以上存储空间)

2、软件环境

(1)操作系统

Windows 11 专业版

(2)浏览器

Google Chrome

Microsoft Edge

(3)测试工具

UI自动化测试工具:Python ,Selenium

性能测试工具:JMeter

接口测试工具:Postman

2.测试用例

界面测试

性能测试

兼容性测试

安全性测试

易用性测试

功能测试

注册

登录

导航栏

首页

我的项目

我的练习

题库中心

模板广场

系统管理

3.兼容性测试

3.1 chrome

3.2 edge

4.自动化测试

4.1目录

4.2FormHelper:辅助公共类

python 复制代码
from selenium.webdriver.common.by import By#导入 Selenium 的定位方式常量
from selenium.webdriver.support.ui import WebDriverWait#导入显示等待工具类
from selenium.webdriver.support import expected_conditions as EC#导入预定义的等待条件

#表单操作辅助类
class FormHelper:
    def __init__(self, driver):
        #driver为实例变量,供所有方法使用
        self.driver = driver

    def clear_fields(self, css_selectors):
        """清空一组输入框内容
       
        """
        for selector in css_selectors:
            self.driver.find_element(By.CSS_SELECTOR, selector).clear()

    def fill_fields(self, values_by_selector):
        """按选择器填充对应的文本值
        
        """
        for selector, value in values_by_selector.items():
            # 新增: 先等待元素出现再填充
            WebDriverWait(self.driver, 5).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, selector))
            )
            self.driver.find_element(By.CSS_SELECTOR, selector).send_keys(value)

    def click(self, css_selector):
        """点击指定元素,等待元素出现再点击
        
        """
        WebDriverWait(self.driver, 5).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, css_selector))
        )
        self.driver.find_element(By.CSS_SELECTOR, css_selector).click()

    def verify_error_message(self, css_selector, expected_text, timeout=10):
        """校验错误提示文本是否与预期一致
       
        """
        error_element = WebDriverWait(self.driver, timeout).until(
            EC.visibility_of_element_located((By.CSS_SELECTOR, css_selector))
        )
        actual_text = error_element.text.strip()
        print(actual_text)
        assert actual_text == expected_text

    # 在规定时间找到元素是否存在
    def is_element_present(self, css_selector, timeout=0):
        """判断元素是否存在
        
        """
        try:
            if timeout and timeout > 0:
                WebDriverWait(self.driver, timeout).until(
                    EC.presence_of_element_located((By.CSS_SELECTOR, css_selector))
                )
                return True
            else:
                self.driver.find_element(By.CSS_SELECTOR, css_selector)
                return True
        except Exception:
            return False

    # 支持列表,检查列表中的所有元素是否存在
    def are_all_elements_present(self, css_selectors, timeout=0):
        """检查一组元素是否全部存在
        
        """
        for selector in css_selectors:
            if not self.is_element_present(selector, timeout):
                return False
        return True

    def wait_for_presence(self, css_selector, timeout=10):
        """等待元素出现在 DOM 中(可不可见均可)
      
        """
        try:
            WebDriverWait(self.driver, timeout).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, css_selector))
            )
            return True
        except Exception:
            return False

    def wait_for_visibility(self, css_selector, timeout=10):
        """等待元素可见
        
        """
        try:
            WebDriverWait(self.driver, timeout).until(
                EC.visibility_of_element_located((By.CSS_SELECTOR, css_selector))
            )
            return True
        except Exception:
            return False

    def screenshot_after_presence(self, css_selector, timeout=10, extra_delay=2):
        """等待元素出现后再截图,统一避免截图过早
        
        """
        try:
            # 等待元素出现
            WebDriverWait(self.driver, timeout).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, css_selector))
            )

            # 额外等待确保页面完全渲染
            import time
            time.sleep(extra_delay)

            # 等待页面加载完成(通过检查document.readyState)
            WebDriverWait(self.driver, 5).until(
                lambda driver: driver.execute_script("return document.readyState") == "complete"
            )

            # 再次短暂等待确保所有异步内容加载完成
            time.sleep(1)

            from Common.Utils import blog_driver
            blog_driver.GetScreeShot()
            return True
        except Exception:
            return False

    def auto_login(self, url, login_func=None, login_url_kw="login", home_url_kw="home", timeout=20):
        """
        通用自动登录方法:用于先尝试访问url,如果已登录直接进入首页,否则执行指定登录逻辑
        
        """
        self.driver.get(url)
        WebDriverWait(self.driver, timeout).until(
            lambda d: login_url_kw in d.current_url or home_url_kw in d.current_url
        )
        if login_url_kw in self.driver.current_url:
            if login_func:
                login_func()
                # 登录后重定向到主页
                WebDriverWait(self.driver, timeout).until(lambda d: home_url_kw in d.current_url)

4.3Utils.py:驱动类

python 复制代码
import datetime
import os.path
import sys
import os

from selenium.webdriver.common.by import By

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import logging

#CHROME_DRIVER_PATH = "D:\\chromedriver-win64\\chromedriver-win64\\chromedriver.exe"

logging.basicConfig(level=logging.INFO)


class Driver:
    driver = ""

    #def __init__(self):
     #   options = webdriver.ChromeOptions()

      #  self.driver = webdriver.Chrome(service=Service(CHROME_DRIVER_PATH), options=options)
       # self.driver.implicitly_wait(10)
    def __init__(self):
        from webdriver_manager.chrome import ChromeDriverManager

        options = webdriver.ChromeOptions()

        # 自动安装ChromeDriver
        service = Service(ChromeDriverManager().install())

        self.driver = webdriver.Chrome(service=service, options=options)
        self.driver.implicitly_wait(10)

    def GetScreeShot(self):
        dirname = datetime.datetime.now().strftime("%Y-%m-%d")
        # 判读dirname是否存在,不存在就创建文件夹
        if not os.path.exists("../images/" + dirname):
            os.mkdir("../images/" + dirname)

        filename = sys._getframe().f_back.f_code.co_name + "-" + datetime.datetime.now().strftime(
            "%Y-%m-%d-%H%M%S") + ".png"
        self.driver.save_screenshot("../images/" + dirname + "/" + filename)


blog_driver = Driver()

4.4HomepageTest.py:首页

python 复制代码
from selenium.webdriver.support.wait import WebDriverWait
from Common.Utils import blog_driver
from Common.FormHelper import FormHelper
from LoginTest import Login



class HomePage:
    url =""
    driver =""

    def __init__(self):
        self.url ="http://49.235.61.184:8080/home"
        self.driver =blog_driver.driver
        self._auto_login()
        self.driver.get(self.url)
        self.form = FormHelper(self.driver)


    def _auto_login(self):
        # 先尝试访问首页,判断是否已登录(未登录会跳转到登录页)
        self.driver.get(self.url)
        WebDriverWait(self.driver ,10).until(
            lambda d :"login" in d.current_url or "home" in d.current_url
        )

        if "login" in self.driver.current_url:
            login =Login()
            login.LoginSuTest()
    # 检测页面元素
    def pageElements(self):
        elememts_check ={
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-page-header.ant-pro-page-container-warp-page-header.ant-pro-page-container-warp-page-header.ant-page-header-has-breadcrumb.ant-page-header-ghost > div.ant-page-header-heading > div > span",
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-page-header.ant-pro-page-container-warp-page-header.ant-pro-page-container-warp-page-header.ant-page-header-has-breadcrumb.ant-page-header-ghost > div.ant-page-header-content > div > div > div > div > div > div.avatar___3ZBop > span > img",
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-col.ant-col-xs-24.ant-col-sm-24.ant-col-md-24.ant-col-lg-24.ant-col-xl-8 > div > div.ant-card-head > div > div",
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-page-header.ant-pro-page-container-warp-page-header.ant-pro-page-container-warp-page-header.ant-page-header-has-breadcrumb.ant-page-header-ghost > div.ant-page-header-content > div > div > div > div > div > div.content___1eLtZ > div.contentTitle___Yu-cR"
        }
        blog_driver.GetScreeShot()
        if self.form.are_all_elements_present(elememts_check ,5):
            print("元素都存在")
        else:
            print("元素存在有问题")

    # 检测创建文件,试卷是否成功
    def CreatSucTest(self):
        self.form.click("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-col.ant-col-xs-24.ant-col-sm-24.ant-col-md-24.ant-col-lg-24.ant-col-xl-8 > div > div.ant-card-body > div > a:nth-child(1)")
        # 统一等待后截图,增加额外延迟确保页面完全加载
        self.form.screenshot_after_presence("#editorContent > div > div > div.header > div.header-content > div.sc-aXZVg.LyTMt.title.quill-container.not-focus > div > pre > div.ql-editor > p", 15, 3)
        self.driver.back()
        self.form.click("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-col.ant-col-xs-24.ant-col-sm-24.ant-col-md-24.ant-col-lg-24.ant-col-xl-8 > div > div.ant-card-body > div > a:nth-child(2)")
        # 统一等待后截图,增加额外延迟确保页面完全加载
        self.form.screenshot_after_presence("#editorContent > div > div > div.header > div.header-content > div.sc-aXZVg.LyTMt.title.quill-container.not-focus > div > pre > div.ql-editor > p", 15, 3)
        self.driver.back()

    # 检测,我的考试,我的试卷,问卷记录,考试记录按钮
    def CheckSucTest(self):
        # 我的考试
        self.form.click("#rc-tabs-0-tab-exam")
        self.form.screenshot_after_presence("#rc-tabs-0-panel-exam > div > div > div > div.ant-table-wrapper > div > div > div > div > div > table > thead > tr > th:nth-child(1)", 15, 3)
        # 我的问卷
        self.form.click("#rc-tabs-0-tab-survey")
        self.form.screenshot_after_presence("#rc-tabs-0-panel-survey > div > div > div > div.ant-table-wrapper > div > div > div > div > div > table > thead > tr > th:nth-child(1)", 15, 3)
        # 问卷记录
        self.form.click("#rc-tabs-0-tab-surveyHistory")
        self.form.screenshot_after_presence("#rc-tabs-0-panel-surveyHistory > div > div > div > div.ant-table-wrapper > div > div > div > div > div > table > thead > tr > th:nth-child(1)", 15, 3)
        # 考试记录
        self.form.click("#rc-tabs-0-tab-examHistory")
        self.form.screenshot_after_presence("#rc-tabs-0-panel-examHistory > div > div > div > div.ant-table-wrapper > div > div > div > div > div > table > thead > tr > th:nth-child(1)", 15, 3)


# home=HomePage()
# home.CheckSucTest()

4.5LoginTest.py:登录

python 复制代码
from Common.Utils import blog_driver
from Common.FormHelper import FormHelper
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from Register import Register


class Login:
    url = ""
    driver = ""
    register_instance = ""
    creds = ""

    def __init__(self):
        self.url = "http://49.235.61.184:8080/user/login"
        self.driver = blog_driver.driver
        self.driver.get(self.url)
        self.driver.implicitly_wait(10)
        self.form = FormHelper(self.driver)
        self.register_instance = Register()
        self.register_instance.RegisterSucTest()  # 只注册一次
        self.driver.get(self.url)  # 注册后跳转回登录页

    def clear(self):
        self.form.clear_fields(["#username", "#password"])

    def commit(self, username, password):
        self.form.fill_fields({
            "#username": username,
            "#password": password,
        })

    def _verify_error_message(self, css_selector, expected_text):
        self.form.verify_error_message(css_selector, expected_text, timeout=10)

    # 登录成功
    def LoginSuTest(self):
        # 注册一个成功的账号
        self.clear()
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys(self.register_instance.username)
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys(self.register_instance.password)
        blog_driver.GetScreeShot()
        self.form.click("#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button")

        # 证明登录成功
        WebDriverWait(self.driver, 10).until(EC.url_contains("/home"))
        self._verify_error_message(
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-page-header.ant-pro-page-container-warp-page-header.ant-pro-page-container-warp-page-header.ant-page-header-has-breadcrumb.ant-page-header-ghost > nav > ol > li:nth-child(2) > span.ant-breadcrumb-link > span",
            "首页")
        # self.driver.get(self.url)

    # 登录失败
    def LoginFailTest(self, username="", password="", error_rules=None):
        self.driver.get(self.url)
        # 清空
        self.clear()
        # 填充
        self.commit(username, password)
        # 提交
        self.form.click("#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button")
        blog_driver.GetScreeShot()

        # 验证所有错误提示
        if error_rules:
            for css_selector, expected_text in error_rules.items():
                self._verify_error_message(css_selector, expected_text)

        blog_driver.GetScreeShot()
        self.driver.get(self.url)

    # 登录失败--都为空
    def FailTest1(self):
        self.LoginFailTest("", "",
                           error_rules={
                               "#username_help > div": "用户名是必填项!",
                               "#password_help > div": "密码是必填项!"
                           })

    # 登录失败--账号为空
    def FailTest2(self):
        self.LoginFailTest("", self.register_instance.password,
                           error_rules={
                               "#username_help > div": "用户名是必填项!"
                           })

        # 登录失败--密码为空

    def FailTest3(self):
        self.LoginFailTest(self.register_instance.username, "",
                           error_rules={
                               "#password_help > div": "密码是必填项!"
                           })

# login=Login()
# # login.LoginSuTest()
# login.LoginSuTest()
# login.FailTest1()
# login.FailTest2()
# login.FailTest3()

4.6MyprojectTest.py:我的项目

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

from Common.Utils import blog_driver
from Common.FormHelper import FormHelper
from LoginTest import Login


class MyProject:
    url = ""
    driver = ""

    def __init__(self):
        self.url = "http://49.235.61.184:8080/project"
        self.driver = blog_driver.driver
        self.form = FormHelper(self.driver)
        # 公共自动登录方法,未登录时执行Login().LoginSuTest
        # self.form.auto_login(self.url, login_func=lambda: Login().LoginSuTest())
        self.driver.get(self.url)

        # 检测页面元素

    def pageElements(self):
        elememts_check = {"#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-page-header.ant-pro-page-container-warp-page-header.ant-pro-page-container-warp-page-header.ant-page-header-has-breadcrumb.ant-page-header-ghost > div.ant-page-header-heading > div > span"}
        blog_driver.GetScreeShot()
        if self.form.are_all_elements_present(elememts_check, 5):
            print("元素都存在")
        else:
            print("元素存在有问题")

    # 测试新增问卷调查
    def AddnewTest(self):
        #self.form.click("body > div:nth-child(9) > div > div > ul > li.ant-dropdown-menu-item.ant-dropdown-menu-item-active.ant-dropdown-menu-item-only-child")
        #self.form.click(".ant-dropdown-menu-item:nth-child(2)")
        self.driver.find_element(By.XPATH, "/html/body/div[5]/div/div/ul/li[2]").click()
        # 等待问卷调查出现并截图
        self.form.screenshot_after_presence("body > div:nth-child(7) > div > div > ul > li:nth-child(1) > span")
        self.form.click("body > div:nth-child(7) > div > div > ul > li:nth-child(1) > span")
        # 检测跳转成功并截图
        self.form.screenshot_after_presence("#editorContent > div > div > div.header > div.header-content > div.sc-aXZVg.LyTMt.title.quill-container.not-focus > div > pre > div.ql-editor > p")
        # 新增
        self.form.fill_fields({"#editorContent > div > div > div.header > div.header-content > div.sc-aXZVg.LyTMt.title.quill-container.not-focus > div > pre > div.ql-editor": "add"})
        # 保存
        self.driver.find_element(By.CSS_SELECTOR,"#editor > div.survey-main-panel > div.survey-main-panel-toolbar > div:nth-child(2) > div > button.ant-btn.ant-btn-primary.ant-btn-sm").click()
        blog_driver.GetScreeShot()
        self.driver.back()
        self.driver.back()

        # 检查问卷是否新增成功
        self.form.verify_error_message(
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-list.ant-list-split.ant-list-grid.survey-home-content > div > div > div > div > div > div > div > div > div > div.card-header > span.survey-title",
            "add")
        blog_driver.GetScreeShot()

    # 检测项目查询功能
    def CheckTest(self):
        self.form.fill_fields({"#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-page-header.ant-pro-page-container-warp-page-header.ant-pro-page-container-warp-page-header.ant-page-header-has-breadcrumb.ant-page-header-ghost > div.ant-page-header-content > div > div > div > div > div > div > div > span > span > input": "add"})
        blog_driver.GetScreeShot()
        self.form.click(
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-page-header.ant-pro-page-container-warp-page-header.ant-pro-page-container-warp-page-header.ant-page-header-has-breadcrumb.ant-page-header-ghost > div.ant-page-header-content > div > div > div > div > div > div > div > span > span > span > button")
        blog_driver.GetScreeShot()
        self.form.verify_error_message(
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-list.ant-list-split.ant-list-grid.survey-home-content > div > div > div > div > div > div > div > div > div > div.card-header > span.survey-title",
            "add")

# project=MyProject()
# project.AddnewTest()
# project.CheckTest()

4.7PersonalPage.py:个人页面

python 复制代码
import time

from Common.Utils import blog_driver
from Common.FormHelper import FormHelper
from LoginTest import Login
from selenium.webdriver.common.by import By


class TemplatePage:
    url = ""
    driver = ""

    def __init__(self):
        self.url = "http://49.235.61.184:8080/template"
        self.driver = blog_driver.driver
        self.form = FormHelper(self.driver)
        # 公共自动登录方法,未登录时执行Login().LoginSuTest
        # self.form.auto_login(self.url, login_func=lambda: Login().LoginSuTest())
        self.driver.get(self.url)

    # 添加模板
    def AddTemplate(self):
        self.form.click(
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-page-header.ant-pro-page-container-warp-page-header.ant-pro-page-container-warp-page-header.ant-page-header-has-breadcrumb.ant-page-header-has-footer.ant-page-header-ghost > div.ant-page-header-heading > span > div > div > button")
        blog_driver.GetScreeShot()
        # 添加
        self.form.fill_fields({
                                  "#editorContent > div > div > div.header > div.header-content > div.sc-aXZVg.LyTMt.title.quill-container.not-focus > div.quill.title > pre > div.ql-editor.ql-blank > p": "模板测试"})
        blog_driver.GetScreeShot()
        # 保存
        self.form.click(
            "#editor > div.survey-main-panel > div.survey-main-panel-toolbar > div:nth-child(2) > div > button:nth-child(5)")
        # 跳出提示
        # 新增模板名称
        self.driver.find_element(By.XPATH, "//*[@id=\"name\"]").send_keys("测试添加模板")
        # 从下拉菜单中选择
        self.driver.find_element(By.XPATH, "//*[@id=\"category\"]").send_keys("测试")
        blog_driver.GetScreeShot()
        # 添加到公共库
        self.form.click(
            "#survey-modal-container > div > div.ant-modal-wrap > div > div.ant-modal-content > div.ant-modal-body > form > div:nth-child(4) > div > div > div > div > label > span.ant-checkbox > input")
        # 保存
        self.driver.find_element(By.CSS_SELECTOR,
                                 "#survey-modal-container > div > div.ant-modal-wrap > div > div.ant-modal-content > div.ant-modal-footer > button.ant-btn.ant-btn-primary").click()
        blog_driver.GetScreeShot()
        time.sleep(5)
        # 关闭
        self.driver.find_element(By.CSS_SELECTOR,
                                 "#editor > div.survey-main-panel > div.survey-main-panel-toolbar > div:nth-child(2) > div > button.ant-btn.ant-btn-primary.ant-btn-sm.ant-btn-dangerous").click()
        # 检测是否添加成功
        self.form.verify_error_message(
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.cardList > div > div > div > div > div:nth-child(1) > div > div > div > div.ant-card-body > div.ant-card-meta > div > div.ant-card-meta-title > a",
            "测试添加模板")

    # 模板名称搜索
    def SearchTemplateTest(self):
        self.form.fill_fields({"#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-page-header.ant-pro-page-container-warp-page-header.ant-pro-page-container-warp-page-header.ant-page-header-has-breadcrumb.ant-page-header-has-footer.ant-page-header-ghost > div.ant-page-header-content > div > div > div > div > div > span > span > input": "测试添加模板"})
        self.form.click("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-page-header.ant-pro-page-container-warp-page-header.ant-pro-page-container-warp-page-header.ant-page-header-has-breadcrumb.ant-page-header-has-footer.ant-page-header-ghost > div.ant-page-header-content > div > div > div > div > div > span > span > span > button")
        blog_driver.GetScreeShot()
        actual = self.driver.find_element(By.XPATH, "//*[contains(text(),'暂无数据')]").text
        print(f"找到的文本内容: {actual}")
        # 断言检测一下是否符合预期
        assert "暂无数据" in actual
# person=TemplatePage()
# person.AddTemplate()
# person.SearchTemplateTest()

4.8PersonalSettings:个人设置

python 复制代码
import time
from selenium.webdriver.common.by import By
from Common.Utils import blog_driver
from Common.FormHelper import FormHelper
from LoginTest import Login


class PersonalsetingPage:
    url = ""
    driver = ""

    def __init__(self):
        self.url = "http://49.235.61.184:8080/system/setting"
        self.driver = blog_driver.driver
        self.form = FormHelper(self.driver)
        # 公共自动登录方法,未登录时执行Login().LoginSuTest
        # self.form.auto_login(self.url, login_func=lambda: Login().LoginSuTest())
        self.driver.get(self.url)

    # 检测页面元素
    def pageElements(self):
        elememts_check = {
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.right___2jdGg > div.title___3cGwa",
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.right___2jdGg > div.baseView___3sRG3 > div.right___3-EXe > div.avatar___1GisI",
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.right___2jdGg > div.baseView___3sRG3 > div.right___3-EXe > span > div > span > div > button",
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.right___2jdGg > div.baseView___3sRG3 > div.left___GavW0 > form > div:nth-child(2) > div > div.ant-col.ant-form-item-label > label"
        }
        blog_driver.GetScreeShot()
        if self.form.are_all_elements_present(elememts_check, 5):
            print("元素都存在")
        else:
            print("元素存在有问题")

    # 提交--全填
    def CommitSucTest(self):
        time.sleep(5)
        self.form.fill_fields({"#name": "admin"})
        self.form.fill_fields({"#phone": "111"})
        self.form.fill_fields({"#email": "111"})
        self.form.fill_fields({"#profile": "111"})
        blog_driver.GetScreeShot()

        # 提交
        self.form.click(
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.right___2jdGg > div.baseView___3sRG3 > div.left___GavW0 > form > div.ant-space.ant-space-horizontal.ant-space-align-center > div:nth-child(2) > button")
        time.sleep(1)
        # 检测
        self.form.verify_error_message(
            "#sk-layout > div > div > section > div.ant-pro-layout-container > header.ant-layout-header.ant-pro-layout-header.ant-pro-layout-header-fixed-header.ant-pro-layout-header-mix.ant-pro-layout-header-fixed-header-action.ant-pro-layout-header-header > div > div.ant-pro-global-header-right-content > div > div > div > span > div > span:nth-child(2)",
            "admin")

        # 清理

    def clear(self):
        self.form.clear_fields(["#name", "#phone", "#email", "#profile"])

    def commit(self, name, phone, email, profile):
        self.form.fill_fields({
            "#name": name,
            "#phone": phone,
            "#email": email,
            "#profile": profile,
        })

    def CommitFailTest(self, name="", username="", password="", repassword="", error_rules=None):
        # 清空
        self.clear()
        # 填充
        self.commit(name, username, password, repassword)
        # 提交
        self.form.click(
            "#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.right___2jdGg > div.baseView___3sRG3 > div.left___GavW0 > form > div.ant-space.ant-space-horizontal.ant-space-align-center > div:nth-child(2) > button")
        blog_driver.GetScreeShot()

        # 验证所有错误提示
        if error_rules:
            for css_selector, expected_text in error_rules.items():
                self.form.verify_error_message(css_selector, expected_text)

        blog_driver.GetScreeShot()

    # 全不填
    def FailTest1(self):

        self.CommitFailTest("add", "", "", "",
                            error_rules={
                                "#phone_help > div": "请输入您的联系电话!",
                                "#email_help > div": "请输入您的邮箱!",
                                "#profile_help > div": "请输入个人简介!"
                            })

# personal=PersonalsetingPage()
# personal.FailTest1()

4.9Register.py:注册

python 复制代码
import time

from Common.Utils import blog_driver
from Common.FormHelper import FormHelper
from selenium.webdriver.common.by import By
import random
import datetime


class Register:
    url = ""
    driver = ""
    password = ""
    name = ""
    username = ""

    def __init__(self):
        self.url = "http://49.235.61.184:8080/user/register"
        self.driver = blog_driver.driver
        self.driver.get(self.url)
        self.name = ""  # 初始化实例属性
        self.password = ""
        self.driver.implicitly_wait(5)
        self.form = FormHelper(self.driver)

    # 清理
    def clear(self):
        self.form.clear_fields(["#name", "#username", "#password", "#rePassword"])

    def commit(self, name, username, password, repassword):
        self.form.fill_fields({
            "#name": name,
            "#username": username,
            "#password": password,
            "#rePassword": repassword,
        })

    def Getpassword(self):
        len = random.randint(6, 10)
        min_num = 10 ** (len - 1)
        max_num = (10 ** len) - 1
        self.password = random.randint(min_num, max_num)

    def Getname(self):
        self.name = "测试账号" + datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S")

    def _verify_error_message(self, css_selector, expected_text):
        self.form.verify_error_message(css_selector, expected_text, timeout=10)

    # 登录成功
    def RegisterSucTest(self):
        self.clear()
        self.Getname()
        # 随机生成6-10位数字长度
        self.Getpassword()
        self.username = "123" + self.name
        self.commit(self.name, self.username, self.password, self.password)
        blog_driver.GetScreeShot()
        self.form.click("#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button")
        time.sleep(2)
        # 证明登录成功
        self.driver.find_element(By.CSS_SELECTOR,
                                 "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button")
        blog_driver.GetScreeShot()

    def RegisterFailTest(self, name="", username="", password="", repassword="", error_rules=None):
        # 清空
        self.clear()
        # 填充
        self.commit(name, username, password, repassword)
        # 提交
        self.form.click("#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button")
        blog_driver.GetScreeShot()

        # 验证所有错误提示
        if error_rules:
            for css_selector, expected_text in error_rules.items():
                self._verify_error_message(css_selector, expected_text)

        blog_driver.GetScreeShot()
        self.driver.get(self.url)

    # 重复注册---信息已经存在
    def FaileTest1(self):
        self.RegisterSucTest()
        self.driver.back()

        self.RegisterFailTest(
            name=self.name,
            username="123" + self.name,
            password=self.password,
            repassword=self.password,
            error_rules={
                "#root > div > div.content___1k5Ro > div.main___19HXK > div > form > div.ant-alert.ant-alert-error > div > div": "账号已存在"
            }
        )

    # 注册失败--全不填
    def FaileTest2(self):
        self.RegisterFailTest(name="",
                              username="",
                              password="",
                              repassword="",
                              error_rules={
                                  "#name_help > div": "用户名是必填项!",
                                  "#username_help > div": "登录账号不能为空",
                                  "#password_help > div": "密码是必填项!",
                                  "#rePassword_help > div": "请再次输入密码"
                              })

    # 注册失败--姓名,密码为空
    def FaileTest3(self):
        self.Getname()
        self.Getpassword()
        self.RegisterFailTest(name="",
                              username="123" + self.name,
                              password="",
                              repassword=self.password,
                              error_rules={
                                  "#name_help > div": "用户名是必填项!",
                                  "#password_help > div": "密码是必填项!",
                              })

        # 注册失败--姓名,账户为空

    def FaileTest4(self):
        self.Getpassword()
        self.RegisterFailTest(name="",
                              username="",
                              password=self.password,
                              repassword=self.password,
                              error_rules={
                                  "#name_help > div": "用户名是必填项!",
                                  "#username_help > div": "登录账号不能为空",
                              })

    # 注册失败--账号,密码,密码确认为空
    def FaileTest5(self):
        self.Getname()
        self.RegisterFailTest(name=self.name,
                              username="",
                              password="",
                              repassword="",
                              error_rules={
                                  "#username_help > div": "登录账号不能为空",
                                  "#password_help > div": "密码是必填项!",
                                  "#rePassword_help > div": "请再次输入密码"
                              })

    # 注册失败--姓名,密码,密码确认为空
    def FaileTest6(self):
        self.Getname()
        self.RegisterFailTest(name="",
                              username=self.name,
                              password="",
                              repassword="",
                              error_rules={
                                  "#name_help > div": "用户名是必填项!",
                                  "#password_help > div": "密码是必填项!",
                                  "#rePassword_help > div": "请再次输入密码"
                              })

        # 注册失败--姓名,账号,密码为空

    def FaileTest7(self):
        self.Getpassword()
        self.RegisterFailTest(name="",
                              username="",
                              password="",
                              repassword=self.password,
                              error_rules={
                                  "#name_help > div": "用户名是必填项!",
                                  "#username_help > div": "登录账号不能为空",
                                  "#password_help > div": "密码是必填项!",
                              })

# register=Register()
# register.FaileTest1()
# register.FaileTest2()
# register.FaileTest3()
# register.FaileTest4()
# register.FaileTest5()
# register.FaileTest6()
# register.FaileTest7()

4.10RunTest.py:运行

python 复制代码
import time

from Common.Utils import blog_driver, Driver
from Common.FormHelper import FormHelper

# Test classes
from HomepageTest import HomePage
from LoginTest import Login
from Register import Register
from PersonalPage import TemplatePage
from MyprojectTest import MyProject
from MyQuestionPage import MyQuestion
from PersonalSettingsTest import PersonalsetingPage

if __name__ == "__main__":
    # 注册
    Register().RegisterSucTest()
    #Register().FaileTest1()
    #Register().FaileTest2()
    #Register().FaileTest3()
    #Register().FaileTest4()
    #Register().FaileTest5()
    #Register().FaileTest6()
    #Register().FaileTest7()

    # 登录
    login = Login()
    login.LoginSuTest()
    #login.FailTest1()
    #login.FailTest2()
    #login.FailTest3()

    # 首页
    #HomePage().pageElements()
    #HomePage().CreatSucTest()
    #HomePage().CheckSucTest()

    # 我的项目
    #MyProject().pageElements()
    #MyProject().AddnewTest()
    #MyProject().CheckTest()

    # 我的题库
    #MyQuestion().pageElements()
    #MyQuestion().AddnewTest()
    #MyQuestion().SearchTest()

    # 模板广场
    #template = TemplatePage()
    #template.AddTemplate()
    #template.SearchTemplateTest()

    # 个人设置
    personal = PersonalsetingPage()
    personal.pageElements()
    personal.CommitSucTest()
    personal.FailTest1()

5.性能测试

5.1postman

5.2jmeter

5.3聚合报告

5.4吞吐量(Transactions per Second)

本次问卷考试系统的性能评估表明,系统在当前负载下表现出良好的稳定性和可扩展性。核心业务接口在持续3分钟的压力测试中保持平稳运行,整体吞吐量稳定在120-140 TPS,峰值达到180 TPS,且无性能衰减趋势。其中,数据查询类接口性能优异,而用户登录接口作为关键路径承载了主要压力,虽未构成瓶颈,但建议实施针对性优化以进一步提升系统弹性。测试结果验证了系统架构能够有效支撑预期并发用户量,为后续业务增长提供了可靠的性能基线。整体而言,系统已达到上线标准,具备投入生产环境服务的能力。

5.5随时间变化的活跃线程状态(Active Threads Over Time)

根据随时间变化的活跃线程状态图表分析:系统在压力测试期间展现出优秀的线程管理能力与稳定的并发处理性能。线程数按预设策略平稳上升,在测试中期达到并维持目标并发规模,无异常线程堆积或提前释放现象。整个压力施加阶段线程曲线平滑,表明系统资源调度有效,未出现因线程竞争或资源不足导致的剧烈波动。测试结束阶段线程数有序下降,进一步验证了系统在负载解除后的资源回收机制运行正常。整体而言,系统的并发控制模块设计合理,能够可靠地支撑设计范围内的用户并发访问。

5.6性能报告

6.总结

6.1性能问题总结

响应时间表现:所有接口响应时间均保持在极低水平,系统响应迅速。

吞吐量表现:系统吞吐能力稳定,各接口负载分布均衡,无单点瓶颈。

最大响应时间异常:login接口出现5.9秒极值(可能原因:首次连接建立、SSL握手、数据库连接创建)

6.2优化建议

针对登录接口

引入缓存机制,将用户登录凭证或鉴权信息缓存至 Redis 等内存数据库,减少数据库查询次数。

优化数据库查询逻辑,如添加索引、拆分复杂查询,提升登录鉴权效率。

针对系统整体

梳理高响应时间接口的业务逻辑,去除冗余操作,优化代码执行效率。

考虑引入分布式架构或服务拆分,将核心功能(如登录、题库)独立部署,提升系统整体并发能力

7.项目链接:

https://gitee.com/xiaoshe-c-language/blog_auto_test/tree/origin

相关推荐
热爱生活的五柒2 小时前
在有真实标签 (Ground Truth) 的情况下,常用的指标有哪些?聚类指标有哪些?
python·指标
superman超哥2 小时前
仓颉语言智能指针深度实战:突破 GC 与所有权的边界
c语言·开发语言·c++·python·仓颉
Elaine3362 小时前
【基于 Scikit-learn 本地数据集的垂直领域词云生成】
python·机器学习·nlp·scikit-learn·词云
3824278272 小时前
python:mysql数据库
数据库·python·mysql
中科院提名者2 小时前
KNN实战进阶:模型评估、Scikit-learn实现与Numpy手动编码
python·numpy·scikit-learn
2401_841495643 小时前
【LeetCode刷题】杨辉三角
数据结构·python·算法·leetcode·杨辉三角·时间复杂度·空间复杂度
小白开始进步3 小时前
OpenCV图像滤波:Python实战指南
人工智能·python·opencv
Aevget3 小时前
Python开发利器PyCharm v2025.3全新发布——支持主动数据探索
开发语言·ide·python·pycharm
znhy_233 小时前
day44打卡
python