高级营销网站建设只需1200元,网站后缀cc,网站站点不安全,网易那个自己做游戏的网站是什么大家好#xff0c;我是鱼皮#xff0c;很多初学编程的同学都会认为 “程序员的工作只有开发新功能#xff0c;功能做完了就完事儿”。但其实不然#xff0c;保证程序的正常运行、提高程序的稳定性和质量也是程序员的核心工作。
之前给大家分享过企业项目的完整开发流程我是鱼皮很多初学编程的同学都会认为 “程序员的工作只有开发新功能功能做完了就完事儿”。但其实不然保证程序的正常运行、提高程序的稳定性和质量也是程序员的核心工作。
之前给大家分享过企业项目的完整开发流程其中有一个关键步骤叫 “单元测试”这篇文章就来聊聊程序员如何编写单元测试吧。
什么是单元测试
单元测试Unit Testing简称 UT是软件测试的一种通常由开发者编写测试代码并运行。相比于其他的测试类型比如系统测试、验收测试它关注的是软件的 最小 可测试单元。
什么意思呢
假如我们要实现用户注册功能可能包含很多个子步骤比如
校验用户输入是否合法校验用户是否已注册向数据库中添加新用户
其中每个子步骤可能都是一个小方法。如果我们要保证用户注册功能的正确可用那么就不能只测试注册成功的情况而是要尽量将每个子步骤都覆盖到分别针对每个小方法做测试。比如输入各种不同的账号密码组合来验证 “校验用户输入是否合法” 这一步骤在成功和失败时的表现是否符合预期。
同理如果我们要开发一个很复杂的系统可能包含很多小功能每个小功能都是一个单独的类我们也需要针对每个类编写单元测试。因为只有保证每个小功能都是正确的整个复杂的系统才能正确运行。
单元测试的几个核心要点是
最小化测试范围单元测试通常只测试代码的一个非常小的部分以确保测试的简单和准确。自动化单元测试应该是自动化的开发人员可以随时运行它们来验证代码的正确性特别是在修改代码后。而不是每次都需要人工去检查。快速执行每个单元测试的执行时间不能过长应该尽量做到轻量、有利于频繁执行。独立性每个单元测试应该独立于其他测试不依赖于外部系统或状态以确保测试的可靠性和可重复性。
为什么需要单元测试
通过编写和运行单元测试开发者能够快速验证代码的各个部分是否按照预期工作有利于保证系统功能的正确可用这是单元测试的核心作用。
此外单元测试还有很多好处比如
1改进代码编写单元测试的过程中开发者能够再次审视业务流程和功能的实现更容易发现一些代码上的问题。比如将复杂的模块进一步拆解为可测试的单元。
2利于重构如果已经编写了一套可自动执行的单元测试代码那么每次修改代码或重构后只需要再自动执行一遍单元测试就知道修改是否正确了能够大幅提高效率和项目稳定性。
3文档沉淀编写详细的单元测试本身也可以作为一种文档说明代码的预期行为。
鱼皮以自己的一个实际开发工作来举例单元测试的重要性。我曾经编写过一个 SQL 语法解析模块需要将 10000 多条链式调用的语法转换成标准的 SQL 语句。但由于细节很多每次改进算法后我都不能保证转换 100% 正确总会人工发现那么几个错误。所以我编写了一个单元测试来自动验证解析是否正确每次改完代码后执行一次就知道解析是否完全成功了。大幅提高效率。
所以无论是后端还是前端程序员都建议把编写单元测试当做一种习惯真的能够有效提升自己的编码质量。
如何编写单元测试
以 Java 开发为例我们来学习如何编写单元测试。
Java 开发中最流行的单元测试框架当属 JUnit 了它提供了一系列的类和方法可以帮助我们快速检验代码的行为。
1、引入 JUnit
首先我们要在项目中引入 JUnit演示 2 种方式
Maven 项目引入
在 pom.xml 文件中引入 JUnit 4 的依赖
dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.13.2/versionscopetest/scope
/dependencySpring Boot 项目引入
如果在 Spring Boot 中使用 JUnit 单元测试直接引入 spring-boot-starter-test 包即可
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope
/dependency然后会自动引入 JUnit Jupiter它是 JUnit 5新版本的一部分提供了全新的编写和执行单元测试的方式更灵活易用。不过学习成本极低会用 JUnit 4基本就会用 JUnit Jupiter。
2、编写单元测试
编写一个单元测试通常包括三个步骤准备测试数据、执行要测试的代码、验证结果。
一般来说每个类对应一个单元测试类每个方法对应一个单元测试方法。
编写 JUnit 单元测试
比如我们要测试一个计算器的求和功能示例代码如下
import org.junit.Test;
import org.junit.Assert;public class CalculatorTest {// 通过 Test 注解标识测试方法Testpublic void testAdd() {// 准备测试数据long a 2;long b 3;// 执行要测试的代码Calculator calculator new Calculator();int result calculator.add(2, 3);// 验证结果Assert.assertEquals(5, result);}
}上述代码中的 Assert 类是关键提供了很多断言方法比如 assertEquals是否相等、assertNull是否为空等用来对比程序实际输出的值和我们预期的值是否一致。
如果结果正确会看到如下输出 如果结果错误输出如下能够清晰地看到执行结果的差异 Spring Boot 项目单测
如果是 Spring Boot 项目我们经常需要对 Mapper 和 Service Bean 进行测试则需要使用 SpringBootTest 注解来标识单元测试类以开启对依赖注入的支持。
以测试用户注册功能为例示例代码如下
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;SpringBootTest
public class UserServiceTest {Resourceprivate UserService userService;Testvoid userRegister() {// 准备数据String userAccount yupi;String userPassword ;String checkPassword 123456;// 执行测试long result userService.userRegister(userAccount, userPassword, checkPassword);// 验证结果Assertions.assertEquals(-1, result);// 再准备一组数据重复测试流程userAccount yu;result userService.userRegister(userAccount, userPassword, checkPassword);Assertions.assertEquals(-1, result);}
}3、生成测试报告
如果系统的单元测试数量非常多比如 1000 个那么只验证某个单元测试用例是否正确、查看单个结果是不够的我们需要一份全面完整的单元测试报告便于查看单元测试覆盖度、评估测试效果和定位问题。
测试覆盖度 是衡量测试过程中被测试到的代码量的一个指标一般情况下越高越好。测试覆盖度 100% 表示整个系统中所有的方法和关键语句都被测试到了。
下面推荐 2 种生成单元测试报告的方法。
使用 IDEA 生成单测报告
直接在 IDEA 开发工具中选择 Run xxx with Coverage 执行单元测试类 然后就能看到测试覆盖度报告了如下图 显然 Main 方法没有被测试到所以显示 0%。
除了在开发工具中查看测试报告外还可以导出报告为 HTML 文档 导出后会得到一个 HTML 静态文件目录打开 index.html 就能在浏览器中查看更详细的单元测试报告了 这种方式简单灵活不用安装任何插件比较推荐大家日常学习使用。
使用 jacoco 生成单测报告
JaCoCo 是一个常用的 Java 代码覆盖度工具能够自动根据单元测试执行结果生成详细的单测报告。
它的用法也很简单推荐按照官方文档中的步骤使用。
官方文档指路https://www.eclemma.org/jacoco/trunk/doc/maven.html
首先在 Maven 的 pom.xml 文件中引入
plugingroupIdorg.jacoco/groupIdartifactIdjacoco-maven-plugin/artifactIdversion0.8.11/version
/plugin当然只引入 JaCoCo 插件还是不够的我们通常希望在执行单元测试后生成报告所以还要增加 executions 执行配置示例代码如下
plugingroupIdorg.jacoco/groupIdartifactIdjacoco-maven-plugin/artifactIdversion0.8.11/versionconfigurationincludesincludecom/**/*/include/includes/configurationexecutionsexecutionidpre-test/idgoalsgoalprepare-agent/goal/goals/executionexecutionidpost-test/idphasetest/phasegoalsgoalreport/goal/goals/execution/executions
/plugin然后执行 Maven 的 test 命令进行单元测试 测试结束后就能够在 target 目录中看到生成的 JaCoCo 单元测试报告网站了 打开网站的 index.html 文件就能看到具体的测试报告结果非常清晰 通常这种方式会更适用于企业中配置流水线来自动化生成测试报告的场景。
实践
编程导航星球的用户中心项目详细讲解了如何使用 JUnit 编写规范的单元测试。 编程导航原创项目教程系列https://yuyuanweb.feishu.cn/wiki/SePYwTc9tipQiCktw7Uc7kujnCd