公司动态

【前后端开发知识 - 边开发边学习】什么的单元测试、集成测试和E2E测试?

📅 2026/7/17 19:30:07
【前后端开发知识 - 边开发边学习】什么的单元测试、集成测试和E2E测试?
单元测试 vs. 集成测试 vs. E2E测试什么的单元测试、集成测试和E2E测试单元测试 vs 集成测试 单元测试Unit Test通俗理解测试单个零件能不能用。说人话就是在不运行完整前后端系统的情况下通过构造假设数据Mock/Stub来验证业务逻辑的正确性。后端例子AuthServiceTest.java 集成测试Integration Test通俗理解测试几个零件组装后能不能用。说人话与单元测试的区别是不再”造假“。后端例子PartCrudApiTest.java E2E 测试End-to-End Test通俗理解测试真实用户使用的完整流程。理解前端例子part-crud.spec.tsE2E 测试属于集成测试对比总结我的项目中的测试最佳实践什么的单元测试、集成测试和E2E测试单元测试 vs 集成测试 单元测试Unit Test定义测试单个组件/函数隔离其他依赖用 Mock 替代。通俗理解测试单个零件能不能用。说人话就是在不运行完整前后端系统的情况下通过构造假设数据Mock/Stub来验证业务逻辑的正确性。类比造汽车你造了一个发动机单元测试就是把发动机单独拿出来不装到车上用模拟器测试能不能启动转速正常吗不管它和轮胎、方向盘配不配特点✅ 快不启动 Spring 容器不连数据库毫秒级✅ 隔离只测 AuthService.login() 逻辑不测 Mapper/数据库✅ 可控Mock 可以模拟任何场景用户不存在、密码错误等❌ 不真实无法发现 SQL 错误、网络问题 缺点不知道装到车上能不能跑// 单元测试只测 PartService.createPart() 这一个方法TestvoidtestCreatePart(){// 假装数据库返回成功不真的连数据库when(partMapper.insert(any())).thenReturn(1);// 测试这个方法的逻辑PartresultpartService.createPart(dto);// 验证零件编号生成了吗assertNotNull(result.getPartNumber());}后端例子AuthServiceTest.javaExtendWith(MockitoExtension.class)// 使用 Mockito 框架classAuthServiceTest{Mock// 模拟依赖不真实调用数据库privateSysUserMappersysUserMapper;MockprivateBCryptPasswordEncoderpasswordEncoder;InjectMocks// 被测试的对象注入上面的 MockprivateAuthServiceauthService;TestvoidtestLogin_success(){// 1. 准备测试数据SysUserusernewSysUser();user.setUsername(admin);user.setPassword($2a$10$encoded);// 2. 模拟依赖行为不真实查数据库when(sysUserMapper.selectOne(any())).thenReturn(user);when(passwordEncoder.matches(admin123,user.getPassword())).thenReturn(true);// 3. 执行被测方法LoginDTOdtonewLoginDTO(admin,admin123);SaTokenInforesultauthService.login(dto);// 4. 验证结果assertNotNull(result.getTokenValue());}} 集成测试Integration Test定义测试多个组件协作使用真实依赖真实数据库/网络。通俗理解测试几个零件组装后能不能用。类比造汽车续说人话与单元测试的区别是不再”造假“。你把发动机 变速箱 轮子组装好集成测试就是真的装到车上真的加油真的踩油门看能不能跑起来// 集成测试测试完整的 API 调用链路TestvoidtestCreatePartApi(){// 发送真实的 HTTP 请求会真的连数据库ResponserespRestAssured.post(http://localhost:8082/api/parts);// 验证数据库里真的插入了吗PartdbPartpartMapper.selectOneById(partId);assertNotNull(dbPart);}后端例子PartCrudApiTest.javaFeature(零部件管理)classPartCrudApiTestextendsBaseApiTest{// 继承基类启动真实服务TestDescription(正常创建零部件期望返回 200 及自动生成的零件编号)voidtestCreatePart_success(){MapString,ObjectbodyMap.of(name,测试零件-API-001,type,MECHANICAL);// 发送真实 HTTP 请求到 http://localhost:8082/api/partsResponserespRestAssured.given(REQUEST_SPEC).body(body).post(/api/parts);// 验证响应resp.then().statusCode(200).body(code,equalTo(200)).body(data.partNumber,startsWith(P));// 验证编号生成逻辑// 验证数据库真实插入了LongpartIdresp.jsonPath().getLong(data.id);PartdbPartpartMapper.selectOneById(partId);assertEquals(测试零件-API-001,dbPart.getName());}}特点✅ 真实测试完整链路 Controller → Service → Mapper → MySQL✅ 发现问题能发现 SQL 错误、事务问题、网络超时❌ 慢需要启动 Spring Boot 连数据库秒级❌ 依赖环境需要 MySQL/Redis 运行 E2E 测试End-to-End Test定义最广泛的集成测试全系统通俗理解测试真实用户使用的完整流程。类比造汽车续E2E 测试就是找一个真人司机让他从家里开车去公司看会不会车门打不开导航找不到路半路抛锚特点✅ 用户视角模拟真实用户操作点击、输入、提交✅ 全链路测试前端 Vue 组件 后端 API 数据库❌ 最慢需要启动浏览器 前端服务 后端服务10秒级❌ 脆弱UI 改动按钮文字变化会导致测试失败理解如果把软件开发比作造汽车单元测试是工程师在实验室里测试每一个活塞、齿轮。集成测试是把发动机装进底盘看能不能点火、漏不漏油。E2E 测试 (Playwright) 是试车员开着整车在跑道上跑一圈看这辆车能不能从起点顺利开到终点乘客坐得舒不舒服。// E2E 测试模拟用户操作test(用户创建零件,async({page}){// 1. 打开网页await page.goto(http://localhost:5173/pdm/parts);// 2. 点击新建按钮await page.click(button:has-text(新建));// 3. 填写表单await page.fill(input[namename], 测试零件);// 4. 点击保存await page.click(button:has-text(保存));// 5. 验证成功提示出现了吗awaitexpect(page.locator(.success-message)).toBeVisible();});前端例子part-crud.spec.tsE2E 测试属于集成测试test(创建零件并验证编号自动生成,async({page}){// 1. 登录真实调用后端 APIawaitloginAsAdmin(page);// 2. 打开零件列表页真实渲染 Vue 组件await page.goto(http://localhost:5173/pdm/parts);// 3. 点击新建按钮await page.locator(button:has-text(新建)).click();// 4. 填写表单await page.locator(input[placeholder*名称]).fill(E2E测试零件);// 5. 提交真实发送 POST /api/parts 请求await page.locator(button:has-text(确定)).click();// 6. 验证成功提示awaitexpect(page.locator(.el-message--success)).toBeVisible();// 7. 验证列表中出现新零件awaitexpect(page.locator(td:has-text(E2E测试零件))).toBeVisible();});对比总结我的项目中的测试最佳实践