Kotlin 프로젝트의 코드 품질 도구

Kotlin 프로젝트의 코드 품질 도구 (Code quality tools in Kotlin projects)

코드 품질 도구는 코딩 표준을 강제하고 버그를 일찍 발견하며 테스트 커버리지를 측정하고, Kotlin 프로젝트 전반의 코드 품질을 유지하도록 도와줘요. 이 가이드는 ktlint, detekt, SonarQube, SonarCloud, Kover 같은 인기 도구를 Maven 또는 Gradle 백엔드 프로젝트에 통합하는 방법을 보여 줍니다.

출처: Code quality tools in Kotlin projects

본문

코드 품질 도구는 코딩 표준을 강제하고, 버그를 일찍 잡아내며, 테스트 커버리지를 측정하고, Kotlin 프로젝트 전반의 코드 품질이 유지되도록 돕는 도구예요. 이 가이드에서는 ktlint, detekt, SonarQube, SonarCloud, Kover 같은 널리 쓰이는 도구를 Maven 또는 Gradle 백엔드 프로젝트에 통합하는 방법을 다룹니다.

ktlint로 코드 포맷팅하기

ktlint는 추가 설정 없이 공식 Kotlin 코딩 규약을 강제하는 Kotlin 린터이자 포매터예요.

ktlint는 들여쓰기, 연산자 주변 공백, import 정렬, 후행 쉼표 같은 규칙을 검사해요. 위반이 발견되면 파일과 줄 번호를 알려 주는 메시지와 함께 빌드가 실패합니다. 위반을 보고하는 것 외에도, ktlint는 단순한 문제를 자동으로 고쳐 주기도 해요.

ktlint를 프로젝트에 통합하려면:

  1. 빌드 파일에 플러그인을 추가해요.
<!-- pom.xml -->
<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>
// build.gradle.kts
plugins {
 id("org.jlleitschuh.gradle.ktlint") version "12.3.0"
}
  1. 린터를 실행해서 코드 스타일을 확인해요.
mvn ktlint:check
./gradlew ktlintCheck
  1. (선택) 규칙을 커스터마이즈하려면 프로젝트 루트에 .editorconfig 파일을 추가할 수도 있어요. 예를 들어 와일드카드 import를 허용하고 후행 쉼표 강제를 끄려면:
[*.{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로 설정하세요.

[*.{kt,kts}]
ktlint_code_style = android_studio
  1. 포맷팅 문제를 자동으로 고치려면:
mvn ktlint:format
./gradlew ktlintFormat

제공되는 기능과 규칙에 대한 자세한 내용은 ktlint 문서를 참고하세요.

detekt로 코드 분석하기

detekt는 코드 냄새(code smell), 복잡성 문제, 잠재적 버그를 감지하는 Kotlin용 정적 코드 분석 도구예요.

detekt를 프로젝트에 통합하려면:

  1. 빌드 파일에 플러그인을 추가해요.
<!-- pom.xml -->
<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>
// build.gradle.kts
plugins {
 id("io.gitlab.arturbosch.detekt") version "1.23.8"
}
  1. 기본 detekt.yml 설정 파일을 생성해요.
mvn detekt:generate-config
./gradlew detektGenerateConfig
  1. detekt.yml 파일을 열고 생성된 파일의 규칙을 커스터마이즈해요. 예를 들어:
complexity:
 LongMethod:
 threshold: 50
style:
 MagicNumber:
 active: false
  1. 새 규칙을 적용할 수 있도록 빌드 파일에서 설정 파일을 참조해요.
<!-- pom.xml -->
<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>
// build.gradle.kts
detekt {
 toolVersion = "1.23.8"
 config.setFrom(file("config/detekt/detekt.yml"))
 buildUponDefaultConfig = true
}
  1. 분석을 실행해요.
mvn detekt:check
./gradlew detekt

detekt는 모든 규칙 위반을 심각도, 파일 위치, 문제 설명과 함께 나열한 리포트를 생성해요. 기본적으로 Gradle은 build/reports/detekt에, Maven은 프로젝트 루트의 reports/detekt 디렉터리에 리포트를 출력합니다.

자세한 내용은 GradleMaven용 detekt 문서를 참고하세요.

SonarSource로 코드 품질 관리하기

SonarSource의 SonarQubeSonarCloud는 Kotlin 프로젝트에 버그 감지, 취약점 스캔, 웹 대시보드를 통한 코드 커버리지 추적을 포함한 심층 정적 분석을 제공해요.

SonarQube로 프로젝트를 분석하려면:

  1. 빌드 파일에 플러그인을 추가해요.
<!-- pom.xml -->
<plugin>
 <groupId>org.sonarsource.scanner.maven</groupId>
 <artifactId>sonar-maven-plugin</artifactId>
 <version>5.7.0.6970</version>
</plugin>
// 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. (선택) 분석 속성을 구성해요. 예를 들어 빌드가 품질 게이트(quality gate) 결과를 기다렸다가 게이트를 통과하지 못하면 실패하도록 하려면 sonar.qualitygate.wait 속성을 추가하세요.
mvn verify sonar:sonar \
 -Dsonar.qualitygate.wait=true \
 -Dsonar.projectKey=my-project \
 -Dsonar.host.url=http://localhost:9000 \
 -Dsonar.token=YOUR_TOKEN
// build.gradle.kts
sonar {
 properties {
 property("sonar.qualitygate.wait", "true")
 }
}

품질 게이트 규칙(최소 커버리지 임계값, 허용 이슈 개수 등)은 빌드 파일이 아니라 SonarQube 또는 SonarCloud 웹 인터페이스의 Quality Gates에서 정의됩니다.

  1. SonarQube 서버를 대상으로 분석을 실행해요.
mvn verify sonar:sonar \
 -Dsonar.projectKey=my-project \
 -Dsonar.host.url=http://localhost:9000 \
 -Dsonar.token=YOUR_TOKEN

SonarCloud를 쓴다면 호스트 URL을 https://sonarcloud.io로 바꾸고 조직 키(organization key)를 제공하세요.

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

분석을 실행하려면 sonar 태스크를 사용하고 인증 토큰을 제공하세요.

./gradlew sonar \
 -Dsonar.token=YOUR_TOKEN

기본적으로 분석은 로컬 SonarQube 서버를 대상으로 실행됩니다. SonarCloud를 사용하려면 build.gradle.ktssonar {} 블록을 https://sonarcloud.io를 쓰도록 바꾸고 조직 키를 추가하세요.

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는 Kotlin을 위한 JetBrains 공식 코드 커버리지 도구예요. 테스트가 코드의 어느 줄과 분기를 커버하는지 측정하고 사람이 읽기 쉬운 리포트를 생성합니다.

JaCoCo와 달리 Kover는 인라인 함수나 데이터 클래스 같은 Kotlin 고유 구조를 올바르게 해석하므로, 컴파일러 생성 바이트코드로 인한 오탐(false negative) 없이 정확한 커버리지 수치를 보고해요.

Kover를 프로젝트에 통합하려면:

  1. 빌드 파일에 플러그인을 추가해요.
<!-- pom.xml -->
<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>
// build.gradle.kts
plugins {
 id("org.jetbrains.kotlinx.kover") version "0.9.8"
}
  1. 커버리지 데이터를 모으고 리포트를 생성하려면 테스트를 실행해요.
mvn verify
./gradlew koverVerify koverHtmlReport
  1. target/site/kover/html/ 디렉터리(Gradle은 build/reports/kover/html/)에 생성된 HTML 리포트를 열어 줄 단위 커버리지를 확인해요.

  2. (선택) 조건이 충족되지 않으면 빌드를 실패시키는 최소 커버리지 임계값을 강제하려면 빌드 파일에 커버리지 검증 설정을 추가할 수 있어요. 예를 들어:

<!-- pom.xml -->
<configuration>
 <!-- Create new coverage verification rule -->
 <rules>
 <rule>
 <bounds>
 <bound>
 <minValue>50</minValue>
 <coverageUnits>LINE</coverageUnits>
 <aggregationForGroup>COVERED_PERCENTAGE</aggregationForGroup>
 </bound>
 </bounds>
 </rule>
 </rules>
</configuration>
// build.gradle.kts
// Add a `kover` configuration block
import kotlinx.kover.gradle.plugin.dsl.*

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

검증 규칙 구성에 대한 자세한 내용은 MavenGradle용 Kover 문서를 참고하세요.

다른 도구 (Other tools)

ktlint, detekt, SonarQube, SonarCloud, Kover 외에도 Kotlin 코드 품질을 높이는 다른 도구들을 시도해 볼 수 있어요.

도구 설명
CodeQL GitHub의 시맨틱 코드 분석 엔진. Kotlin을 지원하며 GitHub Actions와 통합되어 보안 취약점을 자동으로 찾습니다.
Semgrep 커스텀 규칙을 지원하는 빠르고 가벼운 정적 분석 도구. Kotlin에서 패턴을 강제하거나 안티 패턴을 감지하는 데 쓰입니다.
PMD Kotlin을 지원(CPD 복사-붙여넣기 감지기 경유)하는 소스 코드 분석기로, 흔한 프로그래밍 결함과 중복 코드를 감지합니다.

다음 단계 (What's next)

더 알아보기 (Learn more)