目录
一、项目介绍
项目名称
项目简介
相关技术
项目展示
二 、测试用例设计和功能测试
测试用例设计
注册页面
登陆页面
首页面
发布帖子页面
修改个人信息页面
功能测试
注册页面
登录页面
首页面
发布帖子页面
修改个人信息页面
三、接口测试
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 {@Resourceprivate IUserService userService;@Resourceprivate ObjectMapper objectMapper;@Testvoid 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));}@Testvoid createNormalUser() {// 构造用户User user = new User();user.setUsername("TestUser1");user.setNickname("单元测试用户1");user.setPassword("123456");user.setSalt("123456");// 调用ServiceuserService.createNormalUser(user);System.out.println("注册成功");System.out.println("=====================");user.setUsername("bitboy");userService.createNormalUser(user);System.out.println("注册成功");}@Testvoid 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));}@Testvoid 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@Transactionalvoid 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@BeforeAllstatic 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);// 判断跳转页面urlString url = driver.getCurrentUrl();// 断言urlAssertions.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();// 这里不需要返回,并未跳转页面}
}