Create Secound Konsist Test - Architectural Check

Konsist's Architectural Checks serve as a robust tool for maintaining layer isolation, enabling development teams to enforce strict boundaries between different architectural layers. Here few things that can be verified with Konsist:

  • domain layer is independant

  • data layer depends on domain layer

  • ...

See Architecture Snippetssection for more examples.

Write First Architectural Check

Let's write a simple test to verify that application architecture rules are preserved. In this scenario, the application follows a simple 3-layer architecture, where Presentation and Data layers depend on Domain layer and Domain layer is independant (from these layers):

Overview

On a high level writing Konsist architectural check requires 3 steps:

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

1. Define Layers

Create layers instances to represent project layers. Each Layer instance accepts the name (used for presenting architecture violation errors) and package used to define layers.

// Define layers
private val presentationLayer = Layer("Presentation", "com.myapp.presentation..")
private val domainLayer = Layer("Domain", "com.myapp.domain..")
private val dataLayer = Layer("Data", "com.myapp.data..")

The double dot syntax (..) means zero or more packages - layer is represented by the package and all of it's sub packages (seePackage Wildcard syntax).

2. Create The Scope

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 layers
private val presentationLayer = Layer("Presentation", "com.myapp.presentation..")
private val domainLayer = Layer("Domain", "com.myapp.domain..")
private val dataLayer = Layer("Data", "com.myapp.data..")
 
// 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.

3. Assert Architecture

To performa assertion use the assertArchiteture method:

// Define layers
private val presentationLayer = Layer("Presentation", "com.myapp.presentation..")
private val domainLayer = Layer("Domain", "com.myapp.domain..")
private val dataLayer = Layer("Data", "com.myapp.data..")

Konsist
    .scopeFromProject()
     // Assert architecture
    .assertArchitecture {
        // Define architectural rules
    }

Utilize dependsX methods to validate that your project's layers adhere to the defined architectural dependencies:

Konsist
    .scopeFromProject()
    .assertArchitecture {
        private val presentationLayer = Layer("Presentation", "com.myapp.presentation..")
        private val domainLayer = Layer("Domain", "com.myapp.business..")
        private val dataLayer = Layer("Data", "com.myapp.data..")

        // Define layer dependnecies
        presentationLayer.dependsOn(domainLayer)
        dataLayer.dependsOn(domainLayer)
        domainLayer.dependsOnNothing()
    }

Wrap Konsist Code In Test

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

class ArchitectureKonsistTest {
    @Test
    fun `architecture layers have dependencies correct`() {
        Konsist
            .scopeFromProject()
            .assertArchitecture {
                private val presentationLayer = Layer("Presentation", "com.myapp.presentation..")
                private val domainLayer = Layer("Domain", "com.myapp.business..")
                private val dataLayer = Layer("Data", "com.myapp.data..")
        
                // Define layer dependnecies
                presentationLayer.dependsOn(domainLayer)
                dataLayer.dependsOn(domainLayer)
                domainLayer.dependsOnNothing()
            }
    }
}

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

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 architectural test. To get a better understanding of how Konsist API works see Debug Konsist Test.

Last updated