目录
一、项目介绍
项目名称
项目简介
相关技术
项目展示
二 、测试用例设计和功能测试
测试用例设计
注册页面
登陆页面
首页面
发布帖子页面
修改个人信息页面
功能测试
注册页面
登录页面
首页面
发布帖子页面
修改个人信息页面
三、接口测试
1.Junit单元测试
用户接口
2.Swagger API测试
接口测试版块总览:
回复接口:
帖子接口:
版块接口:
用户接口:
站内信接口:
四 自动化测试
1.使用selenium进行自动化测试准备工作
1)引入依赖
2)创建公共类
3)创建测试套件类
2.对登录页面进行自动化测试
一、项目介绍
项目名称
IT论坛
项目简介
相关技术
- 使⽤统⼀返回格式+全局错误信息定义处理前后端交互时的返回结果;
- 使⽤拦截器实现⽤⼾登录校验,方便效验用户信息;
- 使⽤MybatisGeneratorConfig⽣成常用的增删改查⽅法,简化代码编写;
- 集成 Swagger 实现⾃动⽣成 API 测试接⼝,方便后端接口测试;
- 使⽤jQuery 完成 AJAX 请求,并处理 HTML⻚⾯标签。
- 引入了 editor.md,editor.md 是一个开源的页面 markdown 编辑器组件
项目展示
二 、测试用例设计和功能测试
测试用例设计
测试用例会从功能测试,界面测试,兼容性测试,易用性测试,安全性测试,性能测试六个方面进行设计。
注册页面
登陆页面
首页面
发布帖子页面
修改个人信息页面
功能测试
注册页面
输入用户名 | 输入昵称 | 输入密码 | 输入确认密码 | 勾选同意条款 | 点击注册 | 预期结果 | 实际结果 |
空 | 空 | 空 | 空 | 不勾选 | 点击 | 提示不能为空 | 每个输入框下都提示不能为空 |
张三 | 空 | 空 | 空 | 不勾选 | 点击 | 除用户名外都提示不能为空 | 其余三个提示不能为空 |
张三 | 张三 | 123456 | 111111 | 不勾选 | 点击 | 提示密码和确认密码不相同 | 提示请检查确认密码 |
张三 | 张三 | 123456 | 123456 | 不勾选 | 点击 | 提示勾选条款 | 勾选框标红,点击注册结果无效 |
张三 | 张三 | 123456 | 123456 | 勾选 | 点击 | 注册成功 | 注册成功,跳转到登录页面 |
登录页面
给定一个正确的用户名和密码。
用户名:张三
密码:123456
输入用户名 | 输入密码 | 操作 | 预期结果 | 实际结果 |
空 | 空 | 点击登录 | 提示用户名和密码不能为空 | 提示用户名和密码不能为空 |
zhangsan(错误用户名) | 空 | 点击登录 | 提示密码不能为空 | 提示密码不能为空 |
zhangsan(错误用户名) | 123456 | 点击登录 | 提示用户名或密码错误 | 提示用户名或密码错误 |
张三 | 111111 | 点击登录 | 提示用户名或密码错误 | 提示用户名或密码错误 |
张三 | 123456 | 点击登录 | 登录成功 | 登录成功,跳转首页面 |
首页面
操作 | 预期结果 | 实际结果 |
点击Java | 跳转到Java板块 | 跳转到Java板块 |
点击“测试” | 跳转到帖子详情页 | 跳转到帖子详情页 |
点击发布帖子 | 跳转到发布帖子页面 | 跳转到发布帖子页面 |
点击月亮图标 | 切换到夜间模式 | 切换到夜间模式 |
点击铃铛图标 | 显示站内信 | 显示站内信 |
发布帖子页面
输入标题 | 输入内容 | 操作 | 预期结果 | 实际结果 |
空 | 空 | 点击发布 | 提示请输入帖子标题 | 提示请输入帖子标题 |
测试标题 | 空 | 点击发布 | 提示请输入帖子内容 | 提示请输入帖子内容 |
测试标题 | 测试内容 | 点击发布 | 发布成功 | 发布成功,跳转至首页 |
修改个人信息页面
操作 | 预期结果 | 实际结果 |
点击修改头像,上传头像 | 头像变更为刚上传的头像 | 图片无变化(修改头像功能未实现) |
输入邮箱地址,点击修改 | 修改成功 | 修改成功 |
输入电话号码,点击修改 | 修改成功 | 修改成功 |
输入错误原密码,点击提交 | 提示密码效验失败 | 提示密码效验失败 |
输入正确原密码,新密码和确认密码不同,点击提交 | 提示两次密码输入不相同 | 提示两次密码输入不相同 |
输入正确原密码,新密码和确认密码相同,点击提交 | 修改成功 | 修改成功 |
三、接口测试
1.Junit单元测试
这里我展示一个单元测试
用户接口
@SpringBootTest
class UserServiceImplTest {
@Resource
private IUserService userService;
@Resource
private ObjectMapper objectMapper;
@Test
void selectByName() throws JsonProcessingException {
User user = userService.selectByName("bitboy");
System.out.println(objectMapper.writeValueAsString(user));
System.out.println("=====================================");
user = userService.selectByName("bitboy111");
System.out.println(objectMapper.writeValueAsString(user));
}
@Test
void createNormalUser() {
// 构造用户
User user = new User();
user.setUsername("TestUser1");
user.setNickname("单元测试用户1");
user.setPassword("123456");
user.setSalt("123456");
// 调用Service
userService.createNormalUser(user);
System.out.println("注册成功");
System.out.println("=====================");
user.setUsername("bitboy");
userService.createNormalUser(user);
System.out.println("注册成功");
}
@Test
void login() throws JsonProcessingException {
User user = userService.login("bitboy", "123456");
System.out.println(objectMapper.writeValueAsString(user));
user = userService.login("123456", "123456");
System.out.println(objectMapper.writeValueAsString(user));
}
@Test
void selectById() throws JsonProcessingException {
User user = userService.selectById(1L);
System.out.println(objectMapper.writeValueAsString(user));
user = userService.selectById(2L);
System.out.println(objectMapper.writeValueAsString(user));
}
@Test
@Transactional
void addOneArticleCountById() {
userService.addOneArticleCountById(1L);
System.out.println("更新成功");
userService.addOneArticleCountById(2L);
System.out.println("更新成功");
userService.addOneArticleCountById(10L);
System.out.println("更新成功");
}
}
其余单元测试可以参考我的gitee链接:forum: 基于 Spring 的前后端分离的论坛系统 - Gitee.com
2.Swagger API测试
测试链接:(得先在本地启动项目)http://127.0.0.1:8888/swagger-ui/index.html#/
接口测试版块总览:
回复接口:
帖子接口:
版块接口:
用户接口:
站内信接口:
这里展示一个接口的一个功能测试过程:
用户接口的登录过程:
过程:
结果:
四 自动化测试
1.使用selenium进行自动化测试准备工作
1)引入依赖
创建一个maven项目,在pop.xml中引入以下依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-params -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-suite -->
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-suite</artifactId>
<version>1.9.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-suite -->
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-suite</artifactId>
<version>1.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.1</version>
<scope>test</scope>
</dependency>
</dependencies>
2)创建公共类
因为对每一个页面进行测试都需要创建浏览器驱动,所以我们可以把他提取出来并设置成静态的,就可以让创建和销毁驱动的操作只实现一次,其他类都继承这个类即可。
public class AutoTestUtils {
private static ChromeDriver driver;
public static ChromeDriver createDrive() {
if (driver == null) {
driver = new ChromeDriver();
// 隐式等待, 渲染页面, 防止找不到页面元素
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
return driver;
}
}
3)创建测试套件类
创建一个类,通过@Suite
注解识别该类为测试套件类,使用@SelectClasses
来注解声明我们要运行哪些类。
@Suite
@SelectClasses({LoginTest.class, IndexTest.class})
public class RunSuite {
}
2.对登录页面进行自动化测试
①打开登陆网页
②对登陆页面上的文字进行判断
页面上的用户名,密码,登录按钮是否都正常显示
点击注册按钮能否正常跳转页面
③测试窗口伸缩
测试窗口缩小至指定大小,放大到最大
④错误的登录测试
用户名为空,提示用户名不能为空
密码为空,提示密码不能为空
用户名密码不匹配,提示用户名或密码错误
⑤正确的登录测试
输入正确的用户名与密码,登陆成功,跳转至首页,判断跳转的url是否正确,以及跳转页面上的文字是否显示正确
⑥运行结果
测试全部通过
代码详情:
/**
* @author: ZQ
* @date: 2023/8/27 17:42
* @description:
*/
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class LoginTest extends AutoTestUtils {
// 获取浏览器驱动
public static ChromeDriver driver = createDrive();
/**
* 打开网页
*/
@Test
@BeforeAll
static void init() {
// 跳转到登录页面
driver.get("http://8.130.53.233:8848/sign-in.html");
// 隐式等待页面加载完成
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
}
// /**
// * 对登陆页面的一些文字显示进行判断
// */
// @Test
// @Order(1)
// void loginPageTest() {
// // 检查系统名称
// String expect = "用户登录";
// String actual = driver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.card.card-md > div > h2")).getText();
// Assertions.assertEquals(expect, actual);
// // 判断登录窗口的内容
// String expect2 = driver.findElement(By.cssSelector("#signInForm > div.mb-3 > label")).getText();
// Assertions.assertEquals(expect2, "用户名");
// String expect3 = driver.findElement(By.cssSelector("#signInForm > div.mb-2 > label")).getText();
// Assertions.assertEquals(expect3, "密码");
// // 检查登陆按钮是否存在
// driver.findElement(By.cssSelector("#submit"));
// // 检查注册按钮是否存在
// driver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.text-muted.mt-3 > a"));
// // 点击注册按钮
// driver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.text-muted.mt-3 > a")).click();
// // 判断跳转页面是否正确
// String url = driver.getCurrentUrl();
// Assertions.assertEquals(url, "http://8.130.53.233:8848/sign-up.html");
// }
/**
* 测试窗口伸缩
*/
@Test
@Order(2)
public void windowSize() {
driver.manage().window().setSize(new Dimension(900, 900));
driver.manage().window().setSize(new Dimension(300, 300));
driver.manage().window().maximize();
}
/**
* 错误登录测试1
*/
@ParameterizedTest
@Order(4)
@CsvSource(value = {"张三, 12345"})
void loginAbnormal1(String username, String password) {
// 清空用户名和密码
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
// 用户名为空
driver.findElement(By.cssSelector("#username")).click();
driver.findElement(By.cssSelector("#password")).sendKeys(password);
String expect = driver.findElement(By.cssSelector("#signInForm > div.mb-3 > div")).getText();
// 断言
Assertions.assertEquals(expect, "用户名不能为空");
// 密码为空
driver.findElement(By.cssSelector("#username")).sendKeys(username);
driver.findElement(By.cssSelector("#password")).clear();
String expectPass = driver.findElement(By.cssSelector("#signInForm > div.mb-2 > div > div")).getText();
// 断言
Assertions.assertEquals(expectPass, "密码不能为空");
// 返回上一个页面
// driver.navigate().back();// 这里不需要返回,并未跳转页面
}
/**
* 错误登录测试2
*/
@ParameterizedTest
@Order(4)
@CsvSource(value = {"张三, 12345","张三1,123456"})
void loginAbnormal2(String username, String password) {
// 清空用户名和密码
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
// 输入用户名和密码
driver.findElement(By.cssSelector("#username")).sendKeys(username);
driver.findElement(By.cssSelector("#password")).sendKeys(password);
// 点击登录
driver.findElement(By.cssSelector("#submit")).click();
// 等待弹窗内容
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 判断弹窗内容
String expect = driver.findElement(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2")).getText();
// 断言
Assertions.assertEquals(expect, "警告");
// 返回上一个页面
// driver.navigate().back();// 这里不需要返回,并未跳转页面
}
/**
* 正确登录测试
*/
@ParameterizedTest
@Order(4)
@CsvSource(value = {"张三, 123456","李四, 123456"})
void loginNormal(String username, String password) {
// 清空用户名和密码
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
// 输入用户名和密码
driver.findElement(By.cssSelector("#username")).sendKeys(username);
driver.findElement(By.cssSelector("#password")).sendKeys(password);
// 点击登录
driver.findElement(By.cssSelector("#submit")).click();
// 等待跳转页面
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 判断跳转页面url
String url = driver.getCurrentUrl();
// 断言url
Assertions.assertEquals(url, "http://8.130.53.233:8848/sign-in.html");
// 判断显示是否为首页
String expect = driver.findElement(By.cssSelector("#article_list_board_title")).getText();
// 断言
Assertions.assertEquals(expect, "首页");
// 返回上一个页面
driver.navigate().back();// 这里不需要返回,并未跳转页面
}
}