目录
一、项目简介
二、测试用例
三、测试过程
3.1 环境搭建
3.2 编写代码
3.2.1 博客登陆页面测试
3.2.2 博客列表页面测试
3.2.3 博客详情页面测试
3.2.4 博客编辑页面测试
四、测试评估
一、项目简介
本项目是一个简易的个人博客系统,用户可以在登陆后查看其它用户的博客、编辑发布自己的博客、删除自己发布的博客等,用户只有在登录成功后,才可以使用该系统。
项目主要功能:
a) 用户登录、注销功能;
b) 编辑、发布、查看、删除博客功能;
c) 显示用户信息功能。
主要技术栈:Java、MySQL、JDBC、Servlet、Tomcat、Jackson、单例模式
本文主要针对该项目的UI编写测试用例,并进行自动化测试。
二、测试用例
三、测试过程
3.1 环境搭建
(1) 下载最新版本的Chrome浏览器、Chrome驱动
(2) 使用IDEA社区版(2021.3.2版本)创建Maven项目
(3) 在项目的pom.xml文件中引入selenium和Junit相关依赖:
<dependencies>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.0.0</version>
</dependency>
<!--保存文件需要用到的包-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!--Junit依赖-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-suite</artifactId>
<version>1.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
(4) 创建目录结构:
3.2 编写代码
3.2.1 博客登陆页面测试
public class BlogLoginTest extends AutoTestUtils {
private static final ChromeDriver driver = getDriver();
@BeforeAll
public static void driverGet(){
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
driver.get("http://1.117.110.252:8080/blog_system2/blog_list.html");
}
/*
检查登录页面打开是否正确
检查点:用户名输入框、密码输入框、登录按钮元素是否存在
*/
@Test
public void testLoginPageLoadRight() throws IOException {
driver.findElement(By.cssSelector("#username"));
driver.findElement(By.cssSelector("#password"));
driver.findElement(By.cssSelector("#login-btn"));
getScreenShot(getClass().getName());
}
/*
检查正常登录情况
测试数据:
1.账号:orange 密码:123
2.账号:banana 密码:123
检查点:是否跳转到博客列表页(查看全文按钮是否存在)
*/
@ParameterizedTest
@CsvSource({"orange,123","banana,123"})
public void testLoginSuccess(String username,String password) throws IOException {
//1.清空用户名输入框和密码输入框中的内容
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
//2.输入测试数据
driver.findElement(By.cssSelector("#username")).sendKeys(username);
driver.findElement(By.cssSelector("#password")).sendKeys(password);
driver.findElement(By.cssSelector("#login-btn")).click();
//3.检查登录成功后是否跳转到博客列表页
driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > a"));
getScreenShot(getClass().getName());
//4.测试完一组数据后需要返回到登陆页面
driver.navigate().back();
}
/*
检查异常登录情况
测试数据:
1.账号:orange 密码:空字符串
2.账号:空字符串 密码:123
3.账号:apple 密码:666
检查点:是否有登录失败的提示信息
*/
@ParameterizedTest
@CsvSource({"orange,\"\"","\"\",123","apple,666"})
public void testLoginFail(String username,String password) throws IOException {
//1.清空用户名输入框和密码输入框中的内容
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
//2.输入测试数据
driver.findElement(By.cssSelector("#username")).sendKeys(username);
driver.findElement(By.cssSelector("#password")).sendKeys(password);
driver.findElement(By.cssSelector("#login-btn")).click();
//3.检查登录失败后是否有登陆失败的提示信息
String expect = "用户名或密码错误";
String actual = driver.findElement(By.cssSelector("body")).getText();
getScreenShot(getClass().getName());
Assertions.assertEquals(expect,actual);
//4.测试完一组数据后需要返回到登陆页面
driver.navigate().back();
}
// @AfterAll
// public static void driverQuit(){
// driver.quit();
// }
}
3.2.2 博客列表页面测试
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogListTest extends AutoTestUtils {
private static final ChromeDriver driver = getDriver();
@BeforeAll
public static void driverGet(){
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
driver.get("http://1.117.110.252:8080/blog_system2/blog_list.html");
}
/*
检查登录成功后博客列表页是否加载正确
检查点:是否有个人信息模块、查看全文按钮、写博客按钮
*/
@Test
@Order(1)
public void testListPageLoadRight() throws IOException {
driver.findElement(By.cssSelector("body > div.container > div.container-left > div"));
driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > a"));
driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)"));
getScreenShot(getClass().getName());
}
/*
检查在登录状态下能否从博客列表页进入博客详情页
检查点:是否有博客详情模块
*/
@Test
@Order(2)
public void testListToDetail() throws IOException {
//1.找到查看全文按钮元素并点击
driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > a")).click();
//2.查看是否有博客详情模块
driver.findElement(By.cssSelector("body > div.container > div.container-right"));
getScreenShot(getClass().getName());
//3.返回博客列表页
driver.navigate().back();
}
/*
检查在登录状态下能否从博客列表页进入博客编辑页
检查点:是否有发布文章按钮元素
*/
@Test
@Order(3)
public void testListToEdit() throws IOException {
//1.找到写博客按钮元素并点击
driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
//2.查看是否有发布文章按钮元素
driver.findElement(By.cssSelector("#submit"));
getScreenShot(getClass().getName());
//3.返回博客列表页
driver.navigate().back();
}
/*
检查未登录时访问博客列表页情况
检查点:是否返回到博客登录页(是否有登录输入框、密码输入框、登录按钮)
*/
@Test
@Order(4)
public void testLogOutToList() throws IOException {
//1.先注销当前登录用户
driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
//2.在浏览器中直接输入博客列表页的URL
driver.get("http://1.117.110.252:8080/blog_system2/blog_list.html");
//3.检查是否返回到博客登录页
driver.findElement(By.cssSelector("#username"));
driver.findElement(By.cssSelector("#password"));
driver.findElement(By.cssSelector("#login-btn"));
getScreenShot(getClass().getName());
//注销后需要重新登录,用于其他类中的测试用例正常进行
//a.清空用户名输入框和密码输入框中的内容
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
//b.输入正确的账号、密码
driver.findElement(By.cssSelector("#username")).sendKeys("orange");
driver.findElement(By.cssSelector("#password")).sendKeys("123");
driver.findElement(By.cssSelector("#login-btn")).click();
}
// @AfterAll
// public static void driverQuit(){
// driver.quit();
// }
}
3.2.3 博客详情页面测试
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogDetailTest extends AutoTestUtils {
private static final ChromeDriver driver = getDriver();
@BeforeAll
public static void driverGet(){
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
driver.get("http://1.117.110.252:8080/blog_system2/blog_detail.html?blogId=4");
}
/*
检查在登录状态下查看博客详情,打开的页面是否正确
检查点:是否有博客详情模块
*/
@Test
@Order(1)
public void testDetailLoadRight() throws IOException {
driver.findElement(By.cssSelector("#content"));
getScreenShot(getClass().getName());
}
/*
检查在登录状态下能否从博客详情页进入博客列表页
检查点:是否有用户信息模块、博客列表模块
*/
@Test
@Order(2)
public void testDetailToList() throws IOException {
//1.找到并点击主页按钮进入博客列表页
driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)"));
//2.检查是否有用户信息模块、博客列表模块
driver.findElement(By.cssSelector("body > div.container > div.container-left > div"));
driver.findElement(By.cssSelector("body > div.container > div.container-right"));
getScreenShot(getClass().getName());
//3.返回博客详情页
driver.navigate().back();
}
/*
检查在未登录状态访问博客详情页情况
检查点:是否返回到博客登录页(是否有用户名输入框、密码输入框、登录按钮)
*/
@Test
@Order(3)
public void testLogOutToDetail() throws IOException {
//1.找到并点击注销按钮
driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
//2.通过输入博客详情页URL来访问博客列表页
driver.get("http://1.117.110.252:8080/blog_system2/blog_detail.html?blogId=4");
//3.查找是否有用户名输入框、密码输入框、登录按钮
driver.findElement(By.cssSelector("#username"));
driver.findElement(By.cssSelector("#password"));
driver.findElement(By.cssSelector("#login-btn"));
getScreenShot(getClass().getName());
//注销后需要重新登录,用于其他类中的测试用例正常进行
//a.清空用户名输入框和密码输入框中的内容
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
//b.输入正确的账号、密码
driver.findElement(By.cssSelector("#username")).sendKeys("orange");
driver.findElement(By.cssSelector("#password")).sendKeys("123");
driver.findElement(By.cssSelector("#login-btn")).click();
}
// @AfterAll
// public static void driverQuit(){
// driver.quit();
// }
}
3.2.4 博客编辑页面测试
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogEditTest extends AutoTestUtils {
private static final ChromeDriver driver = getDriver();
@BeforeAll
public static void driverGet(){
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
driver.get("http://1.117.110.252:8080/blog_system2/blog_edit.html");
}
/*
检查登录状态下进入博客编辑页情况
检查点:是否有编辑博客模块、发布文章按钮
*/
@Test
@Order(1)
public void testEditLoadRight() throws IOException {
driver.findElement(By.cssSelector("#editor"));
driver.findElement(By.cssSelector("#submit"));
getScreenShot(getClass().getName());
}
/*
检查登录状态下能否从博客编辑页进入博客列表页
检查点:是否有用户信息模块、博客列表模块
*/
@Test
@Order(2)
public void testEditToList() throws IOException {
//1.找到并点击主页按钮回到博客列表页
driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)")).click();
//2.查看是否有用户信息模块、博客列表模块
driver.findElement(By.cssSelector("body > div.container > div.container-left > div"));
driver.findElement(By.cssSelector("body > div.container > div.container-left > div"));
getScreenShot(getClass().getName());
//3.返回博客编辑页
driver.navigate().back();
}
/*
查看在未登录状态进入博客编辑页情况
检查点:是否回到博客列表也(是否有用户名输入框、密码输入框、登录按钮)
*/
@Test
@Order(3)
public void testLogOutToEdit() throws IOException {
//1.找到并点击注销按钮
driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
//2.通过输入博客编辑URL来访问博客列表页
driver.get("http://1.117.110.252:8080/blog_system2/blog_edit.html");
//3.查找是否有用户名输入框、密码输入框、登录按钮
driver.findElement(By.cssSelector("#username"));
driver.findElement(By.cssSelector("#password"));
driver.findElement(By.cssSelector("#login-btn"));
getScreenShot(getClass().getName());
//注销后需要重新登录,用于其他类中的测试用例正常进行
//a.清空用户名输入框和密码输入框中的内容
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
//b.输入正确的账号、密码
driver.findElement(By.cssSelector("#username")).sendKeys("orange");
driver.findElement(By.cssSelector("#password")).sendKeys("123");
driver.findElement(By.cssSelector("#login-btn")).click();
}
// @AfterAll
// public static void driverQuit(){
// driver.quit();
// }
}
四、测试评估
测试用例执行情况分析:
模块名称 | 总用例 | 实际执行用例 | 通过 | 失败 | 未执行 |
博客登录页面 | 6 | 6 | 6 | 0 | 0 |
博客列表页面 | 4 | 4 | 4 | 0 | 0 |
博客详情页面 | 3 | 3 | 3 | 0 | 0 |
博客编辑页面 | 3 | 3 | 3 | 0 | 0 |
本次测试一共使用了16个测试用例,所有测试用例均正常通过,未发现bug