6.1.6 Kotlin 项目中的代码质量工具

原文链接: https://kotlinlang.org/docs/jvm-code-analysis.html

6.1.6 Kotlin 项目中的代码质量工具

了解如何把 ktlint、detekt、SonarQube、SonarCloud 和 Kover 等代码质量工具集成到你的 Kotlin 后端项目中。

代码质量工具帮助你落实编码规范、尽早发现缺陷、度量测试覆盖率,并在整个 Kotlin 项目中保持代码质量。本指南演示如何把 ktlint、detekt、SonarQube、SonarCloud 和 Kover 等流行工具集成到基于 Maven 或 Gradle 的后端项目中。

用 ktlint 进行代码格式化

ktlint 是一个 Kotlin linter 和格式化工具,无需额外配置即可落实官方的 Kotlin 编码规范。

ktlint 检查缩进、运算符周围的空格、导入顺序和尾随逗号等规则。一旦发现违规,构建就会失败并给出文件名和行号。除了报告违规,ktlint 还能自动修复一些显而易见的问题。

要把 ktlint 集成到你的项目中:

  1. 把插件添加到构建文件中:

Maven

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14

   <plugin>
       <groupId>com.github.gantsign.maven</groupId>
       <artifactId>ktlint-maven-plugin</artifactId>
       <version>3.7.1</version>
       <executions>
           <execution>
               <id>check</id>
               <goals>
                   <goal>check</goal>
               </goals>
           </execution>
       </executions>
   </plugin>

Gradle

1
2
3
4
   // build.gradle.kts
   plugins {
       id("org.jlleitschuh.gradle.ktlint") version "12.3.0"
   }
  1. 运行 linter 检查代码风格:

Maven

1
   mvn ktlint:check

Gradle

1
   ./gradlew ktlintCheck
  1. (可选)你也可以在项目根目录添加 .editorconfig 文件来自定义规则。例如,允许通配符导入并禁用尾随逗号检查:
1
2
3
4
   [*.{kt,kts}]
   ij_kotlin_imports_layout = *
   ktlint_standard_trailing-comma-on-call-site = disabled
   ktlint_standard_trailing-comma-on-declaration-site = disabled

默认情况下,ktlint 遵循官方 Kotlin 编码规范。如果你更偏好与 Kotlin 规范差异明显的 Android Kotlin 风格指南,请在 .editorconfig 文件中把代码风格设为 android_studio:

1
2
   [*.{kt,kts}]
   ktlint_code_style = android_studio
  1. 要自动修复格式问题,请运行:

Maven

1
   mvn ktlint:format

Gradle

1
   ./gradlew ktlintFormat

关于可用特性和规则的更多信息,请参阅 ktlint 文档。

用 detekt 进行代码分析

detekt 是一个 Kotlin 静态代码分析工具,可以检测代码坏味道、复杂性问题以及潜在缺陷。

要把 detekt 集成到你的项目中:

  1. 把插件添加到构建文件中:

Maven

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14

   <plugin>
       <groupId>com.github.ozsie</groupId>
       <artifactId>detekt-maven-plugin</artifactId>
       <version>1.23.8</version>
       <executions>
           <execution>
               <phase>verify</phase>
               <goals>
                   <goal>check</goal>
               </goals>
           </execution>
       </executions>
   </plugin>

Gradle

1
2
3
4
   // build.gradle.kts
   plugins {
       id("io.gitlab.arturbosch.detekt") version "1.23.8"
   }
  1. 生成默认的 detekt.yml 配置文件:

Maven

1
   mvn detekt:generate-config

Gradle

1
   ./gradlew detektGenerateConfig
  1. 打开 detekt.yml 文件并自定义生成的规则,例如:
1
2
3
4
5
6
   complexity:
     LongMethod:
       threshold: 50
   style:
     MagicNumber:
       active: false
  1. 在构建文件中引用该配置文件,以便 detekt 应用新规则:

Maven

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21

   <plugin>
       <groupId>com.github.ozsie</groupId>
       <artifactId>detekt-maven-plugin</artifactId>
       <version>1.23.8</version>
       <configuration>
           <config>detekt.yml</config>
           <report>
               <report>txt:reports/detekt.txt</report>
               <report>xml:reports/detekt.xml</report>
           </report>
       </configuration>
       <executions>
           <execution>
               <phase>verify</phase>
               <goals>
                   <goal>check</goal>
               </goals>
           </execution>
       </executions>
   </plugin>

Gradle

1
2
3
4
5
6
   // build.gradle.kts
   detekt {
       toolVersion = "1.23.8"
       config.setFrom(file("config/detekt/detekt.yml"))
       buildUponDefaultConfig = true
   }
  1. 运行分析:

Maven

1
   mvn detekt:check

Gradle

1
   ./gradlew detekt

detekt 会生成一份报告,列出所有规则违规及其严重程度、文件位置和问题描述。默认情况下,Gradle 把报告输出到 build/reports/detekt,Maven 则输出到项目根目录下的 reports/detekt 目录。

更多信息请参阅 detekt 针对 Gradle 和 Maven 的文档。

使用 SonarSource 提升代码质量

SonarSource 的 SonarQube 和 SonarCloud 为 Kotlin 项目提供深度静态分析,包括缺陷检测、漏洞扫描,以及通过 Web 仪表盘跟踪代码覆盖率。

要用 SonarQube 分析你的项目:

  1. 把插件添加到构建文件中:

Maven

1
2
3
4
5
6

   <plugin>
       <groupId>org.sonarsource.scanner.maven</groupId>
       <artifactId>sonar-maven-plugin</artifactId>
       <version>5.7.0.6970</version>
   </plugin>

Gradle

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
   // build.gradle.kts
   plugins {
       id("org.sonarqube") version "6.2.0.5505"
   }

   sonar {
       properties {
           property("sonar.projectKey", "my-project")
           property("sonar.host.url", "http://localhost:9000")
       }
   }
  1. (可选)配置分析属性。例如,让构建等待质量门结果、并在未通过质量门时失败,可以添加 sonar.qualitygate.wait 属性:

Maven

1
2
3
4
5
   mvn verify sonar:sonar \
     -Dsonar.qualitygate.wait=true \
     -Dsonar.projectKey=my-project \
     -Dsonar.host.url=http: // -Dsonar.host.url=http://localhost:9000
     -Dsonar.token=YOUR_TOKEN

Gradle

1
2
3
4
5
6
   // build.gradle.kts
   sonar {
       properties {
           property("sonar.qualitygate.wait", "true")
       }
   }

注意: 质量门规则(例如最低覆盖率阈值和允许的问题数量)是在 SonarQube 或 SonarCloud 的 Web 界面中的 Quality Gates 下定义的,而不是在构建文件中。

  1. 针对你的 SonarQube 服务器运行分析:

Maven

1
2
3
4
   mvn verify sonar:sonar \
     -Dsonar.projectKey=my-project \
     -Dsonar.host.url=http: // -Dsonar.host.url=http://localhost:9000
     -Dsonar.token=YOUR_TOKEN

对于 SonarCloud,请把主机 URL 替换为 https://sonarcloud.io 并提供你的组织键:

1
2
3
4
5
   mvn verify sonar:sonar \
     -Dsonar.projectKey=my-project \
     -Dsonar.organization=my-org \
     -Dsonar.host.url=https: // -Dsonar.host.url=https://sonarcloud.io
     -Dsonar.token=YOUR_TOKEN

Gradle

要运行分析,请使用 sonar 任务并提供你的认证令牌:

1
2
   ./gradlew sonar \
     -Dsonar.token=YOUR_TOKEN

默认情况下,分析针对本地 SonarQube 服务器运行。要使用 SonarCloud,请更新 build.gradle.kts 中的 sonar {} 块,改用 https://sonarcloud.io 并添加你的组织键:

1
2
3
4
5
6
7
   sonar {
       properties {
           property("sonar.projectKey", "example-project")
           property("sonar.organization", "example-org")
           property("sonar.host.url", "https://sonarcloud.io")
       }
   }
  1. 打开 SonarQube 或 SonarCloud 仪表盘查看结果。仪表盘按类型(缺陷、漏洞、代码坏味道)和严重程度对问题分组。

更多信息请参阅 SonarSource 文档。

用 Kover 统计代码覆盖率

Kover 是 JetBrains 官方的 Kotlin 代码覆盖率工具。它度量代码中哪些行和分支被测试覆盖,并生成人类可读的报告。

与 JaCoCo 不同,Kover 能正确解释内联函数、数据类等 Kotlin 特有结构,因此给出的覆盖率数字准确,不会因编译器生成的字节码而出现误判的未覆盖项。

要把 Kover 集成到你的项目中:

  1. 把插件添加到构建文件中:

Maven

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

   <plugin>
       <groupId>org.jetbrains.kotlinx</groupId>
       <artifactId>kover-maven-plugin</artifactId>
       <version>0.9.8</version>
       <executions>
           <execution>
               <id>instr</id>
               <goals>
                   <goal>instrumentation</goal>
               </goals>
           </execution>
           <execution>
               <id>kover-verify</id>
               <goals>
                  <goal>verify</goal>
               </goals>
           </execution>
           <execution>
               <id>kover-report-xml</id>
               <goals>
                   <goal>report-xml</goal>
               </goals>
           </execution>
           <execution>
               <id>kover-report-html</id>
               <goals>
                   <goal>report-html</goal>
               </goals>
           </execution>
       </executions>
   </plugin>

Gradle

1
2
3
4
   // build.gradle.kts
   plugins {
       id("org.jetbrains.kotlinx.kover") version "0.9.8"
   }
  1. 运行测试以收集覆盖率数据并生成报告:

Maven

1
   mvn verify

Gradle

1
   ./gradlew koverVerify koverHtmlReport
  1. 打开 target/site/kover/html/ 目录(Gradle 为 build/reports/kover/html/)中生成的 HTML 报告,逐行查看覆盖率。
  2. (可选)如果要强制最低覆盖率阈值、在条件不满足时让构建失败,可以在构建文件中添加覆盖率校验配置。例如:

Maven

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15

   <configuration>

     <rules>
         <rule>
             <bounds>
                 <bound>
                     <minValue>50</minValue>
                     <coverageUnits>LINE</coverageUnits>
                     <aggregationForGroup>COVERED_PERCENTAGE</aggregationForGroup>
                 </bound>
             </bounds>
         </rule>
     </rules>
   </configuration>

Gradle

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
   // build.gradle.kts
   // 添加一个 `kover` 配置块
   import kotlinx.kover.gradle.plugin.dsl.*

   kover {
       reports {
           total {
               log {
                   aggregationForGroup = AggregationType.COVERED_PERCENTAGE
                   coverageUnits = CoverageUnit.LINE
               }
               verify {
                   rule {
                       minBound(50)
                   }
               }
           }
       }
   }

关于配置校验规则的更多信息,请参阅 Kover 针对 Maven 和 Gradle 的文档。

其他工具

除 ktlint、detekt、SonarQube、SonarCloud 和 Kover 之外,你还可以尝试其他工具来提升 Kotlin 代码质量:

| 工具 | 说明 |

| CodeQL | GitHub 的语义代码分析引擎。支持 Kotlin,并与 GitHub Actions 集成,可自动发现安全漏洞。 | | Semgrep | 快速、轻量的静态分析工具,支持自定义规则。可用于在 Kotlin 代码中强制执行某些模式或检测反模式。 | | PMD | 源代码分析器,支持 Kotlin(通过其 CPD 复制粘贴检测器),可发现常见编程缺陷和重复代码。 |

接下来学什么