背景介绍
为了长期持续高质量、高效率的迭代,必须遵守一定的研发规范,其中主要包括静态代码的扫描和单元测试两个部分。
风险认知
行业的普遍共识,风险识别暴露的越晚,修复的成本越高。
好代码不是一蹴而就的,是持续重构出来的
目标
技术选型
最佳实践
安装sonarLint
本地IntelliJ IDEA安装sonarlint,根据提示重启IntelliJ IDEA即可
有两个选项:根据本地修改扫描和全量扫描。可以根据实际情况开启。扫描结果如下:
此处扫描出范型约束丢失的可能运行时异常,风险等级为Major。Blocker级别为必须修复,否则打包无法通过。
可以通过右键展开全部:
在代码编写过程中,也可同步识别风险:
在Sonar中展示的代码规则违反分类数量统计,分为5个级别:Blocker、Critical、Major、Minor、Info。其中Blocker、Critical是需要重点避免的。
负责人&核心链路
应用负责人
应用 负责人(待定)
质量标准
应用 代码质量要求/核心链路情况
单测
单元测试是保证持续迭代的重要手段,下面提供应用负责人,与质量标准。
几个要点:
不要为了单测而单测,单测可以发现代码结构的不合理处,反向推动代码优化。
单测需要快速、可重复、不依赖外部数据接口(外部数据不稳定)。
不要滥用mock,外部调用(包括数据库)尽量用个Facade封装,只需要 mock Facade即可。
sqlmap的验证需要启动容器和数据库连接,需要单独测试(后面会写到)。
实战
业务单元测试
我们使用powermock + junit进行mock ,关于使用可以参考我之前写过的一篇文章 点我查看使用,为了避免不可预知的兼容性问题,建议maven版本如下
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.3.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>1.7.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.7.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
我们来测试一个接口
UserController#add:
其主要的流程图
单测的结构
@RunWith(PowerMockRunner.class)
@PrepareForTest({
RequestContextHolder.class}) // 需要 mock 类静态方法,需要在此声明
public class BaseUnitTest {
@Before
public void init() {
System.out.println("start run unit test");
}
/**
* API rpc mock
*/
@Mock // 声明这是 mock bean
private BackendUserApi backendUserApi;
@Mock
private RedisService redisService;
@Mock
private BCryptPasswordEncoder passwordEncoder;
@Before
public void before() {
/*
mock rpc result
*/
BaseResult<Integer> baseResult = new BaseResult<>();
baseResult.setCode(BaseResult.SUCCESS);
baseResult.setData(1);
PowerMockito.when(backendUserApi.addBackendUser(notNull(), notNull())).thenReturn(baseResult);
/*
mock static method http request
*/
PowerMockito.mockStatic(RequestContextHolder.class);
MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();
mockHttpServletRequest.setParameter(AuthConstants.AUTH_HEADER, "test");
ServletRequestAttribut