Konsist
GitHubSlack (kotlinlang)Twitter
  • 🚀GETTING STARTED
    • What is Konsist?
    • Getting Started
      • Add Konsist Dependency
      • Create First Konsist Test - Declaration Check
      • Create Secound Konsist Test - Architectural Check
    • Articles & Videos
  • ✅WRITING TESTS
    • Create The Scope
    • Declaration Filtering
    • Declaration Assertion
    • Architecture Assertion
    • Suppress Konsist Test
  • ✏️VERYFYING CODEBASE
    • Verify Classes
    • Verify Interfaces
    • Verify Functions
    • Verify Properties
    • Verify Generics
    • Verify Source Declarations
  • 📗FEATURES
    • Add Konsist Existing To Project (Baseline)
    • Debug Konsist Test
    • Declaration
    • Declaration Vs Property
    • Compiler Type Inference
    • Package Wildcard
    • Declaration References
    • Indirect Parents
    • Kotest Support
  • 🔍INSPIRATION
    • Starter Projects
    • Snippets
      • General Snippets
      • Android Snippets
      • Spring Snippets
      • Test Snippets
      • JUnit Snippets
      • Kotest Snippets
      • Architecture Snippets
      • Clean Architecture Snippets
      • Kotlin Serialization Snippets
      • Library Snippets
      • Generic Types Snippets
  • 🎓ADVANCED
    • Isolate Konsist Tests
    • Enable Full Command Line Logging
    • Dynamic Konsist Tests
      • Explicit Test Names
    • When Konsist API Is Not Enough
    • Additional JUnit5 Setup
    • Why There Are No Pre-defined Rules?
    • Konsist Snapshots
  • ❓HELP
    • Getting Help
    • Known Issues
      • java.lang.OutOfMemoryError: Java heap space
    • Compatibility
  • ℹ️OTHER
    • Changelog
    • Project Status
    • Contributing
    • Contributors
    • Assets And Logos
    • Open Source Licenses
    • Sponsor Konsist
Powered by GitBook
On this page
  • Write First Declaration Check
  • Overview
  • 1. Create The Scope
  • 2. Retrieve Declarations
  • 3. Filter Declarations
  • 4. Define Assertion
  • Wrap Konsist Code In Test
  • Summary
Edit on GitHub
Export as PDF
  1. GETTING STARTED
  2. Getting Started

Create First Konsist Test - Declaration Check

PreviousAdd Konsist DependencyNextCreate Secound Konsist Test - Architectural Check

Last updated 3 months ago

Konsist Declaration Checks provide a powerful mechanism for validating the structural elements of the Kotlin codebase. These checks allow developers to enforce structural rules and coding conventions by verifying classes, interfaces, functions, properties, and other code declarations. Here few things that can be verified with Konsist:

  • All Use cases should reside in usecase specific package

  • Repository classes must implement Repository interface

  • All repository classes should have name ending with Repository

  • data classes should have only val properties

  • Test classes should have test subject named sut

  • ...

See Snippetssection for more examples.

Write First Declaration Check

Let's write a simple test to verify that all classes (all class declarations) residing in resides in controller package are annotated with the RestController annotation .

Overview

On a high level writing Konsist declaration check requires 4 steps:

Let's take a closer look at each of these steps.

1. Create The Scope

The first step is to get a list of Kotlin files to be verified.

The Konsist object is an entry point to the Konsist library.

Konsist

The scopeFromX methods obtains the instance of the scope containing Kotlin project files. To get all Kotlin project files present in the project use the scopeFromProject method:

 // Define the scope containing all Kotlin files present in the project
Konsist.scopeFromProject() //Returns KoScope

To define more granular scopes such as scope from production code or scope from single module see the Create The Scope page.

2. Retrieve Declarations

Each file in the scope contains set of declarations like classes, properties functions etc. (see Declaration). To write this declaration check for all classes present in the scope query classes using classes method :

Konsist.scopeFromProject()
    // Get scope classes
    .classes() 

3. Filter Declarations

In this project controllers are defined as classes annotated with RestController annotation. Use withAllAnnotationsOf method to filter classes with with RestController annotation:

Konsist.scopeFromProject()
    .classes()
    // Filter classes annotated with 'RestController'
    .withAllAnnotationsOf(RestController::class) 

To perform more granular querying and filtering see the Declaration Filteringpage.

4. Define Assertion

To performa assertion use the assertTrue method:

Konsist.scopeFromProject()
    .classes()
    .withAllAnnotationsOf(RestController::class)
    .assertTrue { 
        // Define the assertion
    } 

To verify that classes are located in the controller package, use the resideInPackage method inside assertTrue block:

Konsist.scopeFromProject()
    .classes()
    .withAllAnnotationsOf(RestController::class)
    .assertTrue { 
       // Check if classes are located in the controller package
        it.resideInPackage("..controller") 
    } 

This verification applies to the entire collection of previously filtered classes, rather than examining just one class in isolation.

To learn more about assertions see Declaration Assertion page.

The double dot syntax (..) means zero or more packages - controller package preceded by any number of packages (seePackage Wildcard syntax).

Wrap Konsist Code In Test

class ControllerClassKonsistTest {
    @Test
    fun `classes annotated with 'RestController' annotation reside in 'controller' package`() {
      // 1. Create a scope representing the whole project (all Kotlin files in project)
            Konsist.scopeFromProject()
            // 2. Retrieve class declarations
            .classes()
            // 3. Filter classes annotated with 'RestController'
            .withAllAnnotationsOf(RestController::class)
            // 4. Define the assertion
            .assertTrue { it.resideInPackage("..controller..") }
    }
}
class ControllerClassKonsistTest : FreeSpec({
    "classes annotated with 'RestController' annotation reside in 'controller' package" {
         Konsist
            // 1. Create a scope representing the whole project (all Kotlin files in project)
            .scopeFromProject()
            // 2. Retrieve class declarations
            .classes() // 2. Get scope classes
            // 3. Filter classes annotated with 'RestController'
            .withAllAnnotationsOf(RestController::class)
            // 4. Define the assertion
            .assertTrue (testName = this.testCase.name.testName) { 
                it.resideInPackage("..controller..") 
            }
    }
})

For Kotest to function correctly the Kotest test name has to be explicitly passed. See theKotest Support page.

Note that test class has a KonsistTest suffix. This is the recommended approach to name classes containing Konsist tests.

Summary

This section described the basic way of writing Konsist declaration test. To get a better understanding of how Konsist API works see https://github.com/LemonAppDev/konsist-documentation/blob/main/getting-started/getting-started/broken-reference/README.md and Debug Konsist Test sections.

The above test will execute multiple assertions per test (all controllers will be verified in a single test). If you prefer better isolation each assertion can be executed as a separate test. See the Dynamic Konsist Tests page.

The declaration validation logic should be protected through automated testing. By wrapping Konsist checks within standard testing frameworks such as or , you can verify these rules with each :

The testing framework project dependency should be added to the project. See to get a complete sample project.

The testing framework project dependency should be added to the project. See to get a complete sample project.

🚀
JUnit
KoTest
Pull Request
JUnit
starter projects
Kotest
starter projects