Testing y diagramas de arquitectura
Testing
JUnit Platform, cobertura encadenada al test, y logging de eventos.
tasks.withType<Test> { useJUnitPlatform() finalizedBy("jacocoTestReport")}
tasks.named<Test>("test") { testLogging { events("passed", "skipped", "failed") }}Dependencias de test — unit, ArchUnit para boundaries hexagonales, y libs de
integración pineadas por property(...):
dependencies { testImplementation("org.mockito:mockito-junit-jupiter") testImplementation("org.junit.jupiter:junit-jupiter-engine") testImplementation("com.tngtech.archunit:archunit-junit5:${property("archunit.version")}") testRuntimeOnly("org.junit.platform:junit-platform-launcher")}archunit.version = 1.3.0testcontainers.version = 1.20.4wiremock.version = 3.6.0karate.version = 1.5.0Tip: ArchUnit corre como test normal (archunit-junit5) — los boundaries
(domain sin framework, dependencias apuntando hacia adentro) se validan en el
mismo ./gradlew test, sin paso extra en CI.
Diagramas desde Gradle
PlantUML (class / package)
El plugin plunts.plantuml genera diagramas por módulo desde el bytecode:
classDiagrams { diagram { name("${project.name} Class Diagram") include(packages().withName("io.codehunters")) writeTo(file("$rootDir/architecture/diagrams/${project.name}-class-diagram.puml")) renderTo(file("$rootDir/architecture/diagrams/${project.name}-class-diagram.svg")) } packageDiagram { name("${project.name} Packages Diagram") include(packages().withName("io.codehunters")) writeTo(file("$rootDir/architecture/diagrams/${project.name}-packages-diagram.puml")) renderTo(file("$rootDir/architecture/diagrams/${project.name}-packages-diagram.svg")) }}Structurizr C4 (task custom)
Una configuración dedicada + un JavaExec exportan el workspace Structurizr a
PlantUML/Mermaid. Buen patrón para tooling que no debe contaminar el classpath
del proyecto:
val structurizr: Configuration by configurations.creating { isCanBeResolved = true isCanBeConsumed = false}dependencies { structurizr("com.structurizr:structurizr-dsl:${property("structurizr.version")}") structurizr("com.structurizr:structurizr-export:${property("structurizr.version")}")}
val compileStructurizrExporter by tasks.registering(JavaCompile::class) { source = fileTree("$rootDir/architecture/structurizr/src") classpath = structurizr destinationDirectory.set(layout.buildDirectory.dir("structurizr-classes")) sourceCompatibility = "21"; targetCompatibility = "21"}
tasks.register<JavaExec>("structurizrExport") { description = "Exports Structurizr C4 diagrams to PlantUML and Mermaid" group = "documentation" dependsOn(compileStructurizrExporter) classpath = files(compileStructurizrExporter.get().destinationDirectory) + structurizr mainClass.set("structurizr.StructurizrExporter") args = listOf("$rootDir/architecture/structurizr/workspace.dsl", "$rootDir/architecture/structurizr/export")}Tip: una Configuration aislada (isCanBeConsumed = false) mantiene las deps
de tooling fuera del implementation/runtimeClasspath del artefacto.