一、项目描述
1、采用前后端分离的来实现我的博客系统,使用MySQL 数据库存储用户和博客信息。
2、前端页面包含用户注册、登录、我的博客列表页、博客主页面、添加博客页面、修改博客页以及博客详情页;
3、我的博客系统实现了登录注册、发布博客、修改博客、查看博客详情、数量统计、删除博客、注销等主要功能。可以实现对博客记录,时间、标题、内容以及阅读量等进行查看。
二、项目功能描述
1、注册:在登陆页面点击“注册
”按钮,跳转到注册页面,注册页面输入“用户名
”、“密码
”以及“确认密码
”,首先会进行非空校验以及密码一致性校验,然后会根据用户名查看用户是否存在,如不存在,则加入数据库中,注册成功,点击弹窗,进入登录界面;如果存在会返回提示信息,注册失败。
2、登录:输入用户名和密码,首先会进行非空校验,为空则给出提示信息;如果不为空则查询数据库用户名是否存在,存在的话就校验密码是否正确,两个都校验通过则登陆成功,点击弹窗进入我的博客列表页面;如果用户名不存在或者密码错误,则提示“用户名或密码错误”,登录失败,点击弹窗,停留在登录界面。
3、写博客:在我的博客列表页面,点击写博客按钮,进入添加博客页面,输入博客标题以及博客内容,点击发布文章,这个时候会弹窗“添加成功!是否继续添加
?”点击“是
”,则停留在添加博客页面,点击“否
”,则进入带我的博客列表页面,并且第一条博客是我最新添加的博客。
4、查看详情:在我的博客列表页,点击第一条最新添加的博客,进入博客详情页面,展示当前博客的标题、内容、发布时间以及阅读量等信息。每浏览一次阅读量+1;
5、修改博客:在我的博客博客列表页面点击修改博客按钮,那么会进入博客编辑页,此时编辑页的标题以及正文的内容就是我所点击的博客的标题和正文。
6、删除博客:在我的博客列表页面,点击每个博客对应的删除按钮,则会删除该博客,并且文章数量-1;
7、博客主页:博客主页是分页展示所有的博客,也可以对博客进行查看详情,如果在首页,点击首页按钮,提示“已经在首页了
”;如果只有一页,点击上一页,下一页,末页都不跳转,如果页面数量不是1页,点击相应的页面跳转按钮,会有相应的页面切换。
8、退出登录:点击注销按钮,会提示弹窗“确认注销?
”,点击确认则进入登录界面,点击取消则不退出登录,保留在当前页面。
三、测试计划
1、功能测试
1.1 测试用例
1.2 测试步骤
(1)注册测试
正常注册测试:
RegSuccess.csv
文件:
xulin, 123456, 123456, http://localhost:8080/login.html, http://localhost:8080/reg.html
@Order(3)
@ParameterizedTest
@CsvFileSource(resources = "RegSuccess.csv")
void regSuccess(String uname, String pwd, String pwd2, String login_url, String reg_url) throws InterruptedException {
//打开博客登陆页面
webDriver.get(login_url);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//找到注册按钮
webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
//进入到注册页面
// 获取 页面的url 看是不是等于 “http://localhost:8080/reg.html”
String curUrl = webDriver.getCurrentUrl();
Assertions.assertEquals(reg_url,curUrl);
//输入账号
webDriver.findElement(By.cssSelector("#username")).sendKeys(uname);
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(pwd);
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//输入确认密码
webDriver.findElement(By.cssSelector("#password2")).sendKeys(pwd2);
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//点击注册
webDriver.findElement(By.cssSelector("#submit")).click();
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//这里会有“注册成功”弹窗 确认
sleep(2000);
webDriver.switchTo().alert().accept();
//页面跳转到登录
// 获取 页面的url 看是不是等于 “http://localhost:8080/login.html”
curUrl = webDriver.getCurrentUrl();
Assertions.assertEquals(login_url, curUrl);
}
异常注册测试:
RegFailed.csv
文件:
lisi, 1234, 1234, http://localhost:8080/login.html, http://localhost:8080/reg.html
"", 1234, 1234, http://localhost:8080/login.html, http://localhost:8080/reg.html
lisi, "", 1234, http://localhost:8080/login.html, http://localhost:8080/reg.html
lisi, 123456, 1234, http://localhost:8080/login.html, http://localhost:8080/reg.html
@Order(2)
@ParameterizedTest
@CsvFileSource(resources = "RegFailed.csv")
void regFailed(String uname, String pwd, String pwd2, String login_url, String reg_url) throws InterruptedException {
//打开博客登陆页面
webDriver.get(login_url);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//找到注册按钮
webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
//进入到注册页面
// 获取 页面的url 看是不是等于 “http://localhost:8080/reg.html”
String curUrl = webDriver.getCurrentUrl();
Assertions.assertEquals(reg_url,curUrl);
//输入账号
webDriver.findElement(By.cssSelector("#username")).sendKeys(uname);
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(pwd);
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//输入确认密码
webDriver.findElement(By.cssSelector("#password2")).sendKeys(pwd2);
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//点击注册
webDriver.findElement(By.cssSelector("#submit")).click();
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//这里会有“注册失败”弹窗 确认
sleep(2000);
webDriver.switchTo().alert().accept();
//页面跳转到登录
// 获取 页面的url 看是不是等于 “http://localhost:8080/reg.html”
curUrl = webDriver.getCurrentUrl();
Assertions.assertEquals(reg_url, curUrl);
}
(2)登录测试
正常登录测试:
/**
* 输入正确的账号、密码 登陆成功
*/
// @Test
@Order(3)
@ParameterizedTest
@CsvFileSource(resources = "LoginSuccess.csv")
//@CsvSource( {"lisi, 123, http://localhost:8080/myblog_list.html"})
void loginSuccess(String uname, String pwd, String blog_list_url) throws InterruptedException {
//打开博客登陆页面
webDriver.get("http://localhost:8080/login.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//输入账号
webDriver.findElement(By.cssSelector("#username")).sendKeys(uname);
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(pwd);
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//点击登录
webDriver.findElement(By.cssSelector("#submit")).click();
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//这里会有“登陆成功”弹窗 确认
sleep(2000);
webDriver.switchTo().alert().accept();
//页面跳转到列表页
// 获取 页面的url 看是不是等于 “http://localhost:8080/myblog_list.html”
String curUrl = webDriver.getCurrentUrl();
Assertions.assertEquals(blog_list_url, curUrl);
//列表页展示用户信息 lisi
//获取用户名
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
String curUName = webDriver.findElement(By.cssSelector("#username")).getText();
Assertions.assertEquals(uname, curUName);
}
异常登录测试:
LoginFailed.csv 文件
:
lisi, 1234, http://localhost:8080/login.html
"", 123, http://localhost:8080/login.html
lisi, "", http://localhost:8080/login.html
xulin, 123, http://localhost:8080/login.html
@Order(4)
@ParameterizedTest
@CsvFileSource(resources = "LoginFailed.csv")
void loginFailed(String uname, String pwd, String login_url) throws InterruptedException {
//打开博客登陆页面
webDriver.get(login_url);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//输入账号
webDriver.findElement(By.cssSelector("#username")).sendKeys(uname);
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//输入密码
webDriver.findElement(By.cssSelector("#password")).sendKeys(pwd);
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//点击登录
webDriver.findElement(By.cssSelector("#submit")).click();
//sleep(200);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//这里会有“登陆失败”弹窗 确认
sleep(2000);
webDriver.switchTo().alert().accept();
//页面跳转到列表页
// 获取 页面的url 看是不是等于 “http://localhost:8080/login.html”
String curUrl = webDriver.getCurrentUrl();
Assertions.assertEquals(login_url, curUrl);
}
(3)发布博客测试
正常发布测试:
@ParameterizedTest
@CsvSource({"http://localhost:8080/myblog_list.html"})
void addBlog(String myBlog_url) throws InterruptedException {
//获取当前文章数量
String text = webDriver.findElement(By.cssSelector("#artcount")).getText();
int blogNum = Integer.parseInt(text);
//找到 “写博客”按钮 点击
webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//进入添加博客界面
// 通过Js讲鼻涕进行输入
((JavascriptExecutor) webDriver).executeScript("document.getElementById(\"title\").value=\"我的测试\"");
sleep(3000);
//*[@id="editorDiv"]/div[1]/div[5]/div[1]/div/div
//找到输入框
//#editorDiv > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div > div
WebElement input = webDriver.findElement(By.cssSelector("#editorDiv > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div > div > div.CodeMirror-code > div > pre > span > span"));
new Actions(webDriver).moveToElement(input).click().sendKeys("我的测试数据我的测试数据").perform();
sleep(2000);
webDriver.findElement(By.cssSelector("#submit")).click();
//显示等待 等待confirm 弹窗出现
Wait<WebDriver> wait = new WebDriverWait(webDriver, Duration.ofSeconds(2));
wait.until(ExpectedConditions.alertIsPresent());
//弹窗处理
webDriver.switchTo().alert().dismiss();
//我的博客列表页面
String currentUrl = webDriver.getCurrentUrl();
Assertions.assertEquals(myBlog_url,currentUrl);
//博客数量
text = webDriver.findElement(By.cssSelector("#artcount")).getText();
int newBlogNum = Integer.parseInt(text);
Assertions.assertEquals(blogNum,newBlogNum-1);
}
异常发布测试:
/**
* 不输入标题进行发布文章
* @param mybloglist_url
* @throws InterruptedException
*/
@Order(3)
@ParameterizedTest
@CsvSource({"http://localhost:8080/myblog_list.html"})
void addBlogFailed(String mybloglist_url) throws InterruptedException {
//找到 “写博客”按钮 点击
webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 通过Js讲鼻涕进行输入 标题为空
((JavascriptExecutor) webDriver).executeScript("document.getElementById(\"title\").value=\"\"");
sleep(3000);
//发布文章按钮
webDriver.findElement(By.cssSelector("#submit")).click();
//提示请输入标题
webDriver.switchTo().alert().accept();
String currentUrl = webDriver.getCurrentUrl();
Assertions.assertNotEquals(mybloglist_url, currentUrl);
}
(4)博客详情测试
public static Stream<Arguments> Generator() {
return Stream.of(Arguments.arguments("http://localhost:8080/blog_content.html", "博客正文", "我的测试"));
}
@Order(4)
@ParameterizedTest
@MethodSource("Generator")
void blogDetail(String expected_url, String expected_title, String expected_blog_title) {
//找到第一篇博客的查看全文按钮
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
webDriver.findElement(By.xpath("//*[@id=\"artListDiv\"]/div[1]/div[4]/a[1]")).click();
//获取第一篇博客详情页面的 url
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//这里是因为第一篇博客的详情页后面是带有blogid参数的 所以每次都不同
// 只需要比较前面的部分 截取实际的url前面的部分 与期望的url 进行比较
// currentUrl.substring(0,expected_url.length());
String currentUrl = webDriver.getCurrentUrl().substring(0, expected_url.length());
//获取详情页(正文页)的页面的title
String title = webDriver.getTitle();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//获取第一篇博客的title 也就是刚刚发布的博客
String blogTitle = webDriver.findElement(By.cssSelector("#title")).getText();
webDriver.getCurrentUrl().substring(0, expected_url.length());
Assertions.assertEquals(expected_url, currentUrl);
Assertions.assertEquals(expected_title, title);
Assertions.assertEquals(expected_blog_title, blogTitle);
}
(5)博客修改测试
EditSuccess.csv
文件:
http://localhost:8080/blog_edit.html, 博客编辑, 我的测试, http://localhost:8080/myblog_list.html
/**
* 修改博客
* @param expected_edit_url
* @param expected_title
* @param expected_blog_title
* @param expected_myblog_url
* @throws InterruptedException
*/
@Order(5)
@ParameterizedTest
@CsvFileSource(resources = "EditSuccess.csv")
void blogEdit(String expected_edit_url, String expected_title, String expected_blog_title, String expected_myblog_url) throws InterruptedException {
webDriver.get(expected_myblog_url);
//找到第一篇博客的查看全文按钮
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
webDriver.findElement(By.xpath("//*[@id=\"artListDiv\"]/div[1]/div[4]/a[2]")).click();
//获取第一篇博客编辑页面的 url
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//这里是因为第一篇博客的详情页后面是带有blogid参数的 所以每次都不同
// 只需要比较前面的部分 截取实际的url前面的部分 与期望的url 进行比较
// currentUrl.substring(0,expected_url.length());
String currentUrl = webDriver.getCurrentUrl().substring(0, expected_edit_url.length());
//获取编辑页的页面的title
String title = webDriver.getTitle();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//获取第一篇博客的title 也就是要编辑的博客的title
String blogTitle = webDriver.findElement(By.cssSelector("#title")).getAttribute("value");
// 通过Js 获取title 的内容
//String blogTitle = (String) ((JavascriptExecutor) webDriver).executeScript("document.getElementById(\"title\").value");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
Assertions.assertEquals(expected_edit_url, currentUrl);
Assertions.assertEquals(expected_title, title);
Assertions.assertEquals(expected_blog_title, blogTitle);
//修改数据(标题)
// 通过Js讲鼻涕进行输入 标题为空
((JavascriptExecutor) webDriver).executeScript("document.getElementById(\"title\").value=\"我的测试(修改版)\"");
sleep(3000);
//点击保存文章按钮
webDriver.findElement(By.cssSelector("button")).click();
//显示等待 等待alert弹窗出现
Wait<WebDriver> wait = new WebDriverWait(webDriver, Duration.ofSeconds(2));
wait.until(ExpectedConditions.alertIsPresent());
webDriver.switchTo().alert().accept();
//到了我的博客列表页面
currentUrl = webDriver.getCurrentUrl();
Assertions.assertEquals(expected_myblog_url, currentUrl);
}
(6)博客删除测试
/**
* 删除博客
* @param expect_myblog_url
*/
@Order(6)
@ParameterizedTest
@CsvSource({"http://localhost:8080/myblog_list.html"})
void deleteBlog(String expect_myblog_url) {
//获取页面的文章数量
String blogNumStr = webDriver.findElement(By.cssSelector("#artcount")).getText();
//转化为数字
int blogNum = Integer.parseInt(blogNumStr);
//找到“删除”按钮 然后点击
webDriver.findElement(By.xpath("//*[@id=\"artListDiv\"]/div[1]/div[4]/a[3]")).click();
//处理 alert 弹窗
//显示等待 等待alert 弹窗出现
Wait<WebDriver> wait = new WebDriverWait(webDriver, Duration.ofSeconds(2));
wait.until(ExpectedConditions.alertIsPresent());
webDriver.switchTo().alert().accept();
//此时的页面应该还是 我的博客列表页
String currentUrl = webDriver.getCurrentUrl();
//此时的文章数量应该少了 1
blogNumStr = webDriver.findElement(By.cssSelector("#artcount")).getText();
int newBlogNum = Integer.parseInt(blogNumStr);
Assertions.assertEquals(expect_myblog_url, currentUrl);
Assertions.assertEquals(blogNum - 1, newBlogNum);
}
(7)注销测试
注销失败:
/**
* 注销登录 点击取消注销弹窗
* @param begin_url
*/
@Order(7)
@ParameterizedTest
@CsvFileSource(resources = "LogoutFailed.csv")
void loginOutFailed(String begin_url) {
webDriver.get(begin_url);
//找到注销按钮
webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
//显示等待 等待confirm 弹窗出 现
Wait<WebDriver> wait = new WebDriverWait(webDriver, Duration.ofSeconds(2));
wait.until(ExpectedConditions.alertIsPresent());
webDriver.switchTo().alert().dismiss();
//登录界面
String currentUrl = webDriver.getCurrentUrl();
Assertions.assertEquals(begin_url, currentUrl);
}
注销成功:
/**
* 注销登录 点击确认注销弹窗
* @param begin_url
* @param end_url
*/
@Order(8)
@ParameterizedTest
@CsvFileSource(resources = "Logout.csv")
void loginOut(String begin_url, String end_url) {
webDriver.get(begin_url);
//找到注销按钮
webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
//显示等待 等待confirm 弹窗出 现
Wait<WebDriver> wait = new WebDriverWait(webDriver, Duration.ofSeconds(2));
wait.until(ExpectedConditions.alertIsPresent());
webDriver.switchTo().alert().accept();
//登录界面
String currentUrl = webDriver.getCurrentUrl();
Assertions.assertEquals(end_url, currentUrl);
}