问卷考试系统—测试报告
目录
一、项目背景
(一)、测试目标
(二)、测试任务概述
(二)、测试环境
二、测试用例
三、手动测试 - 测试各页面的功能
(一)、注册页面
(二)、登陆页面
(三)、页面设置
(四)、首页
(五)、我的项目页面
(六)、我的练习页面
(七)、我的题库页面
(八)、问题管理页面
(九)、模板广场页面
(十)、用户管理页面
(十一)、个人设置页面
四、兼容性测试
五、自动化测试
(一)、导入依赖包 - pom.xml
(二)、驱动类 - Utils
(三)、注册页面功能测试类 - RegisterPage
(四)、登录页面功能测试类 - LoginPage
(五)、首页页面功能测试类 - HomePage
(六)、我的项目页面功能测试类 - MyProjectPage
(七)、我的题库页面功能测试类 - MyQuestionBankPage
(八)、模板广场页面功能测试类 - TemplateSquarePage
(九)、个人设置页面功能测试类 - PersonalSettingsPage
(十)、RunTests类
六、性能测试
(一)、Postman进行测能测试
(二)、jmeter进行性能测试
1、注册
2、登录
3、首页
1)currentUser
2)userOverview
3)listUserTask
4、我的项目
5、我的练习
1)practiceList
2)exerciseList
6、我的题库
7、问题管理
8、模板广场
1)listTag
2)listCategory
3)templateSquareList
9、用户管理
1)list
2)permissionList
3)userManagementList
(三)、聚合报告
(四)、TPS可视化
(五)、响应时间可视化
(六)、活跃线程数可视化
(七)、性能测试报告
1、Dashboard - 汇总展示核心性能指标
2、Over Time
3、Throughput
4、Response Times
七、Bug描述
(一)、我的项目页面
(二)、我的题库页面
(三)、模板广场页面
(四)、用户管理页面
(五)、个人设置页面
八、测试总结
一、项目背景
问卷考试系统是基于Web开发的在线平台,便于用户创建管理各种问卷和考试,同时还对数据进行收集与分析,帮助用户快速掌握有效的信息。而且也对题库、模板以及系统进行管理
(一)、测试目标
1)验证系统的稳定性和兼容性:确保问卷/考试创建、题库/试题管理、个人信息管理等核心功能无缺陷,符合需求文档要求,为用户提供流畅的线上考试问卷体验。
2)确保数据安全性与准确性:保障考试、问卷数据、作答结果存储安全、传输加密。
3)确保系统稳定性与兼容性:在不同的浏览器、不同的操作系统以及多用户并发下,确保系统稳定运行、无卡顿。
4)验证系统性能达标:满足预期并发用户下,问卷/考试创建、提交、查询等操作响应及时。
(二)、测试任务概述
1)手动测试:测试各页面的功能有效性、交互合理性、权限准确性、数据正确性及异常场景适配,全面验证用户真实操作流程中的系统表现。
2)自动化测试:测试核心功能正常有效。
3)兼容性测试:测试在不同的设备、不同的浏览器上页面显示是否正常;
4)性能测试:使用jmeter来模拟多用户并发执行核心操作,确保系统性能能满足业务预期。
(二)、测试环境
- 操作系统:Windows 11 家庭中文版
- 浏览器:Google Chrome、Edge
- 测试工具:Selenium 、JMeter、postman
- 开发工具:IntelliJ IDEA Community Edition 2022.1.4
二、测试用例


问卷考试系统Xmind:a板书图解/问卷考试系统.xmind · momin/mominJava的代码 - 码云 - 开源中国
三、手动测试 - 测试各页面的功能
(一)、注册页面
测试场景一:输入正确的姓名、登录账号、密码、密码确认,点击“注册账户”按钮
预期结果:显示注册成功,跳转到登录页面


测试场景二:不输入姓名,其他正常输入,点击“注册账户”按钮
预期结果:用户名是必填项!

测试场景三:不输入登录账号,其他正常输入,点击“注册账户”按钮
预期结果:登陆账号不能为空

测试场景四:输入已存在的账号,点击“注册账户”按钮
预期结果:账号已存在


测试场景五:密码为空、确认密码为空,其他正常输入,点击“注册账户”按钮
预期结果:密码是必填项!、请再次输入密码

测试场景六:密码小于6位
预期结果:密码至少6位

测试场景七:输入的密码和密码确认不一样
预期结果:两次密码不一致!

(二)、登陆页面
测试场景一:输入正确的账号和密码,点击登录
预期结果:显示登陆成功!跳转到问卷考试系统的首页页面


测试场景二:姓名为空,密码正常输入,点击登录
预期结果:用户名是必填项!

测试场景三:密码为空,姓名正常输入,点击登录
预期结果:密码是必填项!

测试场景四:姓名正确、密码不正确,点击登录
预期结果:错误的用户名和密码

测试场景五:姓名不正确、密码正确,点击登录
预期结果:错误的用户名和密码

测试场景六:姓名、密码都不正确,点击登录
预期结果:错误的用户名和密码

(三)、页面设置
测试场景一:点击设置按钮
预期结果:弹出选项栏

测试场景二:点击“整体风格设置”,选择整体风格设置中的暗色风格(实验功能)
预期结果:呈现暗色风格页面



测试场景三:点击“用户设置”
预期结果:跳转到系统管理的个人设置页面


测试场景四:点击“退出登录”
预期结果:跳转到登录页面


(四)、首页
测试场景一:点击”创建问卷“
预期结果:跳转到编辑问卷内容页面


测试场景二:编辑好问卷内容,点击”保存“按钮,再点击“项目”按钮
预期结果:保存成功,首页页面问卷数+1,在我的项目页面可以查看




测试场景三:点击”创建考试“
预期结果:跳转到编辑考试内容页面


测试场景一:编辑好考试内容,点击”保存“按钮,再点击“项目”按钮
预期结果:保存成功,首页页面考试数+1,在我的项目页面可以查看




(五)、我的项目页面
测试场景一:在输入框中输入存在的项目名,点击“查询”按钮
预期结果:下面显示搜索的项目


测试场景二:点击“新建”按钮
预期结果:弹出新建的选项栏


测试场景三:点击“问卷调查”按钮
预期结果:跳转到编辑问卷内容页面


测试场景四:点击“在线考试”按钮
预期结果:跳转到编辑考试内容页面


测试场景五:点击“新建文件夹”按钮
预期结果:弹出创建文件夹弹窗


测试场景六:输入名称(如:学习),点击“确定”按钮
预期结果:在我的项目中显示“学习”文件夹


测试场景七:点击“回收站”按钮
预期结果:弹出回收站弹窗


测试场景八:选择想要删除的(如:学习),点击“彻底删除”按钮;弹出彻底删除问卷弹窗,点击“删除”按钮
预期结果:在回收站弹窗中已经没有学习文件夹



测试场景九:选择想要删除的(如:考试名称),点击“恢复”按钮;弹出恢复问卷弹窗,点击“恢复”按钮
预期结果:在回收站弹窗中已经没有考试名称项目,在我的项目中显示




测试场景十:点击某一个项目(如:“大学生心里调查问卷”)
预期结果:跳转到项目的设置页面


测试场景十一:点击开启后,再点击“打开”按钮,进行填写内容,再提交
预期结果:跳转到问卷/考试提交后,这个项目从“未发布”变成了“收集中”,数据份数+1




测试场景十二:点击“...”后;点击“删除”按钮 ,弹出弹窗;选择点击“删除”按钮
预期结果:我的项目中没有这个项目



(六)、我的练习页面
测试场景一:点击“下拉选择框”,选择”正在进行“的状态,点击查询
预期结果:显示“正在进行”的题库


测试场景二:点击“下拉选择框”,选择”已完成“的状态,点击查询
预期结果:显示“已完成”的题库


测试场景三:点击“重置”按钮
预期结果:我的练习列表中显示练过的题库


(七)、我的题库页面
测试场景一:点击“新建”按钮
预期结果:弹出新增题库弹窗


测试场景二:编辑完内容后,点击“确定”按钮
预期结果:题库列表中显示这个题库


测试场景三:题库名称为空,其他正常输入,点击“确定”按钮
预期结果:题库名称不能为空

测试场景四:题库类型未选择,其他正常输入,点击“确定”按钮
预期结果:请选择题库类型

测试场景五:在输入框中输入题库名(如:数学),在选择框中选择类型(如:考试),点击“查询”按钮
预期结果:显示查询结果


测试场景六:点击“重置”按钮
预期结果:输入框和选择框清空,题库列表中显示全部的题库


测试场景七:点击操作中“...”按钮,点击“删除”后,点击弹窗中“删除”按钮
预期结果:提示删除成功,题库列表没有这个题库



(八)、问题管理页面
测试场景一:选择类型、题型,点击“查询”按钮
预期结果:试题列表中显示查询到的试题


测试场景二:点击“重置”按钮
预期结果:选择框和输入框清空,试题列表中全部的试题


测试场景三:点击操作中“编辑”按钮,进行内容编辑,点击“保存”按钮
预期结果:显示编辑成功


(九)、模板广场页面
测试场景一:点击“添加模板”按钮,编辑内容,点击“保存”按钮,在保存到问卷模板库弹窗中输入内容后,点击“保存”按钮
预期结果:显示问卷模板保存成功,在库中显示这个模板





测试场景二:在问卷模板库弹窗,不输入模板名称,其他正常输入,点击“保存”按钮
预期结果:名称不能为空

测试场景三:在问卷模板库弹窗,不输入分类,其他正常输入,点击“保存”按钮
预期结果:请选择分类

测试场景四:输入已存在的模板名字,点击“搜模板”按钮
预期结果:库中显示搜索出的模板


实际结果:显示“暂无数据”
(十)、用户管理页面
测试场景一:输入已存在的姓名,点击“查询”按钮
预期结果:系统用户列表中显示查询的用户信息


测试场景二:点击“重置”按钮
预期结果:输入框清空,系统用户列表中显示所有的用户信息


测试场景三:点击“新建”按钮后,在新建用户弹窗,填写内容,点击“确定”按钮
预期结果:在系统用户列表中显示新建用户的信息



测试场景四:在新建用户弹窗中,用户名为空,其他正常输入,点击“确定”按钮
预期结果:提示用户名不能为空

测试场景五:在新建用户弹窗中,登录名为空,其他正常输入,点击“确定”按钮
预期结果:提示登录名不能为空

测试场景六:在新建用户弹窗中,输入已存在的登录名,其他正常输入,点击“确定”按钮
预期结果:提示登录名已存在!

测试场景七:在新建用户弹窗中,输入密码为空,其他正常输入,点击“确定”按钮
预期结果:提示请输入密码! 、两次输入密码不一致!

测试场景八:在新建用户弹窗中,确认密码为空,其他正常输入,点击“确定”按钮
预期结果:确认密码不能为空!

测试场景九:在新建用户弹窗中,状态未选择,其他正常输入,点击“确定”按钮
预期结果:状态不能为空


实际结果:未选择状态,新建用户成功,在系统用户列表中显示这个用户的信息
测试场景十:点击操作中的编辑按钮,修改成已存在的登录名,点击“确定”按钮
预期结果:登录名已存在!


测试场景十一:点击“更多”
预期结果:显示下拉栏

测试场景十一:点击“重置密码”按钮后,点击重置密码弹窗中的“修改”按钮
预期结果:提示修改成功



测试场景十二:点击“删除用户”按钮后,点击删除用户弹窗中的“删除”按钮
预期结果:提示删除成功



(十一)、个人设置页面
测试场景一:修改姓名、手机号、邮箱、个人简介,点击"提交"按钮
预期结果:提示更新基本信息成功


测试场景二:姓名为空,其他都输入,点击“提交”按钮
预期结果:提示请输入您的昵称!

测试场景三:手机号为空,其他都输入,点击“提交”按钮
预期结果:提示请输入您的联系电话!

测试场景四:邮箱为空,其他都输入,点击“提交”按钮
预期结果:请输入您的邮箱!

测试场景五:个人简介为空,其他都输入,点击“提交”按钮
预期结果:请输入个人简介!

测试场景六:点击“安全设置”
预期结果:跳转到安全设置页面


测试场景七:点击“修改”按钮
预期结果:显示修改密码弹窗


测试场景八:输入旧密码、新密码、确认新密码,点击“确认修改”按钮
预期结果:提示密码修改成功,跳转到登陆页面

实际结果:提示密码修改成功,并未跳转到登陆页面

测试场景九:输入错误的旧密码、输入正确新密码和确认新密码,点击“确认修改”按钮
预期结果:提示密码验证失败

测试场景十:旧密码为空,其他都输入,点击“确认修改”按钮
预期结果:提示请输入密码!

测试场景十一:新密码为空,其他都输入,点击“确认修改”按钮
预期结果:提示请输入密码!、两次密码输入不一致

测试场景十二:确认密码为空,其他都输入,点击“确认修改”按钮
预期结果:提示请再次输入密码

四、兼容性测试
测试场景一:使用Chrome浏览器访问问卷考试系统
预期结果:无异常且一切布局显示功能等与其一致





测试场景二:使用Edge浏览器访问问卷考试系统
预期结果:无异常且一切布局显示功能等与其一致





测试场景三:使用手机浏览器访问问卷考试系统
预期结果:无异常且一切布局显示功能等与其一致

五、自动化测试
(一)、导入依赖包 - pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>QESystemTest</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.0.0</version></dependency><dependency><groupId>io.github.bonigarcia</groupId><artifactId>webdrivermanager</artifactId><version>5.8.0</version><scope>test</scope></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency></dependencies>
</project>
(二)、驱动类 - Utils
package common;import io.github.bonigarcia.wdm.WebDriverManager;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.WebDriverWait;import java.io.File;
import java.io.IOException;
import java.security.PublicKey;
import java.text.SimpleDateFormat;
import java.time.Duration;public class Utils {public static WebDriver driver = null;public WebDriverWait wait = null;/*** 获取驱动对象*/public static WebDriver createDriver(){if (driver == null){//下载驱动WebDriverManager.chromedriver().setup();//添加配置:允许访问所有的链接ChromeOptions options = new ChromeOptions();options.addArguments("--remote-allow-origins=*");//启动浏览器时自动最大化窗口options.addArguments("--start-maximized");//创建驱动对象driver = new ChromeDriver(options);//隐式等待driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));}return driver;}/*** 构造方法* 初始化WebDriver驱动并加载指定的url页面*/public Utils(String url){//调用driver对象driver = createDriver();//浏览器打开指定的url对应的页面driver.get(url);wait = new WebDriverWait(driver,Duration.ofSeconds(10));}/*** 屏幕截图* String str:传入的字符串参数,用于标识截图的场景,如方法名。*/public void ScreenShot(String str) throws IOException {//定义年月日格式SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd");//定义时分秒毫秒格式SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("HHmmssSS");//将当前时间转换为对应格式的字符串String dirTime = simpleDateFormat1.format(System.currentTimeMillis());String fileTime = simpleDateFormat2.format(System.currentTimeMillis());//定义图片文件名String filename = "./src/test/java/images/" + dirTime + "/" + str + "-" + fileTime +".png";//执行截图并保存File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(srcFile,new File(filename));}/*** 销毁driver对象-关闭浏览器*/public static void quit(){if (driver != null){//彻底终止整个浏览器会话driver.quit();}}}
(三)、注册页面功能测试类 - RegisterPage
package tests;import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;import java.io.IOException;
import java.time.Duration;public class RegisterPage extends Utils {public static String url = "http://49.235.61.184:8080/user/register";public RegisterPage() {super(url);}/*** 注册页面可以正常打开*/public void checkRegisterPageRight(){//检查输入框driver.findElement(By.cssSelector("#name"));driver.findElement(By.cssSelector("#username"));driver.findElement(By.cssSelector("#password"));driver.findElement(By.cssSelector("#rePassword"));//检查按钮driver.findElement(By.cssSelector("#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button"));}/*** 测试一:成功注册-输入正确的姓名、登录账号、密码、密码确认*/public void registerSuc() throws IOException {/*//先清空输入框的内容driver.findElement(By.cssSelector("#name")).clear();driver.findElement(By.cssSelector("#username")).clear();driver.findElement(By.cssSelector("#password")).clear();driver.findElement(By.cssSelector("#rePassword")).clear();*///刷新driver.navigate().refresh();//输入正确的姓名、登录账号、密码、密码确认driver.findElement(By.cssSelector("#name")).sendKeys("linlin");driver.findElement(By.cssSelector("#username")).sendKeys("2w");driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#rePassword")).sendKeys("123456");driver.findElement(By.cssSelector("#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button")).click();//检查是否注册成功,跳转到登录页面driver.findElement(By.cssSelector("#root > div > div.content___2zk1- > div.top___1C1Zi > div.header___5xZ3f > span"));//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());}/*** 测试二:注册失败-姓名为空,其他输入正确*/public void registerFail1() throws IOException, InterruptedException {//先清空输入框的内容driver.findElement(By.cssSelector("#name")).clear();driver.findElement(By.cssSelector("#username")).clear();driver.findElement(By.cssSelector("#password")).clear();driver.findElement(By.cssSelector("#rePassword")).clear();//姓名为空,其他输入正确driver.findElement(By.cssSelector("#username")).sendKeys("linlin");driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#rePassword")).sendKeys("123456");driver.findElement(By.cssSelector("#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button")).click();//检查是否注册失败Thread.sleep(1000);String tip = driver.findElement(By.cssSelector("#name_help > div")).getText();/*WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));WebElement tipElement = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#name_help > div")));String tip = tipElement.getText();*///屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert tip.equals("用户名是必填项!");}/*** 测试三:输入已存在的账号*/public void registerFail2() throws IOException {/*//先清空输入框的内容driver.findElement(By.cssSelector("#name")).clear();driver.findElement(By.cssSelector("#username")).clear();driver.findElement(By.cssSelector("#password")).clear();driver.findElement(By.cssSelector("#rePassword")).clear();*/driver.navigate().refresh();//姓名为空,其他输入正确driver.findElement(By.cssSelector("#name")).sendKeys("xiaolin");driver.findElement(By.cssSelector("#username")).sendKeys("615");driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#rePassword")).sendKeys("123456");driver.findElement(By.cssSelector("#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button")).click();//检查是否注册失败String tip = driver.findElement(By.cssSelector("#root > div > div.content___1k5Ro > div.main___19HXK > div > form > div.ant-alert.ant-alert-error > div > div")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert tip.equals("账号已存在");}/*** 测试三:输入的密码和密码确认不一样*/public void registerFail3() throws IOException {driver.navigate().refresh();driver.findElement(By.cssSelector("#name")).sendKeys("xiaolin");driver.findElement(By.cssSelector("#username")).sendKeys("615");//密码不一致driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#rePassword")).sendKeys("123654");driver.findElement(By.cssSelector("#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button")).click();//检查是否注册失败String tip = driver.findElement(By.cssSelector("#rePassword_help > div")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert tip.equals("两次密码不一致!");}/*** 测试三:密码小于6位*/public void registerFail4() throws IOException {driver.navigate().refresh();driver.findElement(By.cssSelector("#name")).sendKeys("xiaolin");driver.findElement(By.cssSelector("#username")).sendKeys("615");//密码不一致driver.findElement(By.cssSelector("#password")).sendKeys("12345");driver.findElement(By.cssSelector("#rePassword")).sendKeys("12345");driver.findElement(By.cssSelector("#root > div > div.content___1k5Ro > div.main___19HXK > div > form > button")).click();//检查是否注册失败String tip = driver.findElement(By.cssSelector("#password_help > div")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert tip.equals("密码至少6位");}
}
(四)、登录页面功能测试类 - LoginPage
package tests;import common.Utils;
import org.openqa.selenium.By;import java.io.IOException;public class LoginPage extends Utils {public static String url = "http://49.235.61.184:8080/user/login";public LoginPage() {super(url);}/*** 注册页面可以正常打开*/public void checkLoginPageRight(){driver.findElement(By.cssSelector("#root > div > div.content___2zk1- > div.top___1C1Zi > div.header___5xZ3f > span"));//检查输入框driver.findElement(By.cssSelector("#username"));driver.findElement(By.cssSelector("#password"));//检查按钮driver.findElement(By.cssSelector("#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button"));}/*** 测试一 登录成功*/public void loginSuc() throws IOException {/*//先清空输入框的内容driver.findElement(By.cssSelector("#username")).clear();driver.findElement(By.cssSelector("#password")).clear();*///刷新driver.navigate().refresh();//输入正确的账号和密码driver.findElement(By.cssSelector("#username")).sendKeys("lin");driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button")).click();//检测是否登陆成功driver.findElement(By.cssSelector("#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"));//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());}/*** 测试二:输入错误的姓名、密码*/public void loginFile1() throws IOException {/* //清空输入框的内容driver.findElement(By.cssSelector("#username")).clear();driver.findElement(By.cssSelector("#password")).clear();*///刷新driver.navigate().refresh();//输入错误的姓名、密码driver.findElement(By.cssSelector("#username")).sendKeys("hh");driver.findElement(By.cssSelector("#password")).sendKeys("aaaaaa");driver.findElement(By.cssSelector("#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button")).click();//检查是否登录失败String str = driver.findElement(By.cssSelector("#root > div > div.content___2zk1- > div.main___x4OjT > div > form > div.ant-alert.ant-alert-error > div > div")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert str.equals("错误的用户名和密码");}/*** 测试三:输入错误的姓名、正确的密码*/public void loginFile2() throws IOException {//刷新driver.navigate().refresh();//输入错误的姓名、密码driver.findElement(By.cssSelector("#username")).sendKeys("aa");driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button")).click();//检查是否登录失败String str = driver.findElement(By.cssSelector("#root > div > div.content___2zk1- > div.main___x4OjT > div > form > div.ant-alert.ant-alert-error > div > div")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert str.equals("错误的用户名和密码");}/*** 测试四:输入正确的姓名、错误的密码*/public void loginFile3() throws IOException {//刷新driver.navigate().refresh();//输入正确的姓名、错误的密码driver.findElement(By.cssSelector("#username")).sendKeys("lin");driver.findElement(By.cssSelector("#password")).sendKeys("aaaaaa");driver.findElement(By.cssSelector("#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button")).click();//检查是否登录失败String str = driver.findElement(By.cssSelector("#root > div > div.content___2zk1- > div.main___x4OjT > div > form > div.ant-alert.ant-alert-error > div > div")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert str.equals("错误的用户名和密码");}/*** 测试五:姓名为空,输入正确的密码*/public void loginFile4() throws IOException, InterruptedException {//刷新driver.navigate().refresh();//姓名为空,输入正确的密码driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button")).click();//检查是否登录失败Thread.sleep(1000);String str = driver.findElement(By.cssSelector("#username_help > div")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert str.equals("用户名是必填项!");}/*** 测试六:密码为空,输入正确的姓名*/public void loginFile5() throws IOException, InterruptedException {//刷新driver.navigate().refresh();//密码为空,输入正确的姓名driver.findElement(By.cssSelector("#username")).sendKeys("lin");driver.findElement(By.cssSelector("#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button")).click();//检查是否登录失败Thread.sleep(1000);String str = driver.findElement(By.cssSelector("#password_help > div")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert str.equals("密码是必填项!");}}
(五)、首页页面功能测试类 - HomePage
package tests;import common.Utils;
import org.openqa.selenium.By;import java.io.IOException;public class HomePage extends Utils {public static String url = "http://49.235.61.184:8080/home";public HomePage() {super(url);}/*** 检查页面元素* 注意:先要确保用户登录*/public void checkHomePageRight() throws IOException {//检查“我的考试”按钮driver.findElement(By.cssSelector("#rc-tabs-0-tab-exam"));//检查“我的问卷”按钮driver.findElement(By.cssSelector("#rc-tabs-0-tab-survey"));//检查“问卷记录”按钮driver.findElement(By.cssSelector("#rc-tabs-0-tab-surveyHistory"));//检查“考试记录”按钮driver.findElement(By.cssSelector("#rc-tabs-0-tab-examHistory"));//检查问卷数driver.findElement(By.cssSelector("#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.extraContent___3rMo7 > div:nth-child(1) > div > div.ant-statistic-title"));//检查考试数driver.findElement(By.cssSelector("#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.extraContent___3rMo7 > div:nth-child(2) > div > div.ant-statistic-title"));//检查“创建问卷”按钮driver.findElement(By.cssSelector("#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)"));//检查“创建考试”按钮driver.findElement(By.cssSelector("#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)"));//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());}
}
(六)、我的项目页面功能测试类 - MyProjectPage
package tests;import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;import java.io.IOException;
import java.time.Duration;public class MyProjectPage extends Utils {public static String url = "http://49.235.61.184:8080/project";public MyProjectPage() {super(url);}/*** 检查页面元素*/public void checkMyProjectPageRight() {//检查页面标题driver.findElement(By.cssSelector("#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"));//检查搜索框driver.findElement(By.cssSelector("#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"));//检查“查询”按钮driver.findElement(By.cssSelector("#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 > span > svg"));//检查“新建”按钮driver.findElement(By.cssSelector("#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 > span > div > div > button"));}/*** 测试一:创建调查问卷*/public void createSurveyQuestionnaires() throws IOException, InterruptedException {// 点击“新建”按钮driver.findElement(By.cssSelector("#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 > span > div > div > button")).click();//显式等待:最长等10秒,直到“问卷调查”选项可见WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));//用 XPath 文本定位WebElement surveyItem = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(@class, 'ant-dropdown-menu')]//span[text()='问卷调查']")));//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());// 滚动到元素 + JS强制点击((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({block: 'center'});", surveyItem);Thread.sleep(1000);((JavascriptExecutor) driver).executeScript("arguments[0].click();", surveyItem);Thread.sleep(1000);//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//点击“保存”按钮driver.findElement(By.cssSelector("#editor > div.survey-main-panel > div.survey-main-panel-toolbar > div:nth-child(2) > div > button.ant-btn.ant-btn-primary.ant-btn-sm > span")).click();//点击"项目"driver.findElement(By.cssSelector("#root > div > div.survey-main-navigator > div.actions-container > div:nth-child(6) > a > button > span.anticon.anticon-home > svg")).click();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//查询是否新建成功//在搜索框中输入搜索的内容,点击“查询”按钮driver.findElement(By.cssSelector("#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")).sendKeys("请输入标题");driver.findElement(By.cssSelector("#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 > span > svg")).click();//检查是否新建成功String str = driver.findElement(By.cssSelector("#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:nth-child(1) > div > div > div > div > div > div.card-header > span.survey-title")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert str.equals("请输入标题");}/*** 测试一:创建在线考试*/public void createOnlineExams() throws IOException, InterruptedException {// 点击“新建”按钮driver.findElement(By.cssSelector("#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 > span > div > div > button")).click();//显式等待:最长等10秒,直到“问卷调查”选项可见WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));//用 XPath 文本定位WebElement surveyItem = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(@class, 'ant-dropdown-menu')]//span[text()='在线考试']")));//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());// 滚动到元素 + JS强制点击((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({block: 'center'});", surveyItem);Thread.sleep(1000);((JavascriptExecutor) driver).executeScript("arguments[0].click();", surveyItem);Thread.sleep(1000);//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//点击“保存”按钮driver.findElement(By.cssSelector("#editor > div.survey-main-panel > div.survey-main-panel-toolbar > div:nth-child(2) > div > button.ant-btn.ant-btn-primary.ant-btn-sm > span")).click();//点击"项目"driver.findElement(By.cssSelector("#root > div > div.survey-main-navigator > div.actions-container > div:nth-child(6) > a > button > span.anticon.anticon-home > svg")).click();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//查询是否新建成功//在搜索框中输入搜索的内容,点击“查询”按钮driver.findElement(By.cssSelector("#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")).sendKeys("考试名称");driver.findElement(By.cssSelector("#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 > span > svg")).click();//检查是否新建成功String str = driver.findElement(By.cssSelector("#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:nth-child(1) > div > div > div > div > div > div.card-header > span.survey-title")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert str.equals("考试名称");}
}
(七)、我的题库页面功能测试类 - MyQuestionBankPage
package tests;import common.Utils;
import org.openqa.selenium.By;import java.io.IOException;public class MyQuestionBankPage extends Utils {public static String url = "http://49.235.61.184:8080/repo/index";public MyQuestionBankPage() {super(url);}/*** 检查页面元素*/public void checkMyQuestionBankPageRight() throws IOException {//检查页面标题driver.findElement(By.cssSelector("#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(3) > span.ant-breadcrumb-link > span"));//检查名称输入框driver.findElement(By.cssSelector("#name"));//检查类型选择框driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-pro-card.ant-pro-table-search.ant-pro-table-search-query-filter > form > div > div:nth-child(2) > div > div > div.ant-col.ant-form-item-control > div > div > div > div"));//检查“重置”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-pro-card.ant-pro-table-search.ant-pro-table-search-query-filter > form > div > div:nth-child(3) > div > div > div.ant-col.ant-form-item-control > div > div > div > div > div > div:nth-child(1) > button"));//检查“查询”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-pro-card.ant-pro-table-search.ant-pro-table-search-query-filter > form > div > div:nth-child(3) > div > div > div.ant-col.ant-form-item-control > div > div > div > div > div > div:nth-child(2) > button"));//检查“新建”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div:nth-child(2) > div > div.ant-pro-table-list-toolbar > div > div.ant-space.ant-space-horizontal.ant-space-align-center.ant-pro-table-list-toolbar-right > div:nth-child(1) > div > div > button"));//检查“文本导入”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div:nth-child(2) > div > div.ant-table-wrapper > div > div > div > div > div > table > tbody > tr:nth-child(2) > td:nth-child(9) > div > div:nth-child(1) > a"));//检查“模板导入”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div:nth-child(2) > div > div.ant-table-wrapper > div > div > div > div > div > table > tbody > tr:nth-child(2) > td:nth-child(9) > div > div:nth-child(2) > a"));//检查“试题管理”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div:nth-child(2) > div > div.ant-table-wrapper > div > div > div > div > div > table > tbody > tr:nth-child(2) > td:nth-child(9) > div > div:nth-child(3) > a"));//检查“...”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div:nth-child(2) > div > div.ant-table-wrapper > div > div > div > div > div > table > tbody > tr:nth-child(2) > td:nth-child(9) > div > div:nth-child(4) > a"));//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());}/*** 测试一:新建题库和查询*/public void createQuestionBank() throws IOException, InterruptedException {//新建//点击“新建”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div:nth-child(2) > div > div.ant-pro-table-list-toolbar > div > div.ant-space.ant-space-horizontal.ant-space-align-center.ant-pro-table-list-toolbar-right > div:nth-child(1) > div > div > button")).click();Thread.sleep(2000);//输入题库名称/*driver.findElement(By.cssSelector("#name")).sendKeys("自动化测试");*/driver.findElement(By.xpath("//input[@placeholder=\"请输入题库名称\"]")).sendKeys("自动化测试");Thread.sleep(2000);//选择题库类型driver.findElement(By.xpath("//div[contains(@class, 'ant-drawer')]//*[@id='mode']")).click();Thread.sleep(1000);driver.findElement( By.xpath("//div[contains(@class, 'ant-drawer')]//*[text()='问卷']")).click();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//点击”确定“按钮driver.findElement(By.cssSelector("body > div:nth-child(7) > div > div.ant-drawer-content-wrapper > div > div > div.ant-drawer-footer > div > div > div:nth-child(2) > button")).click();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//查询//输入新建题库的名字Thread.sleep(1000);driver.findElement(By.cssSelector("#name")).sendKeys("自动化测试");//点击“查询”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div > main > div > div.ant-pro-grid-content > div > div > div > div.ant-pro-card.ant-pro-table-search.ant-pro-table-search-query-filter > form > div > div:nth-child(3) > div > div > div.ant-col.ant-form-item-control > div > div > div > div:nth-child(1) > div > div:nth-child(2) > button")).click();Thread.sleep(1000);//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//获取新建题库的名称String str = driver.findElement(By.xpath("//td[@title='自动化测试']")).getAttribute("title");assert str.equals("自动化测试");}/*** 测试二:重置*/public void reset() throws IOException, InterruptedException {//点击“重置”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-pro-card.ant-pro-table-search.ant-pro-table-search-query-filter > form > div > div:nth-child(3) > div > div > div.ant-col.ant-form-item-control > div > div > div > div > div > div:nth-child(1) > button")).click();Thread.sleep(1000);//获取第一个题库的标签String str = driver.findElement(By.cssSelector("#sk-layout > div > div > section > div > main > div > div.ant-pro-grid-content > div > div > div > div:nth-child(2) > div > div.ant-table-wrapper > div > div > div > div > div > table > tbody > tr:nth-child(2) > td:nth-child(7) > span")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert str.equals("123");String str1 = driver.findElement(By.cssSelector("#name")).getText();assert str1.equals("");}}
(八)、模板广场页面功能测试类 - TemplateSquarePage
package tests;import common.Utils;
import org.openqa.selenium.By;import java.io.IOException;public class TemplateSquarePage extends Utils {public static String url = "http://49.235.61.184:8080/template";public TemplateSquarePage() {super(url);}/*** 检查页面元素*/public void checkTemplateSquarePageRight() throws IOException {//检查标题driver.findElement(By.cssSelector("#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 > div > span"));//检查搜索框driver.findElement(By.cssSelector("#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"));//检查“搜模板”按钮driver.findElement(By.cssSelector("#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"));//检查“添加模板”按钮driver.findElement(By.cssSelector("#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"));//检查公共库driver.findElement(By.cssSelector("#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-footer > div > div.ant-tabs-nav > div.ant-tabs-nav-wrap > div > div.ant-tabs-tab.ant-tabs-tab-active"));//检查私有库driver.findElement(By.cssSelector("#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-footer > div > div.ant-tabs-nav > div.ant-tabs-nav-wrap > div > div:nth-child(2)"));//检查分类driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-card > div > form > div:nth-child(1) > div.label___12r3x > span"));//检查标签driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div.ant-pro-grid-content > div > div > div > div.ant-card > div > form > div:nth-child(2) > div.label___12r3x > span"));//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());}/*** 测试一:添加模板*/public void addTemplate() throws IOException, InterruptedException {//点击“添加模板”按钮driver.findElement(By.cssSelector("#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")).click();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//点击“保存”按钮driver.findElement(By.cssSelector("#editor > div.survey-main-panel > div.survey-main-panel-toolbar > div:nth-child(2) > div > button:nth-child(5)")).click();//添加模板名称driver.findElement(By.cssSelector("#name")).sendKeys("测试模板");//添加分类driver.findElement(By.cssSelector("#category")).sendKeys("测试");//勾选添加到公共库driver.findElement(By.cssSelector("#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")).click();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//点击“保存”按钮driver.findElement(By.cssSelector("#survey-modal-container > div > div.ant-modal-wrap > div > div.ant-modal-content > div.ant-modal-footer > button.ant-btn.ant-btn-primary")).click();Thread.sleep(3000);//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//点击“关闭”按钮driver.findElement(By.cssSelector("#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();Thread.sleep(1000);//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//检查是否添加成功String str = driver.findElement(By.cssSelector("#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")).getText();assert str.equals("测试模板");}/*** 测试二:搜索模板*/public void searchTemplate() throws IOException {//在搜索框中输入你想要查找的内容driver.findElement(By.cssSelector("#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")).sendKeys("测试模板");//点击“搜模板”按钮driver.findElement(By.cssSelector("#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")).click();//如果显示“暂无数据”则“搜模板”按钮异常String str = driver.findElement(By.cssSelector("#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 > div.ant-empty-description")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert str.equals("暂无数据");}}
(九)、个人设置页面功能测试类 - PersonalSettingsPage
package tests;import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;import java.io.IOException;
import java.time.Duration;public class PersonalSettingsPage extends Utils {public static String url = "http://49.235.61.184:8080/system/setting";public PersonalSettingsPage() {super(url);}/*** 检查页面元素*/public void checkPersonalSettingsPageRight() throws IOException {//检查“基本设置”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.leftMenu___179-W > ul > li.ant-menu-item.ant-menu-item-selected.ant-menu-item-only-child > span"));//检查“安全设置”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.leftMenu___179-W > ul > li:nth-child(2) > span"));//检查“AI设置”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.leftMenu___179-W > ul > li:nth-child(3) > span"));//检查“系统设置”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.leftMenu___179-W > ul > li:nth-child(4) > span"));//检查姓名输入框driver.findElement(By.cssSelector("#name"));//检查手机号输入框driver.findElement(By.cssSelector("#phone"));//检查邮箱输入框driver.findElement(By.cssSelector("#email"));//检查个人简介输入框driver.findElement(By.cssSelector("#profile"));//检查“提交”按钮driver.findElement(By.cssSelector("#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"));//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());}/*** 测试一:提交基本信息*/public void submitBasicInformationSuc() throws IOException {//刷新driver.navigate().refresh();//输入姓名driver.findElement(By.cssSelector("#name")).sendKeys("霖霖");//输入手机号driver.findElement(By.cssSelector("#phone")).sendKeys("13727357843");//输入邮箱driver.findElement(By.cssSelector("#email")).sendKeys("3847563783@qq.com");//输入个人简介driver.findElement(By.cssSelector("#profile")).sendKeys("linlin");//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//点击“提交”按钮driver.findElement(By.cssSelector("#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")).click();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//验证是否修改成功String str = driver.findElement(By.cssSelector("#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-header > div > div.ant-pro-global-header-right-content > div > div > div > span > div > span:nth-child(2)")).getText();assert str.equals("霖霖");}/*** 测试二:修改失败-姓名为空*/public void updateInformationFile1() throws IOException {
//刷新driver.navigate().refresh();//输入手机号driver.findElement(By.cssSelector("#phone")).sendKeys("13727357843");//输入邮箱driver.findElement(By.cssSelector("#email")).sendKeys("3847563783@qq.com");//输入个人简介driver.findElement(By.cssSelector("#profile")).sendKeys("linlin");//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//点击“提交”按钮driver.findElement(By.cssSelector("#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")).click();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//验证是否修改成功String str = driver.findElement(By.cssSelector("#name_help > div")).getText();assert str.equals("请输入您的昵称!");}/*** 测试三:修改失败-手机号为空*/public void updateInformationFile2() throws IOException {//刷新driver.navigate().refresh();//输入姓名driver.findElement(By.cssSelector("#name")).sendKeys("霖霖");//输入邮箱driver.findElement(By.cssSelector("#email")).sendKeys("3847563783@qq.com");//输入个人简介driver.findElement(By.cssSelector("#profile")).sendKeys("linlin");//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//点击“提交”按钮driver.findElement(By.cssSelector("#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")).click();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//验证是否修改成功String str = driver.findElement(By.cssSelector("#phone_help > div")).getText();assert str.equals("请输入您的联系电话!");}/*** 测试四:修改失败-邮箱为空*/public void updateInformationFile3() throws IOException {//刷新driver.navigate().refresh();//输入姓名driver.findElement(By.cssSelector("#name")).sendKeys("霖霖");//输入手机号driver.findElement(By.cssSelector("#phone")).sendKeys("13727357843");//输入个人简介driver.findElement(By.cssSelector("#profile")).sendKeys("linlin");//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//点击“提交”按钮driver.findElement(By.cssSelector("#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")).click();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//验证是否修改成功String str = driver.findElement(By.cssSelector("#email_help > div")).getText();assert str.equals("请输入您的邮箱!");}/*** 测试五:修改失败-个人简介为空*/public void updateInformationFile4() throws IOException {//刷新driver.navigate().refresh();//输入姓名driver.findElement(By.cssSelector("#name")).sendKeys("霖霖");//输入手机号driver.findElement(By.cssSelector("#phone")).sendKeys("13727357843");//输入邮箱driver.findElement(By.cssSelector("#email")).sendKeys("3847563783@qq.com");//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//点击“提交”按钮driver.findElement(By.cssSelector("#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")).click();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//验证是否修改成功String str = driver.findElement(By.cssSelector("#profile_help > div")).getText();assert str.equals("请输入个人简介!");}/*** 测试六:修改账户密码*/public void updatePassword() throws IOException, InterruptedException {//刷新driver.navigate().refresh();//点击“安全设置”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.leftMenu___179-W > ul > li:nth-child(2) > span")).click();//点击“修改”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.right___2jdGg > div.ant-list.ant-list-split > div > div > ul > li > ul > li > a")).click();//输入旧密码driver.findElement(By.cssSelector("#oldPassword")).sendKeys("123456");//输入新密码driver.findElement(By.cssSelector("#password")).sendKeys("111111");//输入确认密码driver.findElement(By.cssSelector("#confirmPassword")).sendKeys("111111");//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());/*//点击“确认修改”按钮driver.findElement(By.cssSelector("body > div:nth-child(8) > div > div.ant-modal-wrap > div > div.ant-modal-content > div.ant-modal-footer > div > div > div:nth-child(2) > button")).click();//屏幕截图*/// 点击“确认修改”按钮WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));// 等待弹窗按钮容器可见,直接定位“主按钮”(Ant Design 弹窗的确认按钮默认是 primary 类型)WebElement confirmBtn = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(".ant-modal-content .ant-modal-footer .ant-btn-primary")));confirmBtn.click();ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());driver.findElement(By.cssSelector("#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-header > div > div.ant-pro-global-header-right-content > div > div > div > div:nth-child(2) > span > svg")).click();//用 XPath 文本定位WebElement surveyItem = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(@class, 'ant-dropdown-menu')]//span[text()='退出登录']")));// 滚动到元素 + JS强制点击((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({block: 'center'});", surveyItem);Thread.sleep(1000);((JavascriptExecutor) driver).executeScript("arguments[0].click();", surveyItem);Thread.sleep(1000);//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//输入正确的账号和密码driver.findElement(By.cssSelector("#username")).sendKeys("lin");driver.findElement(By.cssSelector("#password")).sendKeys("111111");driver.findElement(By.cssSelector("#root > div > div.content___2zk1- > div.main___x4OjT > div > form > button")).click();//检测是否登陆成功String str = driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.right___2jdGg > div.title___3cGwa")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert str.equals("基本设置");}/*** 测试七:修改账户密码失败-旧密码为空*/public void updatePasswordFile1() throws IOException, InterruptedException {//刷新driver.navigate().refresh();//点击“安全设置”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.leftMenu___179-W > ul > li:nth-child(2) > span")).click();//点击“修改”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.right___2jdGg > div.ant-list.ant-list-split > div > div > ul > li > ul > li")).click();//输入新密码driver.findElement(By.cssSelector("#password")).sendKeys("123456");//输入确认密码driver.findElement(By.cssSelector("#confirmPassword")).sendKeys("123456");//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//点击“确认修改”按钮driver.findElement(By.cssSelector("body > div:nth-child(7) > div > div.ant-modal-wrap > div > div.ant-modal-content > div.ant-modal-footer > div > div > div:nth-child(2) > button")).click();Thread.sleep(1000);String str = driver.findElement(By.cssSelector("#oldPassword_help > div")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert str.equals("请输入密码!");}/*** 测试八:修改账户密码失败-新密码为空并且密码输入不一致*/public void updatePasswordFile2() throws IOException, InterruptedException {//刷新driver.navigate().refresh();//点击“安全设置”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.leftMenu___179-W > ul > li:nth-child(2) > span")).click();//点击“修改”按钮driver.findElement(By.cssSelector("#sk-layout > div > div > section > div.ant-pro-layout-container > main > div > div > div > div.right___2jdGg > div.ant-list.ant-list-split > div > div > ul > li > ul > li")).click();//输入旧密码driver.findElement(By.cssSelector("#oldPassword")).sendKeys("111111");//输入确认密码driver.findElement(By.cssSelector("#confirmPassword")).sendKeys("123456");//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());//点击“确认修改”按钮driver.findElement(By.cssSelector("body > div:nth-child(7) > div > div.ant-modal-wrap > div > div.ant-modal-content > div.ant-modal-footer > div > div > div:nth-child(2) > button")).click();Thread.sleep(1000);String str = driver.findElement(By.cssSelector("#password_help > div")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert str.equals("请输入密码!");Thread.sleep(1000);String str1 = driver.findElement(By.cssSelector("#confirmPassword_help > div")).getText();//屏幕截图ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());assert str1.equals("两次密码输入不一致");}
}
(十)、RunTests类
import common.Utils;
import tests.*;import java.io.IOException;public class RunTests {public static void main(String[] args) throws IOException, InterruptedException {//注册测试RegisterPage registerPage = new RegisterPage();registerPage.checkRegisterPageRight();registerPage.registerFail1();registerPage.registerFail2();registerPage.registerFail3();registerPage.registerFail4();registerPage.registerSuc();//登录测试LoginPage loginPage = new LoginPage();loginPage.checkLoginPageRight();loginPage.loginFile1();loginPage.loginFile2();loginPage.loginFile3();loginPage.loginFile4();loginPage.loginFile5();loginPage.loginSuc();//首页页面测试HomePage homePage = new HomePage();homePage.checkHomePageRight();//我的页面页面测试MyProjectPage myProjectPage = new MyProjectPage();myProjectPage.checkMyProjectPageRight();myProjectPage.createSurveyQuestionnaires();myProjectPage.createOnlineExams();//我的题库页面测试MyQuestionBankPage myQuestionBankPage = new MyQuestionBankPage();myQuestionBankPage.checkMyQuestionBankPageRight();myQuestionBankPage.createQuestionBank();myQuestionBankPage.reset();//模板广场页面测试TemplateSquarePage templateSquarePage = new TemplateSquarePage();templateSquarePage.checkTemplateSquarePageRight();templateSquarePage.addTemplate();templateSquarePage.searchTemplate();//个人设置页面测试PersonalSettingsPage personalSettingsPage = new PersonalSettingsPage();personalSettingsPage.checkPersonalSettingsPageRight();personalSettingsPage.updateInformationFile1();personalSettingsPage.updateInformationFile2();personalSettingsPage.updateInformationFile3();personalSettingsPage.updateInformationFile4();personalSettingsPage.submitBasicInformationSuc();personalSettingsPage.updatePassword();personalSettingsPage.updatePasswordFile1();personalSettingsPage.updatePasswordFile2();//退出Utils.quit();}}
六、性能测试
通过使用postman和jmeter工具进行性能测试
(一)、Postman进行测能测试
postman用于验证接口功能的正确性。

(二)、jmeter进行性能测试
jmeter用于高并发场景下系统稳定性验证。

1、注册




2、登录




3、首页
1)currentUser




2)userOverview




3)listUserTask




4、我的项目




5、我的练习
1)practiceList




2)exerciseList




6、我的题库




7、问题管理




8、模板广场
1)listTag




2)listCategory




3)templateSquareList




9、用户管理
1)list




2)permissionList




3)userManagementList




(三)、聚合报告

(四)、TPS可视化
Transactions per Second:指系统每秒能成功处理的 “完整业务事务” 数量。
实时统计并展示 “每秒事务数。

(五)、响应时间可视化
Response Times Over Time,用于实时展示接口响应时间随测试时间的变化趋势。

(六)、活跃线程数可视化
Active Threads Over Time,用于实时展示测试过程中活跃线程数(并发用户数)随时间的变化趋势。

(七)、性能测试报告

1、Dashboard - 汇总展示核心性能指标




——————————————————————————

2、Over Time
“随时间变化” 的图表分类,用于展示指标随测试时间的波动情况。

3、Throughput
吞吐量图表,展示系统每秒处理的请求数,反映系统的处理能力。

4、Response Times
响应时间图表,展示接口的响应耗时统计,评估接口快慢。

七、Bug描述
(一)、我的项目页面
创建问卷/考试异常:没进行编辑,点击“保存”,显示保存成功


(二)、我的题库页面
“添加”按钮异常:未编辑文本 点击“添加”按钮,显示添加成功



(三)、模板广场页面
“搜模板”按钮异常:输入已存在的模板,点击“搜模板”按钮,显示暂无数据


(四)、用户管理页面
状态选择框异常:在新建用户的时候,未选择状态,点击“确定”按钮,创建用户成功并且显示激活状态


重置密码异常:输入原来的密码,点击“修改”按钮,显示修改成功


(五)、个人设置页面
修改密码成功,却没有跳转到登录页面进行登录


旧密码和新密码相同进行修改,显示修改成功



八、测试总结
问卷考试系统的主功能没有问题,可以在不同的浏览器、设备、操作系统中正常运行和使用。但有些地方需要优化比如:我的项目页面中“保存”按钮异常问题、我的题库页面中“文本导入”中的异常问题、模板广场页面中的“搜模板”按钮异常问题、用户管理页面新建用户中状态选择框、重置密码的异常问题以及个人设置页面的修改密码的异常问题。
问卷考试系统在性能测试中表现出良好的稳定性与响应效率:核心接口响应时间符合业务预期,吞吐量满足并发处理需求,且无异常请求,系统整体性能达标。

