What is Konsist?

Konsist is a structural linter (static code analyzer) designed for Kotlin language. Verifying codebase with Konsist enables development teams to enforce architectural rules and class structures through automated testing.
Konsist offers comprehensive verification capabilities that enable developers to enforce architectural rules and maintain code consistency, thereby improving the readability and maintainability of the code. It's like ArchUnit, but for Kotlin language. Whether you're working on Android, Spring, or Kotlin Multiplatform projects, Konsist has got you covered.
The Konsist API provides developers with the capability to create custom checks through unit tests, customized to align with the project's unique requirements. Additionally, it offers smooth integration with leading testing frameworks, including JUnit4, JUnit5, and Kotest, further streamlining the development process.
Konsist offers two types of checks, namely Declaration Checks and ArchitecturalChecks, to thoroughly evaluate the codebase.
Declaration Checks
The first type involves declaration checks, where custom tests are created to identify common issues and violations at the declaration level (classes, functions, properties, etc.). These cover various aspects such as class naming, package structure, visibility modifiers, presence of annotations, etc. Here are a few ideas of things to check:
Every child class extending
ViewModel
must haveViewModel
suffixClasses with the
@Repository
annotation should reside in..repository..
packageEvery class constructor has alphabetically ordered parameters
Every constructor parameter has a name derived from the class name
Field injection and
m
prefix is forbiddenEvery public member in
api
package must be documented with KDocand more...
Here is a sample test that verifies if every use case class resides in domain.usecase
package:
class UseCaseKonsistTest {
@Test
fun `every use case reside in use case package`() {
Konsist
.scopeFromProject() // Define the scope containing all Kotlin files present in the project
.classes() // Get all class declarations
.withNameEndingWith("UseCase") // Filter classes heaving name ending with 'UseCase'
.assertTrue { it.resideInPackage("..domain.usecase..") } // Assert that each class resides in 'any domain.usecase any' package
}
}
ArchitecturalChecks
The second type of Konsist checks revolves around architecture boundaries - they are intended to maintain the separation of concerns between layers.
Consider this simple 3 layer of Clean Architecture:
The
domain
layer is independentThe
data
layer depends ondomain
layerThe
presentation
layer depends ondomain
layeretc.
Here is a Konsist test that verifies if Clean Architecture dependency requirements are valid:
class ArchitectureTest {
@Test
fun `clean architecture layers have correct dependencies`() {
Konsist
.scopeFromProject() // Define the scope containing all Kotlin files present in project
.assertArchitecture { // Assert architecture
// Define layers
val domain = Layer("Domain", "com.myapp.domain..")
val presentation = Layer("Presentation", "com.myapp.presentation..")
val data = Layer("Data", "com.myapp.data..")
// Define architecture assertions
domain.dependsOnNothing()
presentation.dependsOn(domain)
data.dependsOn(domain)
}
}
}
Summary
By utilizing Konsist, teams can be confident that their Kotlin codebase remains standardized and aligned with best practices, making code reviews more efficient and code maintenance smoother.
Last updated