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
  • Existing Test Source Set
  • Dedicated konsistTest Source Set
  • Dedicated Gradle Module
  • Add Gradle konsistTest Module:
  • Running Konsist Tests Stored In A Dedicated Gradle Module
Edit on GitHub
Export as PDF
  1. ADVANCED

Isolate Konsist Tests

Aim for better test separation.

PreviousGeneric Types SnippetsNextEnable Full Command Line Logging

Last updated 7 months ago

Typically, it's advisable to consolidate all Konsist tests in a unified location. This approach is preferred because these tests are often designed to validate the structure of the entire project's codebase. There are three potential options for storing Konsist tests in project codebase:

Android
Spring
KMP
Pure Kotlin

✅

✅

✅

✅

❌

✅

✅

✅

✅

✅

✅

✅

Recommended approach is to use Dedicated konsistTest Source Set or a #dedicated-module. These approaches allows to easily isolate Konsist tests from other types of tests e.g. separate unit tests from Konsist tests.

Existing Test Source Set

The Konsist library can be added to the project by adding the dependency on the existing test source set .

To execute tests run ./gradlew test command.

The downside of this approach is that various types of tests are mixed in test source set e.g. unit tests and Konsist tests.

Dedicated konsistTest Source Set

This section demonstrates how to add the konsistTest test source directory inside the app module. This configuration is mostly useful for Spring and Kotlin projects.

This page describes the test located in the app module with the build config file located in app a folder. If the project does not contain any module then configuration should be applied in the root build config file.

This test directory will have a kotlin folder containing Kotlin code.

// build.gradle.kts (root)

plugins {
    `jvm-test-suite`
}

testing {
    suites {
        register("konsistTest", JvmTestSuite::class) {
            dependencies {
                // Add 'main' source set dependency
                implementation(project())
                
                // Add Konsist dependency
                implementation("com.lemonappdev:konsist:0.13.0") 
            }
        }
    }
}

// Optional : Remove Konsist tests from the 'check' task if it exists
tasks.matching { it.name == "check" }.configureEach {
  setDependsOn(dependsOn.filter { it.toString() != "konsistTest" })
}
// build.gradle (root)

plugins {
    id 'jvm-test-suite'
}

testing {
    suites { 
        test { 
            useJUnitJupiter() 
        }

        konsistTest(JvmTestSuite) { 
            dependencies {
                // Add 'main' source set dependency
                implementation project() 
                
                // Add Konsist dependency
                implementation "com.lemonappdev:konsist:0.13.0"
            }

            targets { 
                all {
                    testTask.configure {
                        shouldRunAfter(test)
                    }
                }
            }
        }
    }
}

// Optional: Remove Konsist tests from the 'check' task if it exists
tasks.matching { it.name == "check" }.configureEach { task ->
    task.setDependsOn(task.getDependsOn().findAll { it.toString() != "konsistTest" })
}
# app/pom.xml

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>3.3.0</version>
    <executions>
        <execution>
            <id>add-konsist-test-source</id>
            <phase>generate-test-sources</phase>
            <goals>
                <goal>add-test-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>${project.basedir}/src/konsistTest/kotlin</source>
                </sources>
            </configuration>
        </execution>
    </executions>
</plugin>

Create app/src/konsistTest/kotlin folder and reload the project. The IDE will present a new konsistTest source set in the app module.

The konsistTest test source folder works exactly like the build-in test source folder, so Kosist tests can be defined and executed in a similar way:

./gradlew app:konsistTest
mvn test

Dedicated Gradle Module

This section demonstrates how to add the konsistTest module to the project. This configuration is primarily helpful for Android projects and Kotlin Multiplatform (KMP) projects, however, this approach will also work with Spring and pure Kotlin projects.

Add Gradle konsistTest Module:

Create konsistTest/src/test/kotlin directory in the project root:

Add module include inside settings.gradle.kts file:

// settings.gradle.kts
include(":konsistTest")

Create konsistTest/src/test/kotlin directory in the project root:

Add module include inside settings.gradle.kts file:

// settings.gradle
include ':konsistTest'

For Android projects add com.android.library plugin in the konsistTest/scr/test/kotlin/build.gradle file.

Refresh/Sync the Gradle Project in IDE.

Running Konsist Tests Stored In A Dedicated Gradle Module

Gradle's default behavior assumes that a module's code is up-to-date if the module itself hasn't been modified. This can lead to issues when Konsist tests are placed in a separate module. In such cases, Gradle may skip these tests, believing they're unnecessary.

However, this approach doesn't align well with Konsist's functionality. Konsist analyzes the entire codebase, not just individual modules. As a result, when Gradle skips Konsist tests based on its module-level change detection, it fails to account for potential changes in other modules that Konsist would typically examine.

There are few solutions to this problem.

Solution 1: Module Is Always Out of Date

An alternative solution for this problem is to define konsistTest module as always being out of date:

// konsistTest/build.gradle.kts

tasks.withType<Test> {
    outputs.upToDateWhen { false }
}
// konsistTest/build.gradle

tasks.withType(Test) {
    outputs.upToDateWhen { false }
}

Solution 2: Flag --rerun-tasks

To execute all unit tests besides tests in the konsistTest module run:

./gradlew test -x konsistTest:test

To avoid manually passing --rerun-tasks flag each time a custom konsistCheck task can be added to the root build config file:

Add to root build.gradle.kts:

tasks.register("konsistCheck") {
    group = "verification"
    description = "Runs Konsist static code analysis"

    doLast {
        val output = ByteArrayOutputStream()
        val result = project.exec {
            commandLine("./gradlew", "konsistTest:test", "--rerun-tasks")
            standardOutput = output
            errorOutput = output
            isIgnoreExitValue = true
        }

        println(output.toString())

        if (result.exitValue != 0) {
            throw GradleException("Konsist tests failed")
        }
    }
}

Add to root build.gradle:

tasks.register("konsistCheck") {
    group = "verification"
    description = "Runs Konsist static code analysis"

    doLast {
        def output = new ByteArrayOutputStream()
        def result = project . exec {
            commandLine './gradlew', 'konsistTest:test', '--rerun-tasks'
            standardOutput = output
            errorOutput = output
            ignoreExitValue = true
        }

        println output . toString ()

        if (result.exitValue != 0) {
            throw new GradleException ("Konsist tests failed")
        }
    }
}

After adding konsistCheck task run ./gradlew konsistCheck to execute all Konsist tests.

Use the Gradle built-in to define the konsistTest source set. Add a testing block to the project configuration:

Use the Gradle built-in to define the konsistTest source set. Add a testing block to the project configuration:

Use the to define the konsistTest test source directory. Add plugin config to the project configuration:

The is used to build Android apps. The Android Gradle Plugin is not compatible with the and it does not allow adding new source sets. To fully isolate tests a new module is required.

The project contains modules with code for different platforms. To decouple Konsist tests from a single platform dedicated module containing Konsist test should be added.

🎓
JVM Test Suite Plugin
JVM Test Suite Plugin
Maven Build Helper Plugin
Android Gradle Plugin
JVM Test Suite Plugin
Kotlin Multiplatform
Existing Test Source Set
#dedicated-konsist-test-source-set
#dedicated-module
test sorce directory
konsistTest sorce directory