文章目录
一. 项目简介
创思交流论坛系统是采用前后端分离的方式实现的,使用到的技术有:SpringBoot,SpringMVC,MyBatis,MySQL等,并将其部署到了云服务器上。
该系统旨在为用户提供一个基于 Web 的文章发布和讨论平台。用户可以进行注册登录、查看和修改个人信息,以及进行帖子的增删改查等基础操作。此外,系统还提供了评论、站内信等交流功能,用户可以对帖子进行点赞,并在帖子详情页上查看点赞数和阅读量等信息。
二. 测试环境
硬件:Lenovo Yoga 14S 2021(R7-5800H/16GB/512GB/集显)。
操作系统:Windows 11。
浏览器:Microsoft Edge版本 123.0.2420.81 (正式版本) (64 位)。
测试工具:黑盒测试,Selenium3 和 Junit5。
项目运行环境:CentOS7、maven、JDK1.8。
自动化脚本运行环境:IIntelliJ IDEA 2022.2.1。
三. 测试执行概况及功能测试
1. 手工测试
1.1. 手动编写测试用例
♨️功能测试用例:

♨️非功能测试用例:

1.2. 手动执行的部分测试用例
🍂🌸对注册页面进行的测试
1️⃣场景1:在输入部分注册信息时,由于信息不全,点击注册按钮后系统应该给出相应的提示。
🍁预期结果:页面提示部分信息不能为空。
🍁实际结果:系统确实给出了相应的提示,要求补全所有必填项,与预期一致。

2️⃣场景2:输入一个已经存在的用户名,并确保密码和确认密码一致,然后点击注册按钮。
🍁预期结果:系统应该提示用户该用户名已经存在。
🍁实际结果:系统确实给出了提示,提示用户该用户名已经存在,与预期结果一致。

3️⃣场景3:输入一个不存在的用户名,并且输入密码与确认密码不一致,然后点击注册按钮。
🍁预期结果:系统应该提示用户检查确认密码是否输入一致。
🍁实际结果:系统确实给出了相应的提示,指示用户检查确认密码,与预期结果一致。

4️⃣场景4:输入一个不存在的用户名,同时确保密码和确认密码一致,然后点击注册按钮。
🍁预期结果:系统应该显示注册成功,并跳转回登录界面。
🍁实际结果:系统确实显示了注册成功,并且跳转回了登录界面,符合预期。
🍂🌸对登录页面进行的测试
1️⃣场景1:输入一个已经存在的用户名,并确保密码输入正确,然后点击登录按钮。
🍁预期结果:系统应该显示登录成功,并跳转到论坛首页。
🍁实际结果:系统确实显示了登录成功,并且跳转到了论坛首页,与预期结果一致。 

2️⃣场景2:输入一个已经存在的用户名,并且输入错误的密码,然后点击登录按钮。
🍁预期结果:系统应该显示登录失败,并给出相应的错误提示。
🍁实际结果:系统确实显示了登录失败,并给出了错误提示,符合预期。

3️⃣场景3:输入一个不存在的用户名,然后点击登录按钮。
🍁预期结果:系统应该显示登录失败,并给出相应的错误提示。
🍁实际结果:系统确实显示了登录失败,并给出了错误提示,符合预期。

🍂🌸对首页进行的测试
1️⃣场景1:在未登录或登录过期的状态下,点击首页链接或手动输入首页地址。
🍁预期结果:系统应该自动跳转回登录界面,要求用户重新登录。
🍁实际结果:系统确实执行了跳转回登录界面的操作,与预期一致。
2️⃣场景2:在未登录状态下录或登录过期的状态下,点击首页中的任意一条帖子内容。
🍁预期结果:系统应该自动跳转回登录界面,要求用户重新登录。
🍁实际结果:系统确实执行了跳转回登录界面的操作,与预期一致。
3️⃣场景3:登录状态下,点击“首页”按钮。
🍁预期结果:应该显示导航栏中的所有版块名称,下方应显示所有帖子列表,并且右上方应该显示登录用户的信息。
🍁实际结果:系统确实展示了导航栏中的所有版块名称,下方显示了所有帖子列表,并且右上方显示了登录用户的信息,与预期一致。

4️⃣场景4:登录状态下,点击导航栏中的版块名“Java”。
🍁预期结果:系统应该展示 Java 版块的名称,该版块下的帖子数量,以及该版块下的所有帖子列表,并且右上方应该显示登录用户的信息。
🍁实际结果:系统确实展示了 Java 版块的名称和帖子数量,同时显示了该版块下的所有帖子列表,并且右上方也显示了登录用户的信息,与预期一致。

5️⃣场景5:登录状态下,在搜索框中输入关键字“多线程”进行搜索。
🍁预期结果:系统应该显示下方所有帖子正文中包含关键字“多线程”的帖子。
🍁实际结果:由于项目目前未实现搜索功能,实际结果是刷新回到首页界面,与预期不符。
6️⃣场景6:登录状态下,点击“月亮”按钮。
🍁预期结果:系统应该进入夜间模式的切换。
🍁实际结果:系统确实执行了夜间模式的切换操作,与预期一致。

7️⃣场景7:登录状态下,点击“发布帖子”按钮。
🍁预期结果:系统应该进入帖子编辑页面,且版块名默认选择 Java。
🍁实际结果:系统确实进入了帖子编辑页面,并且版块名默认选择了 Java,符合预期。

🍂🌸对编辑页面进行的测试
1️⃣场景1:未登录状态下(登录过期),尝试进入编辑页面。
🍁预期结果:系统应该自动跳转回登录界面,要求用户重新登录。
🍁实际结果:系统确实执行了跳转回登录界面的操作,与预期一致。
2️⃣场景2:在登录状态下,发布帖子时不输入帖子标题,只输入帖子内容,然后点击发布按钮。
🍁预期结果:系统应该给出提示,要求用户输入帖子标题。
🍁实际结果:系统确实给出了提示,要求用户输入帖子标题,与预期一致。

3️⃣场景3:登录状态下,输入了帖子标题但没有输入帖子内容,然后点击发布按钮。
🍁预期结果:系统应该给出提示,要求用户输入帖子内容。
🍁实际结果:系统确实给出了提示,要求用户输入帖子内容,与预期一致。

4️⃣场景4:登录状态下,输入了帖子标题和帖子内容,然后点击发布按钮。
🍁预期结果:系统应该成功编辑帖子,并跳转回首页,最上方应该显示刚发布的帖子信息。
🍁实际结果:系统确实执行了编辑成功的操作,跳转回了首页,并在最上方显示了刚发布的帖子信息,与预期一致。


🍂🌸对帖子详情页面进行的测试
1️⃣场景1:未登录或者登录过期的状态下,点击首页中的任意一条帖子内容。
🍁预期结果:系统应该自动跳转回登录界面,要求用户重新登录。
🍁实际结果:系统确实执行了跳转回登录界面的操作,与预期一致。
2️⃣场景2:登录状态下,点击首页中的一条帖子内容,例如“设计模式之单例模式(懒汉, 饿汉)”。
🍁预期结果:系统应该跳转到该帖子的详情页面。
🍁实际结果:系统确实跳转到了该帖子的详情页面,与预期一致。

3️⃣场景3:登录状态下,点击首页中的一条帖子内容,“不良人”(帖子作者“创客001”,当前登录作者“梧桐”)。
🍁预期结果:系统应该跳转到该帖子的详情页面,最上方应该显示该帖子的信息,左侧应该显示帖子作者的信息,下方应该显示该帖子的内容,而下方应该只显示点赞按钮。
🍁实际结果:系统确实展示了预期的内容,包括帖子信息、作者信息、帖子内容以及点赞按钮,与预期一致。


4️⃣场景4:登录状态下,点击帖子详情页面上的点赞按钮。
🍁预期结果:应该看到上方显示的点赞数加1。
🍁实际结果:系统确实执行了点赞操作,上方显示的点赞数加1,与预期一致。

5️⃣场景5:登录状态下,点击首页中的一条帖子内容,“123”(帖子作者“梧桐”,当前登录作者“梧桐”)。
🍁预期结果:系统应该跳转到该帖子的详情页面,最上方应该显示该帖子的信息,左侧应该显示帖子作者的信息,下方应该显示该帖子的内容,而下方应该显示点赞按钮、删除按钮和编辑按钮。
🍁实际结果:系统确实展示了预期的内容,包括帖子信息、作者信息、帖子内容以及点赞按钮、删除按钮和编辑按钮,与预期一致。


6️⃣场景6:登录状态下,点击首页中的一条帖子内容“不良人”,然后观察帖子信息中的访问数变化。
🍁预期结果:系统应该跳转到该帖子的详情页面,最上方应该显示帖子信息中的访问数+1。
🍁实际结果:系统确实执行了跳转到帖子详情页面的操作,并且观察到帖子信息中的访问数确实增加了1,与预期一致。
7️⃣场景7:登录状态下,点击发私信按钮(当前登录用户“梧桐”,给“创客001”发),然后不输入文本内容,直接点击“发送”按钮。
🍁预期结果:系统应该给出警告提示,要求用户输入要发送的内容。
🍁实际结果:系统确实给出了警告提示,要求用户输入要发送的内容,与预期一致。


8️⃣场景8:登录状态下,点击发私信按钮(当前登录用户“梧桐”,给“创客001”发私信),然后输入文本内容,最后点击“发送”按钮。
🍁预期结果:系统应该给出成功提示,提示私信发送成功。
🍁实际结果:系统确实给出了成功提示,显示私信发送成功,与预期一致。


9️⃣场景9:登录状态下,在下方的评论框中不输入文本内容,然后点击“回复”按钮。
🍁预期结果:系统应该给出警告提示,提示用户输入回复内容。
🍁实际结果:系统确实给出了警告提示,要求用户输入回复内容,与预期一致。

🔟场景10:登录状态下,在下方的回复框中输入文本内容,然后点击“回复”按钮。
🍁预期结果:系统应该给出成功提示,同时在下方显示评论内容,并清空回复框中的内容。
🍁实际结果:系统确实成功进行了评论,但回复框中的内容并没有被清空,与预期不符。可能是系统功能上的一处小问题。

🍂🌸对个人中心页面进行的测试
1️⃣场景1:登录状态下,点击“我的帖子”按钮。
🍁预期结果:系统应该显示下方所有属于该登录用户的帖子信息。
🍁实际结果:系统确实展示了预期的结果,显示了属于该登录用户的所有帖子信息,与预期一致。


2️⃣场景2:登录状态下,先发布新贴,然后点击“我的帖子”按钮,查看发帖子数。
🍁预期结果:系统应该即时更新,下方显示该登录用户的所有帖子的数量应该和上方显示的发帖数一致。
🍁实际结果:发帖数并没有即时更新,可能是系统在更新发帖数方面存在延迟或者需要手动刷新页面才能更新,与预期不符。(进而想到删除帖子,也有这个问题)。



3️⃣场景3:登录状态下,点击“个人中心”按钮。
🍁预期结果:系统应该显示下方该登录用户的个人信息。
🍁实际结果:系统确实展示了预期的结果,显示了该登录用户的个人信息,与预期一致。


4️⃣场景4:登录状态下,尝试进行修改头像操作。
🍁预期结果:应该打开电脑,上传本地图片,然后点击修改头像按钮成功修改。
🍁实际结果:虽然上传本地图片成功,但点击修改头像按钮时没有反应,与预期不符。(项目目前未实现修改头像)。
5️⃣场景5:登录状态下,尝试进行修改昵称操作。
🍁预期结果:应该输入修改后的昵称,并且修改成功后页面能够刷新,显示新的昵称。
🍁实际结果:系统确实执行了修改昵称的操作,并且修改成功后页面进行了刷新,显示了新的昵称,与预期一致。
6️⃣场景6:登录状态下,尝试进行修改密码操作:输入的原密码错误,但新密码和确认密码一致,然后点击修改密码按钮。
🍁预期结果:系统应该给出警告提示,提示参数校验失败。
🍁实际结果:系统确实给出了警告提示,提示参数校验失败,与预期一致。

7️⃣场景7:登录状态下,尝试进行修改密码操作:输入的原密码正确,但新密码和确认密码不一致,然后点击修改密码按钮。
🍁预期结果:系统应该给出警告提示,提示两次输入的密码不一致。
🍁实际结果:系统确实给出了警告提示,提示两次输入的密码不一致,与预期一致。

8️⃣场景8:登录状态下,尝试进行修改密码操作:输入的原密码正确,新密码和确认密码一致,然后点击修改密码按钮。
🍁预期结果:系统应该跳转回登录界面,并要求用户重新登录。
🍁实际结果:系统确实执行了跳转回登录界面的操作,并要求用户重新登录,与预期一致。
1.3. 上述手工测试发现的bug
- 1️⃣在给帖子进行评论时,尽管评论可以成功发布,但是评论输入框中的内容并没有自动清空。
- 2️⃣个人中心的发帖数量更新不及时,即使在登录状态下发布新帖子或者删除旧帖子,个人中心页面刷新几次后仍然显示相同的帖子数量,需要退出登录并重新登录才能正常更新显示。
- 3️⃣在编辑界面中,编辑器有时加载不完全,导致无法进行编辑操作,需要手动刷新页面才能解决该问题。
2. 自动化测试
2.1. 初始化工具类
🍂这部分代码是为了在测试过程中初始化和关闭浏览器驱动,并提供了截图功能来记录测试执行的结果。
提供了以下功能:
- 在测试开始前(BeforeAll),通过 Selenium WebDriver 初始化浏览器驱动(EdgeDriver)。
- 在测试结束后(AfterAll),关闭已打开的浏览器驱动。
- 获取当前时间戳的方法(getTime),用于创建文件夹和保存截图时使用。
- 获取屏幕截图并保存的方法(getScreenShot),根据时间戳生成文件名并将截图保存到指定路径。
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
public class InitAndEnd {
static WebDriver webDriver;
@BeforeAll
static void SetUp() {
//创建一个驱动对象来打开浏览器
System.setProperty("webdriver.edge.driver", "C:\\Program Files\\Java\\jdk1.8.0_192\\bin\\msedgedriver.exe");
webDriver = new EdgeDriver();
}
@AfterAll
static void TearDown() {
// 关闭 Web 驱动
webDriver.quit();
}
// 获取当前时间戳将截图按照时间保存
public List<String> getTime() {
// 文件夹以当天日期保存
// 截图以当天日期-时间保存
SimpleDateFormat sim1 = new SimpleDateFormat("yyyyMMdd");
SimpleDateFormat sim2 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");
String dirname = sim1.format(System.currentTimeMillis());
String filename = sim2.format(System.currentTimeMillis());
List<String> list = new ArrayList<>();
list.add(dirname);
list.add(filename);
return list;
}
// 获取屏幕截图,把所有的用例执行的结果保存下来
public void getScreenShot(String str) throws IOException {
List<String> list = getTime();
String filename = "D:\\bit\\software_testing\\software-testing\\test-forum\\src\\main\\java\\com\\forum\\test" + list.get(0) + "\\" + str + "_" + list.get(1) + ".png";
File srcfile = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);
// 把屏幕截图生成的文件放到指定的路径
FileUtils.copyFile(srcfile, new File(filename));
}
}
2.2. 注册页面测试
2.2.1. 验证注册成功的情况
🍂场景1:注册用户名在数据库中不存在,昵称正常输入,两次密码输入一致,执行注册操作后,预期注册成功并跳转回登录页面。
具体流程如下:
- 使用 WebDriver 打开登录页面。
- 点击页面中的注册按钮,跳转到注册页面。
- 输入不存在于数据库中的用户名 “zhangsan”、昵称 “张三”,并输入两次相同的密码 “123”。
- 勾选同意协议复选框。
- 点击注册按钮进行注册。
- 等待页面跳转,然后获取当前页面的 URL。
- 判断页面跳转后的 URL 是否是预期的登录页面的 URL。
- 如果跳转成功,断言注册成功,并输出注册成功的信息。
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.By;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class RegCases extends InitAndEnd {
/**
* 场景1:不存在的用户名,昵称,两次密码一致
*/
@Order(1)
@ParameterizedTest
@CsvSource({"zhangsan, 张三, 123, 123"})
void regSuccess(String username, String nickname, String password, String againpassword) throws InterruptedException, IOException {
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
// 找到注册按钮点击跳转
webDriver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.text-muted.mt-3 > a")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入昵称
webDriver.findElement(By.cssSelector("#nickname")).sendKeys(nickname);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入确认密码
webDriver.findElement(By.cssSelector("#passwordRepeat")).sendKeys(againpassword);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击同意协议复选框
webDriver.findElement(By.cssSelector("#policy")).click();
// 点击注册按钮
webDriver.findElement(By.cssSelector("#submit")).click();
Thread.sleep(1000); // 显示等待
// 注册成功之后,判断是否会跳转回登录界面
String expect = "http://47.113.217.156:58080/sign-in.html";
String actual = webDriver.getCurrentUrl();
webDriver.manage().timeouts().implicitlyWait(300, TimeUnit.MINUTES);
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(expect, actual);
System.out.println("注册成功, 测试结果");
}
}

2.2.2. 验证注册失败的情况
🍂场景2:用户名已存在于数据库中,但昵称和两次输入的密码仍然符合要求,执行注册操作后,预期注册失败并停留在注册页面。
具体流程如下:
- 使用 WebDriver 打开登录页面。
- 点击页面中的注册按钮,跳转到注册页面。
- 输入已存在于数据库中的用户名 “wutong”、昵称 “梧桐”,并输入两次相同的密码 “123”。
- 勾选同意协议复选框。
- 点击注册按钮进行注册。
- 等待页面响应,获取当前页面的 URL。
- 判断页面是否停留在注册页面,即当前页面的 URL 是否是预期的注册页面的 URL。
- 如果停留在注册页面,断言注册失败,并输出注册失败的信息。
/**
* 场景2:用户名已存在,昵称,两次密码一致
*/
@Order(2)
@ParameterizedTest
@CsvSource({"wutong, 梧桐, 123, 123"})
void regFail(String username, String nickname, String password, String againpassword) throws InterruptedException, IOException {
// 打开注册页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
// 找到注册按钮点击跳转
webDriver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.text-muted.mt-3 > a")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入昵称
webDriver.findElement(By.cssSelector("#nickname")).sendKeys(nickname);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入确认密码
webDriver.findElement(By.cssSelector("#passwordRepeat")).sendKeys(againpassword);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//点击同意协议复选框
webDriver.findElement(By.cssSelector("#policy")).click();
// 点击注册按钮
webDriver.findElement(By.cssSelector("#submit")).click();
Thread.sleep(1000); // 显示等待
// 注册失败,页面没有跳转,还停留在注册页面
String expect = "http://47.113.217.156:58080/sign-up.html";
String actual = webDriver.getCurrentUrl();
webDriver.manage().timeouts().implicitlyWait(300, TimeUnit.MINUTES);
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(expect, actual);
System.out.println("注册失败, 测试通过");
}

2.3. 登录界面测试
2.3.1. 登录失败测试
🍂场景1:用户名正确但密码错误,执行登录操作后,预期登录失败并出现警告提示。
具体流程如下:
- 使用 WebDriver 打开论坛的登录页面。
- 输入正确的用户名 “admin” 和错误的密码 “123”。
- 点击登录按钮进行登录操作。
- 等待页面响应并获取警告提示的文本内容。
- 验证警告提示内容是否与预期一致。
- 截图保存测试结果。
- 断言警告提示内容与预期是否一致,输出警告提示内容。
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.*;
import org.openqa.selenium.By;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static java.lang.Thread.sleep;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class ForumCases extends InitAndEnd {
/**
* 场景1:用户名正确,密码错误,登录失败
*/
@Order(1)
@ParameterizedTest
@CsvSource(value = "amdin, 123")
void LoginAbnormal(String username, String password) throws InterruptedException, IOException {
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(300);
// 登录失败,出现警告提示
// 验证提示内容
String msg = webDriver.findElement(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div")).getText();
String except = " ×\n警告\n用户名或密码错误";
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(except, msg);
System.out.println(msg);
}
}

2.3.2. 登录成功测试
🍂场景2:用户名和密码都正确,执行登录操作后,预期登录成功并跳转到系统主页。
具体流程如下:
- 使用 WebDriver 打开论坛的登录页面。
- 从外部 CSV 文件中读取用户名和密码数据,例如 “wutong, 123456”。
- 输入正确的用户名和密码。
- 点击登录按钮进行登录操作。
- 等待页面响应并获取当前页面的 URL。
- 验证当前页面的 URL 是否是预期的系统主页的 URL。
- 截图保存测试结果。
- 断言当前页面的 URL 是否与预期的系统主页的 URL 一致,确保登录成功后跳转到系统主页。
- 测试完成后,使用 WebDriver 的
navigate().back()方法返回到登录界面,准备进行下一组账号的测试。
/**
* 场景2:用户名和密码都正确,登录成功
*/
@Order(2)
@ParameterizedTest
@CsvFileSource(resources = "LoginSuccess.csv") // wutong, 123456
void LoginSuccess(String username, String password) throws InterruptedException, IOException {
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
Thread.sleep(1000);
// 登录成功,进入系统主页
// 验证主页 url
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName); // 截图保存测试结果
String expect = "http://47.113.217.156:58080/index.html";
String actual = webDriver.getCurrentUrl();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
Assertions.assertEquals(expect, actual); // 查看当前的url是否在博客详情页面
// 适应多个组账号的测试,当一个账号测完之后,回退到登录界面
webDriver.navigate().back();
}

2.4. 显示帖子列表测试
2.4.1. 未登录状态下测试
🍂场景1:未登录状态下,直接通过 URL 访问主页帖子列表,预期返回登录页面。
具体流程如下:
- 使用 WebDriver 直接访问论坛的主页列表页面。
- 获取当前页面的 URL。
- 验证当前页面的 URL 是否是预期的登录页面的 URL。
- 截图保存测试结果。
- 断言当前页面的 URL 是否与预期的登录页面的 URL 一致,确保未登录状态下访问主页列表会被重定向到登录页面。
/**
* 场景1:未登录状态下,访问主页列表,预期返回登录页面
*/
@Order(3)
@Test
void BlogList1() throws InterruptedException, IOException {
// 未登录,直接通过url访问主页帖子列表
webDriver.get("http://47.113.217.156:58080/index.html");
// 获取当前的url地址
String expect = "http://47.113.217.156:58080/sign-in.html";
String actual = webDriver.getCurrentUrl();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
// 判断是否跳转到登录界面
Assertions.assertEquals(expect, actual);
}
未登录,直接跳转回登录界面。
2.4.2. 登录状态下测试
🍂场景2:登录状态下,进入论坛首页,验证页面是否正确显示帖子相关的控件信息。
具体流程如下:
- 使用 WebDriver 进行登录操作,输入用户名和密码并点击登录按钮。
- 等待页面响应,并验证页面的导航栏是否显示了 “首页” 文本。
- 截图保存测试结果。
- 断言导航栏中是否包含 “首页” 文本,确保页面正确显示了导航栏信息。
- 查看是否有发布帖子的按钮,并点击该按钮。
- 等待页面响应,查看是否跳转到了帖子编辑页面,并验证页面是否包含 “发新贴” 文本。
- 截图保存测试结果。
- 断言页面是否包含 “发新贴” 文本,确保跳转到了帖子编辑页面。
/**
* 场景2:登录状态下,进入论坛首页,是否正确显示帖子相应的控件信息
*/
@Order(4)
@ParameterizedTest
@CsvSource(value = "wutong, 123456")
void BlogList2(String username, String password) throws InterruptedException, IOException {
// 1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 2-进入论坛首页,查看页面的文本内容显示是否正确
String expect1 = "首页";
String actual1 = webDriver.findElement(By.cssSelector("#nav_board_index > a > span.nav-link-title")).getText();
Thread.sleep(10000);
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(expect1, actual1); // 断言
// 3-查看是否有发布帖子按钮,并点击
webDriver.findElement(By.cssSelector("#bit-forum-content > div.page-header.d-print-none > div > div > div.col-auto.ms-auto.d-print-none > div > a.btn.btn-primary.d-none.d-sm-inline-block.article_post")).click();
Thread.sleep(1000);
// 查看是否跳转到帖子编辑页面(验证是否有发新贴文本)
String expect2 = "发新贴";
String actual2 = webDriver.findElement(By.cssSelector("#bit-forum-content > div.page-header.d-print-none > div > div > div > h2")).getText();
// 截图保存测试结果
String methodName2 = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName2);
Assertions.assertEquals(expect2, actual2); // 断言
System.out.println("跳转到了编辑帖子页面");
}


2.5. 发布帖子测试
2.5.1. 登录后测试标题和内容其中一个为空
🍂场景1:登录后,点击发布帖子,进入编辑页分别 输入帖子标题但不输入帖子内容 和 不输入帖子标题但输入帖子内容,分别点击发布按钮,测试这两种情况能否成功发布。
具体流程如下:
🍁场景1):登录状态下,测试标题和内容其中一个为空时,发布帖子失败并出现相应提示。
- 打开登录页面,输入用户名和密码进行登录。
- 点击发布帖子按钮,进入帖子编辑页面。
- 第一个场景中,只输入标题而不输入内容,点击发布按钮。
- 验证发布失败后页面出现的提示信息是否为 “请输入帖子内容”。
- 截图保存测试结果并断言提示信息是否符合预期。
🍁场景2):不输入标题,只输入内容时,发布帖子失败并出现相应提示。
- 清空标题输入框内容。
- 编辑帖子内容,因为使用了第三方md插件,不能直接通过sendkeys输入内容,通过模拟点击事件插入内容。
- 点击发布按钮。
- 验证发布失败后页面出现的提示信息是否为 “请输入帖子标题”。
- 截图保存测试结果并断言提示信息是否符合预期。
// 发布帖子测试
/**
* 场景1:登录状态下,测试标题和内容其中一个为空
*/
@Order(5)
@ParameterizedTest
@CsvSource(value = "wutong, 123456")
void WriteBlog1(String username, String password) throws InterruptedException, IOException {
// 1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 2-点击 发布帖子 按钮,进入帖子编辑页面
webDriver.findElement(By.cssSelector("#bit-forum-content > div.page-header.d-print-none > div > div > div.col-auto.ms-auto.d-print-none > div > a.btn.btn-primary.d-none.d-sm-inline-block.article_post")).click();
// 1)只输入标题,不输入内容
webDriver.findElement(By.cssSelector("#article_post_title")).sendKeys("测试只输入标题");
Thread.sleep(6000);
//点击发布按钮
// webDriver.findElement(By.cssSelector("#article_post_submit")).click();
// 使用 Actions 类可以模拟鼠标操作
WebElement element = webDriver.findElement(By.cssSelector("#article_post_submit"));
Actions actions = new Actions(webDriver);
actions.moveToElement(element).click().perform();
Thread.sleep(1000);
// 发布失败,出现提示
// 验证提示内容
String msg = webDriver.findElement(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div")).getText();
String except = "×\n提示\n请输入帖子内容";
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(except, msg);
System.out.println(msg);
// 场景2:不输入标题,只输入内容
// 清空标题
webDriver.findElement(By.cssSelector("#article_post_title")).clear();
// 编辑帖子内容,因为项目中使用的是第三方的md插件,所以不能直接通过sendkeys来输入内容
// 但我们可以通过click点击事件,往模块内容中插入横线等,这是插件本身提供的元素功能
webDriver.findElement(By.cssSelector("#edit-article > div.editormd-toolbar > div > ul > li:nth-child(21) > a > i")).click();
Thread.sleep(10000); // 等待页面响应
// 点击发布按钮
// webDriver.findElement(By.cssSelector("#article_post_submit")).click();
actions.moveToElement(element).click().perform();
Thread.sleep(1000);
// 发布失败,出现提示
// 验证提示内容
String msg2 = webDriver.findElement(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div")).getText();
String except2 = "×\n提示\n请输入帖子标题";
// 截图保存测试结果
String methodName2= Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName2);
Assertions.assertEquals(except2, msg2);
System.out.println(msg2);
}


2.5.2. 登录后测试标题和内容都不为空
🍂场景2:登录后,点击发布帖子,进入编辑页输入帖子标题帖子内容,预期能够成功发布。
具体流程如下:
- 打开登录页面,输入用户名和密码进行登录。
- 点击发布帖子按钮,进入帖子编辑页面。
- 输入标题和内容,这里测试输入的标题为 “测试发布”。
- 点击发布按钮。
- 等待页面响应,验证发布成功后是否跳转到首页,并查看首页的帖子列表中是否包含刚发布的标题 “测试发布”。
- 截图保存测试结果并断言首页帖子列表中是否包含期望的标题。
/**
* 场景2:登录状态下,测试标题和内容都不为空
*/
@Order(6)
@ParameterizedTest
@CsvSource(value = "wutong, 123456")
void WriteBlog2(String username, String password) throws InterruptedException, IOException {
// 1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 2-点击 发布帖子 按钮,进入帖子编辑页面
webDriver.findElement(By.cssSelector("#bit-forum-content > div.page-header.d-print-none > div > div > div.col-auto.ms-auto.d-print-none > div > a.btn.btn-primary.d-none.d-sm-inline-block.article_post")).click();
// 3-输入标题和内容
webDriver.findElement(By.cssSelector("#article_post_title")).sendKeys("测试发布");
Thread.sleep(6000);
webDriver.findElement(By.cssSelector("#edit-article > div.editormd-toolbar > div > ul > li:nth-child(21) > a > i")).click();
Thread.sleep(1000);
//点击发布按钮
// webDriver.findElement(By.cssSelector("#article_post_submit")).click();
// 使用 Actions 类可以模拟鼠标操作
WebElement element = webDriver.findElement(By.cssSelector("#article_post_submit"));
Actions actions = new Actions(webDriver);
actions.moveToElement(element).click().perform();
Thread.sleep(6000);
// 4-发布成功,跳转到首页,验证列表的第一帖子
String msg = webDriver.findElement(By.cssSelector("#artical-items-body > div:nth-child(1) > div > div.col > div.text-truncate > a > strong")).getText();
String except = "测试发布";
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(except, msg);
System.out.println(msg);
}

2.6. 查询帖子内容测试
🍂场景1:登录后,查看帖子内容,分别查看 帖子作者和当前登录用户一致 和 不一致 的帖子,是否正确显示对应帖子的信息。
具体流程如下:
- 点击帖子标题为“不良人”的帖子,验证帖子标题是否正确,是否有点赞按钮,并截图保存测试结果。
- 点击帖子标题为“与风行”的帖子,验证帖子标题是否正确,是否有点赞按钮、编辑按钮和删除按钮,并截图保存测试结果。
// 查询帖子测试
/**
* 场景1:登录状态下,进入帖子详情页,是否正确显示对应帖子的信息
*/
@Order(7)
@ParameterizedTest
@CsvSource(value = "wutong, 123456")
void BlogSearch(String username, String password) throws InterruptedException, IOException {
//1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
// 1):点击帖子内容“不良人“,博客作者与登录作者不一致,只显示点赞按钮
webDriver.findElement(By.cssSelector("#artical-items-body > div:nth-child(4) > div > div.col > div.text-truncate > a > strong")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
Thread.sleep(5000);
// 看帖子详情页 帖子标题 是否准确, 是否有点赞按钮
String expect = "不良人";
String act = webDriver.findElement(By.cssSelector("#details_article_content_title")).getText();
String expect2 = "点赞";
String act2 = webDriver.findElement(By.cssSelector("#details_btn_like_count")).getText();
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(expect, act);
Assertions.assertEquals(expect2, act2);
// 帖子内容
System.out.println(webDriver.findElement(By.cssSelector("#h1-u59ECu5982u96EAu548Cu674Eu661Fu4E91")).getText());
// 帖子作者
System.out.println(webDriver.findElement(By.cssSelector("#article_details_author_name")).getText());
// 点击回到首页
webDriver.findElement(By.cssSelector("#nav_board_index > a > span.nav-link-title")).click();
// 2):点击帖子内容“与风行”,帖子作者与登录用户一致,显示点赞按钮,编辑按钮,删除按钮
webDriver.findElement(By.cssSelector("#artical-items-body > div:nth-child(3) > div > div.col > div.text-truncate > a > strong")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
Thread.sleep(5000);
// 看帖子详情页 帖子标题 是否准确, 是否有 点赞,编辑,删除 按钮
String expect3 = "与风行";
String act3 = webDriver.findElement(By.cssSelector("#details_article_content_title")).getText();
String expect4 = "点赞";
String act4 = webDriver.findElement(By.cssSelector("#details_btn_like_count")).getText();
String expect5 = "编辑";
String act5 = webDriver.findElement(By.cssSelector("#details_artile_edit > span")).getText();
String expect6 = "删除";
String act6 = webDriver.findElement(By.cssSelector("#bit-forum-content > div.page-body > div > div > div:nth-child(1) > div.col-9.card.card-lg > div.card-footer.bg-transparent.mt-auto.justify-content-end > div > div:nth-child(3) > div > a > span")).getText();
// 截图保存测试结果
String methodName2 = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName2);
Assertions.assertEquals(expect3, act3);
Assertions.assertEquals(expect4, act4);
Assertions.assertEquals(expect5, act5);
Assertions.assertEquals(expect6, act6);
// 帖子内容
System.out.println(webDriver.findElement(By.cssSelector("#details_article_content > p")).getText());
// 帖子作者
System.out.println(webDriver.findElement(By.cssSelector("#article_details_author_name")).getText());
}
登录状态下,登录用户与帖子作者不一致,获取到了帖子标题,帖子内容,帖子作者,点赞按钮。
登录状态下,登录用户与帖子作者一致,获取到了帖子标题,帖子内容,帖子作者,点赞、编辑、删除三个按钮。


2.7. 编辑修改帖子测试
🍂场景1:登录状态下,修改登录用户自己的帖子,修改标题和内容,重新发布,重新查看帖子内容看是否更新。
具体流程如下:
- 登录并点击帖子标题为“与风行”的帖子,进入帖子详情页。
- 点击编辑按钮,跳转到编辑页面。
- 清空原标题,更新标题为“与凤行”,同时添加样式表示修改。
- 点击提交按钮,保存修改并跳转到主页。
- 验证帖子列表中相应帖子的标题是否已更新为“与凤行”。
// 编辑修改帖子测试
/**
* 场景1:登录状态下,修改登录用户自己的帖子,修改标题和内容,重新发布
*/
@Order(8)
@ParameterizedTest
@CsvSource(value = "wutong, 123456")
void BlogUpdate(String username, String password) throws InterruptedException, IOException {
//1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
// 2):点击帖子内容“与风行”
webDriver.findElement(By.cssSelector("#artical-items-body > div:nth-child(3) > div > div.col > div.text-truncate > a > strong")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 点击编辑按钮,跳转到编辑页
webDriver.findElement(By.cssSelector("#details_artile_edit > span")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 清空标题
webDriver.findElement(By.cssSelector("#edit_article_title")).clear();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
webDriver.findElement(By.cssSelector("#edit_article_title")).clear();
// 更新标题为“与凤行”
webDriver.findElement(By.cssSelector("#edit_article_title")).sendKeys("与凤行");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 正文加点样式表示修改
webDriver.findElement(By.cssSelector("#edit_article_content_area > div.editormd-toolbar > div > ul > li:nth-child(7) > a > i")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
webDriver.findElement(By.cssSelector("#edit_article_content_area > div.editormd-toolbar > div > ul > li:nth-child(7) > a > i")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
webDriver.findElement(By.cssSelector("#edit_article_content_area > div.editormd-toolbar > div > ul > li:nth-child(7) > a > i")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
//点击提交按钮
WebElement element = webDriver.findElement(By.cssSelector("#edit_article_submit"));
Actions actions = new Actions(webDriver);
actions.moveToElement(element).click().perform();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 修改提交后跳转到主页
// 检查标题是否更新
Thread.sleep(5000);
String expect = "与凤行";
String act = webDriver.findElement(By.cssSelector("#artical-items-body > div:nth-child(3) > div > div.col > div.text-truncate > a > strong")).getText();
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(expect, act);
}
修改前:

修改后:

2.8. 删除帖子测试
🍂场景1:登录状态下,进入帖子详情页,点击删除按钮,删除帖子成功,成功跳转回帖子列表页面。
具体流程如下:
- 登录并点击第一个帖子标题为“测试发布”的帖子,进入帖子详情页。
- 在帖子详情页点击删除按钮,弹出删除确认弹窗。
- 点击确定按钮,确认删除帖子。
- 验证帖子列表中第一条帖子标题是否已更新为其他值(比如"1111")。
// 删除帖子测试
/**
* 场景1:登录状态下,进入帖子详情页,点击删除按钮并删除
*/
@Order(9)
@ParameterizedTest
@CsvSource(value = "wutong, 123456")
void BlogDelete(String username, String password) throws InterruptedException, IOException {
//1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 2-点击第一个帖子“测试发布”
webDriver.findElement(By.cssSelector("#artical-items-body > div:nth-child(1) > div > div.col > div.text-truncate > a > strong")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 3-跳转到帖子详情页,点击删除按钮
webDriver.findElement(By.cssSelector("#bit-forum-content > div.page-body > div > div > div:nth-child(1) > div.col-9.card.card-lg > div.card-footer.bg-transparent.mt-auto.justify-content-end > div > div:nth-child(3) > div > a")).click();
Thread.sleep(3000);
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
// 4-处理弹窗 点击确定
webDriver.findElement(By.cssSelector("#details_artile_delete")).click();
Thread.sleep(5000);
// 5-验证删除后的第一条帖子
String expect = "1111";
String act = webDriver.findElement(By.cssSelector("#artical-items-body > div:nth-child(1) > div > div.col > div.text-truncate > a > strong")).getText();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 截图保存测试结果
String methodName2 = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName2);
Assertions.assertEquals(expect, act);
System.out.println("帖子删除成功");
}


2.9. 我的帖子查询测试
🍂场景1:登录状态下,进入主页,点击我的帖子,跳转到个人中心页面,显示用户昵称等信息。
具体流程如下:
- 登录并点击头像,进入个人中心查看选项。
- 点击我的帖子。
- 验证我的帖子详情页面中用户昵称是否准确显示(例如,验证昵称是否为"梧桐")。
// 我的帖子查询测试
/**
* 场景1:登录状态下,进入博客列表页,点击头像,再点击我的帖子,跳转到个人中心页面
*/
@Order(10)
@ParameterizedTest
@CsvSource(value = "wutong, 123456")
void MyBlog(String username, String password) throws InterruptedException, IOException {
// 1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 2-点击头像,再点击我的帖子,跳转到个人中心页面
webDriver.findElement(By.cssSelector("#index_nav_avatar")).click();
Thread.sleep(1000);
webDriver.findElement(By.cssSelector("#index_user_profile")).click();
Thread.sleep(5000);
// 校验是否有用户昵称 是否 准确
String expect = "梧桐";
String act = webDriver.findElement(By.cssSelector("#profile_nickname")).getText();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 截图保存测试结果
String methodName2 = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName2);
Assertions.assertEquals(expect, act);
}

2.10. 点赞测试
🍂场景1:登录状态下,进入帖子详情页,点击点赞按钮,验证点赞数是否相应增加。
具体流程如下:
- 登录并进入帖子详情页。
- 获取点赞前的点赞数。
- 点击点赞按钮。
- 获取点赞后的点赞数。
- 验证点赞后的点赞数是否等于点赞前的点赞数加一。
// 点赞测试
/**
* 场景1:登录状态下,进入帖子详情页,点击点赞按钮,验证点赞数是否相应增加
*/
@Order(11)
@ParameterizedTest
@CsvSource(value = "wutong, 123456")
void Like(String username, String password) throws InterruptedException, IOException {
// 1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 2-点击帖子内容“与凤行”,进入该帖内容页,找到点赞按钮并点击
webDriver.findElement(By.cssSelector("#artical-items-body > div:nth-child(2) > div > div.col > div.text-truncate > a > strong")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
Thread.sleep(3000);
// 获取点赞前的点赞数
String cur = webDriver.findElement(By.cssSelector("#details_article_likeCount")).getText();
// 点击点赞按钮
webDriver.findElement(By.cssSelector("#details_btn_like_count")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
Thread.sleep(3000);
// 获取点赞后的点赞数
String after = webDriver.findElement(By.cssSelector("#details_article_likeCount")).getText();
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
// 验证点赞数是否增加
Assertions.assertEquals(Integer.parseInt(cur) + 1, Integer.parseInt(after));
}
点赞前。

点赞后。

2.11. 个人信息页显示和修改相关测试
2.11.1. 登录后显示个人信息测试
🍂场景1:登录状态下,进入个人中心页面,验证个人信息是否正确显示
具体流程如下:
- 登录并进入个人中心页面。
- 获取页面上显示的用户昵称,并验证是否和预期一致。
- 获取页面上显示的“昵称”文本,并验证是否存在。
- 获取页面上显示的“邮箱地址”文本,并验证是否存在。
- 获取页面上显示的“电话号码”文本,并验证是否存在。
- 获取页面上显示的“修改密码”文本,并验证是否存在。
- 检查页面上是否显示“提交修改”按钮。
- 获取昵称修改框中的内容,并验证是否和预期一致。
@Order(12)
@ParameterizedTest
@CsvSource(value = "wutong, 123456")
void MyInformation(String username, String password) throws InterruptedException, IOException {
// 1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 2-点击头像,再点击个人中心,跳转到个人中心页面
webDriver.findElement(By.cssSelector("#index_nav_avatar")).click();
Thread.sleep(1000);
webDriver.findElement(By.cssSelector("#index_user_settings")).click();
Thread.sleep(3000);
//是否有用户昵称
String expect1 = "梧桐";
String actual1 = webDriver.findElement(By.cssSelector("#settings_nickname")).getText();
//是否有“昵称”这两个字
String expect2 = "昵称";
String actual2 = webDriver.findElement(By.cssSelector(" #bit-forum-content > div.page-body > div > div > div > div.col.d-flex.flex-column > div > h3:nth-child(4)")).getText();
//是否有“邮箱地址”这几个字
String expect3 = "邮箱地址";
String actual3 = webDriver.findElement(By.cssSelector(" #bit-forum-content > div.page-body > div > div > div > div.col.d-flex.flex-column > div > h3:nth-child(7)")).getText();
//是否有“电话号码”这几个字
String expect4 = "电话号码";
String actual4 = webDriver.findElement(By.cssSelector(" #bit-forum-content > div.page-body > div > div > div > div.col.d-flex.flex-column > div > h3:nth-child(10)")).getText();
//是否有“修改密码”这几个字
String expect5 = "修改密码";
String actual5 = webDriver.findElement(By.cssSelector(" #bit-forum-content > div.page-body > div > div > div > div.col.d-flex.flex-column > div > h3:nth-child(13)")).getText();
//是否有“提交修改”按钮#settings_input_passwordRepeat
boolean b = webDriver.findElement(By.cssSelector("#settings_submit_password")).isDisplayed();
// 获取昵称修改框中的内容
String expect6= "梧桐";
String actual6 = webDriver.findElement(By.cssSelector("#setting_input_nickname")).getAttribute("value");
Thread.sleep(3000);
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(expect1, actual1);
Assertions.assertEquals(expect2, actual2);
Assertions.assertEquals(expect3, actual3);
Assertions.assertEquals(expect4, actual4);
Assertions.assertEquals(expect5, actual5);
Assertions.assertTrue(b);
Assertions.assertEquals(expect6, actual6);
System.out.println("个人信息显示成功");
}

2.11.2. 登录后修改昵称测试
🍂场景2:登录后点击用户头像下的个人中心,输入新昵称并修改,获取新昵称观察是否显示成功。
具体流程如下:
- 登录并进入个人中心页面。
- 清除昵称文本框中的内容。
- 输入要修改的新昵称。
- 点击修改按钮。
- 获取修改后的昵称,并验证是否和预期一致。
/**
* 场景2:登录状态下在个人中心页面,修改昵称
*/
@Order(14)
@ParameterizedTest
@CsvSource(value = "wutong, 123456")
void ChangeNickname(String username, String password) throws InterruptedException, IOException {
// 1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 2-点击头像,再点击个人中心,跳转到个人中心页面
webDriver.findElement(By.cssSelector("#index_nav_avatar")).click();
Thread.sleep(1000);
webDriver.findElement(By.cssSelector("#index_user_settings")).click();
Thread.sleep(3000);
// 3-修改昵称
// 清除昵称的文本内容
webDriver.findElement(By.cssSelector("#setting_input_nickname")).clear();
// 输入要修改的新昵称
webDriver.findElement(By.cssSelector("#setting_input_nickname")).sendKeys("梧桐木");
//点击修改按钮
webDriver.findElement(By.cssSelector("#setting_submit_nickname")).click();
Thread.sleep(3000);
//再次获取昵称,判断是不是修改后的昵称名
String exceptNickName = "梧桐木";
String actualNickName = webDriver.findElement(By.cssSelector("#settings_nickname")).getText();
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(exceptNickName, actualNickName);
System.out.println("昵称修改成功!");
}
修改前。

修改后。

2.11.3. 登录后修改密码测试
🍂场景3:登录后点击用户头像下的个人中心,输入新密码并修改,其中两次密码一致,输入原密码也正确,观察是否跳转回登录界面。
具体流程如下:
- 登录并进入个人中心页面。
- 输入原密码、新密码和确认密码。
- 点击提交修改按钮。
- 验证修改密码后是否返回登录页面。
- 使用原密码登录,验证登录失败。
- 使用新密码登录,验证登录成功。
/**
* 场景3:登录状态下在个人中心页面,修改密码
*/
@Order(15)
@ParameterizedTest
@CsvSource(value = "wutong, 123456")
void ChangePassword(String username, String password) throws InterruptedException, IOException {
// 1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 2-点击头像,再点击个人中心,跳转到个人中心页面
webDriver.findElement(By.cssSelector("#index_nav_avatar")).click();
Thread.sleep(1000);
webDriver.findElement(By.cssSelector("#index_user_settings")).click();
Thread.sleep(3000);
// 3-修改密码
//4-修改密码:原密码 123456 正确,两次新密码 654321 也一致
//输入原密码
webDriver.findElement(By.cssSelector("#settings_input_oldPassword")).sendKeys("123456");
//输入新密码
webDriver.findElement(By.cssSelector("#settings_input_newPassword")).sendKeys("654321");
//输入确认密码
webDriver.findElement(By.cssSelector("#settings_input_passwordRepeat")).sendKeys("654321");
// 点击 提交修改 按钮
// webDriver.findElement(By.cssSelector("#settings_submit_password")).click();
// 使用 Actions 类可以模拟鼠标操作
WebElement element = webDriver.findElement(By.cssSelector("#settings_submit_password"));
Actions actions = new Actions(webDriver);
actions.moveToElement(element).click().perform();
Thread.sleep(1000);
Thread.sleep(5000);
// 判断是否返回登录界面
// 获取当前的url地址
String except = "http://47.113.217.156:58080/sign-in.html";
String actual = webDriver.getCurrentUrl();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(except, actual);
System.out.println("密码修改成功!");
// 判断原来的用户名和密码能否再次登录
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(3000);
// 登录失败,出现警告提示
// 验证提示内容
String msg = webDriver.findElement(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div")).getText();
String except2 = "×\n警告\n用户名或密码错误";
String methodName2 = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName2);
Assertions.assertEquals(except2, msg);
System.out.println("原密码登录失败!");
// 再用新密码进行登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys("654321");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(5000);
// 登录成功,跳转到主页
// 获取当前的url地址
String except3 = "http://47.113.217.156:58080/index.html";
String actual3 = webDriver.getCurrentUrl();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 截图保存测试结果
String methodName3 = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName3);
Assertions.assertEquals(except3, actual3);
System.out.println("新密码登录成功!");
}



2.12. 退出测试
🍂场景1:登录后,点击用户头像下的退出按钮,跳转回登录界面,退出成功。
具体流程如下:
- 登录并进入个人中心页面。
- 点击头像,再点击退出。
- 验证退出后是否跳转到登录页面。
// 退出测试
/**
* 场景1:登录状态下,点击头像,再点击退出,跳转到登录页面
*/
@Order(16)
@ParameterizedTest
@CsvSource(value = "wutong, 654321")
void Logout(String username, String password) throws InterruptedException, IOException {
// 1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 2-点击头像,再点击退出,跳转到登录页面
webDriver.findElement(By.cssSelector("#index_nav_avatar")).click();
Thread.sleep(1000);
webDriver.findElement(By.cssSelector("#index_user_logout")).click();
Thread.sleep(3000);
// 获取当前的url地址
String except = "http://47.113.217.156:58080/sign-in.html";
String actual = webDriver.getCurrentUrl();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(except, actual);
System.out.println("退出成功!");
}

2.13. 评论测试
2.13.1. 登录状态下测试评论内容为空发布评论
🍂场景1:登录状态下,进入帖子详情页,直接点击回复按钮,发表评论。(分别测试作者给自己的帖子评论,和别人给自己的帖子评论)。
具体流程如下:
- 登录并进入帖子详情页面。
- 直接点击回复按钮但不输入评论内容。
- 验证是否出现提示要求输入回复内容。
// 评论测试
/**
* 场景1:登录状态下,不输入评论内容,点击评论按钮,发表评论
*/
@Order(17)
@ParameterizedTest
@CsvSource({"wutong, 654321", "admin, admin"}) // 分别测试作者给自己的帖子评论,和别人给自己的帖子评论
void CommentNoContent(String username, String password) throws InterruptedException, IOException {
// 1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 2-点击帖子内容“与凤行”,进入该帖内容页
webDriver.findElement(By.cssSelector("#artical-items-body > div:nth-child(2) > div > div.col > div.text-truncate > a > strong")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(3000);
// 点击回复按钮
WebElement element2 = webDriver.findElement(By.cssSelector("#details_btn_article_reply"));
Actions actions2 = new Actions(webDriver);
actions2.moveToElement(element2).click().perform();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(2000);
// 出现提示,验证提示内容
String msg = webDriver.findElement(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div")).getText();
String except = "×\n提示\n请输入回复内容";
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(except, msg);
System.out.println("评论失败!");
}


2.13.2. 登录状态下测试评论内容不为空发布评论
🍂场景2:登录状态下,进入帖子详情页,输入评论内容,点击回复按钮,发表评论。(分别测试作者给自己的帖子评论,和别人给自己的帖子评论)。
具体流程如下:
- 登录并进入帖子详情页面。
- 输入评论内容。
- 点击评论按钮发表评论。
- 验证评论数是否增加。
- 验证评论内容是否正确展示。
/**
* 场景2:登录状态下,输入评论,点击评论按钮,发表评论
*/
@Order(18)
@ParameterizedTest
@CsvSource({"wutong, 654321", "admin, admin"})
void Comment(String username, String password) throws InterruptedException, IOException {
// 1-登录
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 2-点击帖子内容“与凤行”,进入该帖内容页
webDriver.findElement(By.cssSelector("#artical-items-body > div:nth-child(2) > div > div.col > div.text-truncate > a > strong")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(5000);
// 获取评论前的评论数
String cur = webDriver.findElement(By.cssSelector("#details_article_replyCount")).getText();
// 3-评论框中输入一些内容(前端评论展示的内容是# > >),找到回复按钮并点击
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
WebElement element1 = webDriver.findElement(By.cssSelector("#article_details_reply > div.editormd-toolbar > div > ul > li:nth-child(7) > a > i"));
Actions actions1 = new Actions(webDriver);
actions1.moveToElement(element1).click().perform();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(1000);
actions1.moveToElement(element1).click().perform();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(1000);
WebElement element2 = webDriver.findElement(By.cssSelector("#article_details_reply > div.editormd-toolbar > div > ul > li:nth-child(12) > a > i"));
Actions actions2 = new Actions(webDriver);
actions2.moveToElement(element2).click().perform();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(1000);
actions2.moveToElement(element2).click().perform();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(1000);
// 点击回复按钮
webDriver.findElement(By.cssSelector("#details_btn_article_reply")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(3000);
// 获取评论后的评论数
String after = webDriver.findElement(By.cssSelector("#details_article_replyCount")).getText();
// 获取第一条评论
String exceptComment = "# > >";
String actualComment = webDriver.findElement(By.cssSelector("#details_article_reply_content_21")).getText();
if (username == "admin") {
actualComment = webDriver.findElement(By.cssSelector("#details_article_reply_content_22")).getText();
}
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
// 验证评论数是否增加
Assertions.assertEquals(Integer.parseInt(cur) + 1, Integer.parseInt(after));
// 验证评论内容
Assertions.assertEquals(exceptComment, actualComment);
System.out.println("评论成功!");
}


2.14. 站内信测试
🍂场景1:登录状态下,验证两个账号用户之间的站内信的发送和回复能否正常更新,站内信息状态的切换更新是否正常。
具体流程如下:
- 1️⃣准备工作:
- 使用两个不同的账号,例如账号wutong(A)和账号admin(B)。
- 确保账号A已登录并且有发送站内信的权限。
- 确保账号B已登录并且有接收和回复站内信的权限。
- 2️⃣登录账号A:
- 打开登录页面并使用账号A的用户名和密码登录。
- 导航到帖子详情页面,选择一个非当前用户的帖子,例如“不良人”。
- 3️⃣发送站内信:
- 点击帖子中的“发私信”按钮。
- 在站内信编辑框中输入内容,例如“你好,我是账号A”。
- 点击发送按钮,等待发送成功提示。
- 4️⃣退出登录账号A:
- 点击头像,选择退出登录,确保账号A已退出登录状态。
- 5️⃣登录账号B:
- 打开登录页面并使用账号B的用户名和密码登录。
- 导航到站内信页面,点击页面上的站内信图标(小铃铛)。
- 6️⃣验证站内信接收:
- 在站内信列表中查看是否接收到了来自账号A的站内信。
- 确认站内信内容和发送者信息是否正确。
- 确认站内信状态是否为“未读”。
- 7️⃣回复站内信:
- 点击站内信中的回复按钮或者打开站内信详情页面。
- 在回复编辑框中输入回复内容,例如“你好,我是账号B”。
- 点击发送按钮,等待回复发送成功提示。
- 8️⃣验证站内信状态更新:
- 返回站内信列表页面,确认站内信状态是否已更新为“已回复”。
- 如果站内信列表中显示“已回复”,则表示站内信状态更新成功。
- 9️⃣退出登录账号B:
- 刷新页面后,点击头像,选择退出登录,确保账号B已退出登录状态。
- 🔟登录账号A:
- 打开登录页面并使用账号A的用户名和密码登录。
- 导航到站内信页面,点击页面上的站内信图标(小铃铛)。
- 1️⃣1️⃣验证回复接收:
- 在站内信列表中查看是否接收到了来自账号B的回复。
- 确认站内信内容和发送者信息是否正确。
- 确认站内信状态是否为“未读”。
- 1️⃣2️⃣截图和结果记录:
- 在每个关键步骤执行后,截取页面截图以及输出结果信息。
- 结果记录应该包括每个步骤的执行情况,包括发送站内信、接收站内信、回复站内信,回复接收以及站内信状态更新。
// 站内信测试
/**
* 场景1:登录状态下,两个账号用户之间的站内信的发送和回复,站内信息状态的更新
*/
@Order(19)
@ParameterizedTest
@CsvSource(value = "wutong, 654321, admin, admin")
void Message(String username1, String password1, String username2, String password2) throws InterruptedException, IOException {
// 1-登录发送站内信的账号
// 打开登录页面
webDriver.get("http://47.113.217.156:58080/sign-in.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username1);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password1);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 2-点击作者是非当前用户的一个帖子,点击帖子内容“不良人”,进入该帖内容页
webDriver.findElement(By.cssSelector("#artical-items-body > div:nth-child(3) > div > div.col > div.text-truncate > a > strong")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(3000);
// 3-点击“发私信”按钮,发送站内信
webDriver.findElement(By.cssSelector("#btn_details_send_message")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(3000);
// 在文本框中输入内容,发送站内信
webDriver.findElement(By.cssSelector("#index_message_receive_content")).sendKeys("你好,我是" + username1);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(1000);
// 点击发送按钮
webDriver.findElement(By.cssSelector("#btn_index_send_message")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(3000);
// 4-退出登录
// 点击头像,再点击退出,跳转到登录页面
webDriver.findElement(By.cssSelector("#index_nav_avatar")).click();
Thread.sleep(1000);
webDriver.findElement(By.cssSelector("#index_user_logout")).click();
Thread.sleep(3000);
// 5-登录被发送者,即接收者账号
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username2);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password2);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
Thread.sleep(1000);
// 6-点击小铃铛,打开到站内信页面,验证是否接受到站内信
webDriver.findElement(By.cssSelector("body > div.page > header.navbar.navbar-expand-md.navbar-light.d-print-none > div > div > div:nth-child(2) > div > a > svg")).click();
Thread.sleep(3000);
// 验证第一条站内信内容
String except = "你好,我是" + username1;
String actual = webDriver.findElement(By.cssSelector("#index_div_message_list > div:nth-child(1) > div > div.col.text-truncate > div")).getText();
// 验证信息状态
String except2 = "[未读]";
String actual2 = webDriver.findElement(By.cssSelector("#index_div_message_list > div:nth-child(1) > div > div.col.text-truncate > a > span.index_message_item_statue")).getText();
// 验证发送者
String except3 = "梧桐木";
String actual3 = webDriver.findElement(By.cssSelector("#index_div_message_list > div:nth-child(1) > div > div.col.text-truncate > a > span:nth-child(2) > strong")).getText();
// 截图保存测试结果
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
Assertions.assertEquals(except, actual);
Assertions.assertEquals(except2, actual2);
Assertions.assertEquals(except3, actual3);
System.out.println("站内信发送成功!");
// 7-点击第一条站内信后取消,检查状态更新
webDriver.findElement(By.cssSelector("#index_div_message_list > div:nth-child(1) > div > div.col.text-truncate > a")).click();
Thread.sleep(3000);
// 点击取消
webDriver.findElement(By.cssSelector("#index_message_reply_cancel")).click();
// 验证信息状态
String except4 = "[已读]";
String actual4 = webDriver.findElement(By.cssSelector("#index_div_message_list > div:nth-child(1) > div > div.col.text-truncate > a > span.index_message_item_statue")).getText();
// 截图保存测试结果
String methodName2 = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName2);
Assertions.assertEquals(except4, actual4);
System.out.println("站内信状态切换正常!");
// 8-回复站内信,点击第一条站内信,进入回复页面
webDriver.findElement(By.cssSelector("#index_div_message_list > div:nth-child(1) > div > div.col.text-truncate > a")).click();
Thread.sleep(3000);
// 点击回复
webDriver.findElement(By.cssSelector("#btn_index_message_reply")).click();
Thread.sleep(3000);
// 在文本框中输入内容
webDriver.findElement(By.cssSelector("#index_message_reply_receive_content")).sendKeys("哈喽,我是" + username2);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(1000);
// 点击发送按钮
webDriver.findElement(By.cssSelector("#btn_index_send_message_reply")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
sleep(3000);
// 10-再次验证站内信状态
String except6 = "[已回复]";
String actual6 = webDriver.findElement(By.cssSelector("#index_div_message_list > div:nth-child(1) > div > div.col.text-truncate > a > span.index_message_item_statue")).getText();
// 截图保存测试结果
String methodName3 = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName3);
Assertions.assertEquals(except6, actual6);
System.out.println("站内信状态切换正常!");
// 刷新页面
webDriver.navigate().refresh();
Thread.sleep(3000);
// 11-退出登录
webDriver.findElement(By.cssSelector("#index_nav_avatar")).click();
Thread.sleep(1000);
webDriver.findElement(By.cssSelector("#index_user_logout")).click();
Thread.sleep(3000);
// 12-登录被回复者,验证是否收到了回复内容
// 输入用户名
webDriver.findElement(By.cssSelector("#username")).sendKeys(username1);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(password1);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 点击登录按钮
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.MINUTES);
// 点击站内信,跳转到站内信页面
// 点击小铃铛
webDriver.findElement(By.cssSelector("body > div.page > header.navbar.navbar-expand-md.navbar-light.d-print-none > div > div > div:nth-child(2) > div > a > svg")).click();
Thread.sleep(3000);
// 验证第一条站内信内容
String except7 = "哈喽,我是" + username2;
String actual7 = webDriver.findElement(By.cssSelector("#index_div_message_list > div:nth-child(1) > div > div.col.text-truncate > div")).getText();
// 验证信息状态
String except8 = "[未读]";
String actual8 = webDriver.findElement(By.cssSelector("#index_div_message_list > div:nth-child(1) > div > div.col.text-truncate > a > span.index_message_item_statue")).getText();
// 验证发送者
String except9 = "创客001";
String actual9 = webDriver.findElement(By.cssSelector("#index_div_message_list > div:nth-child(1) > div > div.col.text-truncate > a > span:nth-child(2) > strong")).getText();
// 截图保存测试结果
String methodName4 = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName4);
Assertions.assertEquals(except7, actual7);
Assertions.assertEquals(except8, actual8);
Assertions.assertEquals(except9, actual9);
System.out.println("站内信回复成功!");
}





3. 性能测试
🍂这里针对登录功能使用 LoadRunner 进行简单的性能测试,在实现的过程中,插入集合点以及事务等,并通过设置来实现用户的并发操作。
具体流程如下:
- 添加访问地址
- 通过开发者工具查看请求发送的格式,以此来进行性能测试脚本的编写(可以使用VUG录制脚本再进行增强)。
- 用户名以及密码可以有多个,可以使用参数化。
- 添加事务以及集合点、检查点:注意检查点一般放在请求之前。
- 设置迭代次数:为了能够更好地遍历到所有的参数。
- 进行脚本测试。
- 设置并发数量进行性能测试(Controller),并导出测试报告以及图表(Analysis)。
3.1. 编写脚本并执行
Action()
{
lr_rendezvous("login");
lr_start_transaction("Login");
web_url("sign-in.html",
"URL=http://47.113.217.156:58080/sign-in.html",
"Resource=0",
"Referer=",
"Snapshot=t1.inf",
"Mode=HTML",
EXTRARES,
"Url=/sign-in.html", ENDITEM,
LAST);
web_submit_data("login",
"Action=http://47.113.217.156:58080/user/login",
"Method=POST",
"RecContentType=application/json",
"Referer=http://47.113.217.156:58080/sign-in.html",
"Snapshot=t12.inf",
"Mode=HTML",
ITEMDATA,
"Name=username", "Value={user_name}", ENDITEM,
"Name=password", "Value={pass_word}", ENDITEM,
LAST);
web_url("index.html",
"URL=http://47.113.217.156:58080/index.html",
"Resource=0",
"Referer=http://47.113.217.156:58080/sign-in.html",
"Snapshot=t13.inf",
"Mode=HTML",
EXTRARES,
"Url=/user/info", ENDITEM,
"Url=/board/topList", ENDITEM,
"Url=/message/getUnreadCount", ENDITEM,
"Url=/message/getAll", ENDITEM,
"Url=/article/getAllByBoardId", ENDITEM,
LAST);
web_url("article_list.html",
"URL=http://47.113.217.156:58080/article_list.html",
"Resource=0",
"Referer=http://47.113.217.156:58080/index.html",
"Snapshot=t14.inf",
"Mode=HTML",
LAST);
lr_end_transaction("Login",LR_AUTO);
return 0;
}




以上结果表明脚本执行通过。
3.2. 使用Controller创建性能测试场景
1️⃣在 Controller 中设置场景,首先设置10个虚拟用户数量,防止电脑崩溃。

2️⃣一次初始化一个用户,每次间隔 15s 初始化一个虚拟用户。

3️⃣设置虚拟用户数量 10 个,每隔 10S 启动一个用户。

4️⃣运行5分钟。

5️⃣退出所有用户,每隔 10s退出一个用户。

6️⃣设置好这些之后,就可以点击运行,启动场景了。
🍂运行过程截图。

🍂运行结束截图。

3.3. 生成测试报告

🍂场景名称为 “Scenario1”,测试时间段从 2024/4/14 18:27 到 2024/4/14 18:37,持续了 10 分钟 29 秒,以下是监测到的相关实时数据。
- 虚拟用户数为 10:测试期间最大运行的虚拟用户数为 10 个。
- 总吞吐量 49,056,158:总共的吞吐量为 49,056,158 字节。
- 平均吞吐量为 77,867:系统在单位时间(秒)内处理的请求数量,测试期间处理了 77,867 个请求。
- 总请求次数 824:总共发送了 824 次请求。
- 点击率/平均每秒请求次数为 1.308:在一定时间内发生的点击次数,测试中出现了 1308 次点击,即平均每秒处理的请求次数为 1.308 次/秒。
- 总错误数 1:测试期间总共出现了 1 次错误。
- 标准差为 37.071:系统不够稳定,后续应进一步优化系统以降低标准差,提高系统的可靠性和稳定性。
最后是最后是 HTTP 响应的摘要信息,总共接收到了 824 次 HTTP 200 响应,平均每秒处理的 HTTP 200 响应次数为 1.308 次/秒。
🍁点击率:刚开始启动,点击率较少,后面慢慢开始增大。
🍁吞吐量:点击数越多,要处理的数量就越多,和上图的趋势相似。



2193

被折叠的 条评论
为什么被折叠?



