Saat proyek membesar, kita sering perlu memisahkan kode produksi dari kode pengujian, atau memisahkan kode yang berjalan di platform berbeda. Mekanisme Gradle untuk itu disebut source set. Pada chapter ini kita akan membahas konsep source set, source set bawaan (main dan test), cara mendefinisikan source set kustom, serta source set khusus Kotlin Multiplatform seperti commonMain dan jvmMain. Pemahaman ini penting untuk mengorganisasi proyek Gradle yang sehat.
Apa Itu Source Set #
Source set adalah kumpulan direktori sumber beserta konfigurasi dependensi yang di-compile menjadi output terpisah. Gradle secara default menyediakan dua source set:
main: kode produksi. Di-compile kebuild/classes/kotlin/main.test: kode uji. Di-compile kebuild/classes/kotlin/test; hanya berjalan saat tasktest.
Kode pada test dapat memanggil kode main, tetapi tidak sebaliknya. Classpath kedua source set juga berbeda — test biasanya memiliki dependensi tambahan seperti JUnit, Kotest, atau MockK.
Struktur Direktori Standar #
Konvensi Gradle + Kotlin:
src/
├── main/
│ ├── kotlin/ ← kode produksi Kotlin
│ └── resources/ ← file resource (application.conf, dll.)
└── test/
├── kotlin/ ← kode uji Kotlin
└── resources/ ← resource uji (fixture, file JSON)Pada Kotlin Multiplatform (KMP), struktur diperluas dengan target:
src/
├── commonMain/kotlin/ ← kode lintas-platform
├── commonTest/kotlin/ ← uji kode commonMain
├── jvmMain/kotlin/ ← kode khusus JVM
├── jvmTest/kotlin/ ← uji kode jvmMain
├── jsMain/kotlin/ ← kode khusus JS
└── nativeMain/kotlin/ ← kode khusus NativeContoh Kode #
Berikut program kecil yang memperlihatkan pemisahan logika produksi dan logika pengujian secara konseptual:
// File: source_sets.kt
// Mendemonstrasikan konsep source set via simulasi runtime.
// Pada Gradle, source set adalah kumpulan direktori sumber yang di-compile
// menjadi output terpisah. Kotlin memperlakukan main/ dan test/ sebagai
// dua source set berbeda dengan classpath masing-masing.
package com.example.sourceset
import java.time.LocalDate
// Sumber di src/main/kotlin (production code).
data class ItemTugas(val judul: String, val tenggat: LocalDate, val selesai: Boolean = false) {
fun ringkas(): String {
val status = if (selesai) "selesai" else "belum"
return "[$status] $judul — tenggat ${tenggat}"
}
}
// Sumber di src/test/kotlin (test code). Pada proyek nyata fungsi ini
// ditempatkan pada source set test/ dan hanya di-compile saat test.
object TesSimulasi {
fun verifikasiRingkas(): Boolean {
val tugas = ItemTugas("Review", LocalDate.of(2026, 3, 1), selesai = true)
return tugas.ringkas().contains("[selesai]")
}
}
fun main() {
val tugas1 = ItemTugas("Tulis laporan", LocalDate.of(2026, 3, 1))
val tugas2 = ItemTugas("Review kode", LocalDate.of(2026, 3, 5), selesai = true)
println(tugas1.ringkas())
println(tugas2.ringkas())
println("Tes verifikasi ringkas: ${TesSimulasi.verifikasiRingkas()}")
println("Struktur source set:")
println(" src/main/kotlin -> output: build/classes/kotlin/main")
println(" src/test/kotlin -> output: build/classes/kotlin/test")
println(" src/jvmMain/kotlin (KMP) -> build/classes/kotlin/jvmMain")
}Output yang Dihasilkan:
[belum] Tulis laporan — tenggat 2026-03-01
[selesai] Review kode — tenggat 2026-03-05
Tes verifikasi ringkas: true
Struktur source set:
src/main/kotlin -> output: build/classes/kotlin/main
src/test/kotlin -> output: build/classes/kotlin/test
src/jvmMain/kotlin (KMP) -> build/classes/kotlin/jvmMainMari kita bedah kode di atas:
- Baris 11 (
data class ItemTugas): tipe produksi padasrc/main/kotlin. Setiap file yang memakaiItemTugaspadamainatautestdapat mengaksesnya karenatestmelihat classpathmain. - Baris 19-23 (
object TesSimulasi): menunjukkan kode yang seharusnya berada padasrc/test/kotlin.TesSimulasi.verifikasiRingkas()menguji methodringkas(). Pada proyek nyata, object ini akan ditempatkan pada file uji terpisah dan dianotasi@Test. - Baris 25-33 (
fun main): titik masuk produksi. MemakaiItemTugasdanTesSimulasiuntuk demonstrasi. - Baris 29-33 (println struktur source set): mencetak informasi struktur direktori source set agar pembaca melihat relasi sumber-output secara visual.
Source Set Kustom #
Kita dapat mendefinisikan source set kustom pada build.gradle.kts. Misalnya, untuk memisahkan kode demo:
sourceSets {
create("demo") {
kotlin.srcDir("src/demo/kotlin")
}
}
dependencies {
"demoImplementation"(project(":core"))
"demoImplementation"("io.github.microutils:kotlin-logging:3.0.5")
}Konfigurasi di atas membuat source set demo dengan direktori sendiri dan dependensi sendiri. Output akan di-compile ke build/classes/kotlin/demo.
Source Set pada Kotlin Multiplatform #
Pada KMP, commonMain berisi kode yang berjalan di semua target. Source set target seperti jvmMain, jsMain, nativeMain berisi kode khusus platform. Kompilator memastikan bahwa kode commonMain tidak memakai API yang tidak tersedia di semua target.
Referensi Lanjutan #
- Gradle — panduan resmi Gradle untuk Kotlin source set
- Gradle User Guide — dokumentasi Gradle source set dan organisasi source
- Version Catalogs — Gradle version catalogs untuk koordinasi dependency antar source set
Selanjutnya #
Setelah memahami source set, kita akan mendalami modifier internal yang merupakan penerapan langsung konsep modul dan source set — topik chapter internal Visibility.