Madde 2 : TDD Yaklaşımı ile Gradle Eklentisi Geliştirin
Yayınlandı: 24 September 2025
Bu makalede, bir Gradle eklentisi için sağlam bir geliştirme tabanı nasıl kurulacağını test odaklı geliştirme (TDD) yaklaşımıyla inceleyeceğiz. Bu yöntem kodumuzun sağlam, sürdürülebilir olmasını ve gereksinimlerimize tam olarak cevap vermesini başlangıçta sağlar.
1. Proje Başlatma
Gradle, bir eklenti oluşturmayı komutla büyük ölçüde kolaylaştırır.gradle init. Bir "Gradle Plugin" oluşturmak için Kotlin kullanarak seçtiğimizde, hemen kullanılabilir bir proje yapısı elde ederiz; bu, iki tür kritik testi içerir:
-
Birim testleri:içinde bulunan`src/test`, eklentimizin yalıtık bileşenlerini doğrulama imkanı sağlar, görev iç mantığı veya bir eklenti yapılandırması gibi. Hızlı çalışır ve Gradle’nin tam bir yürütülmesini gerektirmez.
-
Fonksiyonel testler :bulunuyorlar`src/functionalTest`kullanırlar`GradleRunner`Geçici bir test projesi içinde tam bir Gradle derlemesi yürütmek için. Bu, kontrollü ortamda eklentinin gerçek davranışını doğrulamamıza olanak tanır.
2. İlk TDD Döngüsü: Bir Görev Kaydetmek
İlk şartımız basittir: eklenti adlandırılmış bir görevi kaydetmelidir.printSiteConfig.
2.1. İlk Test (Başarısız Olan Test)
TDD’ye uygun olarak, bu görevin varlığını kontrol eden bir testi önce yazıyoruz. İçinde`SiteBakerPluginTest.kt`(birim test dosyamızda) ekliyoruz :
@Test
fun `plugin registers task`() {
// Créer un projet de test en mémoire
val project = ProjectBuilder.builder().build()
project.plugins.apply("com.cheroliv.site-baker")
// Vérifier que la tâche a bien été enregistrée
assertNotNull(project.tasks.findByName("printSiteConfig"))
}
Bu test başarısız, çünkü hâlâ pluginimizde hiçbir kod yazmadık.
2.2. Kod daha sonra (Testi geçirmek)
Şimdi, gerekli olan en az kodu yazıyoruz içinde`SiteBakerPlugin.kt`testin geçmesi için
class SiteBakerPlugin: Plugin<Project> {
override fun apply(project: Project) {
// Enregistrer une tâche simple
project.tasks.register("printSiteConfig") { task ->
// ... la logique de la tâche viendra plus tard
}
}
}
Testleri yeniden başlatıyoruz ve geçiyorlar. İlk işlevimiz doğrulandı.
3. TDD İkinci Döngüsü : DSL uzantısı ekle
Bir sonraki gereklilik, kullanıcıların bir DSL bloğu üzerinden eklentimizi yapılandırmalarını mümkün kılmak içindekileri`build.gradle.kts`. Bir blok istiyoruz`site { … }`bir yapılandırma yolu belirtebileceğiniz yer.
3.1. İlk Test
Eklentinın doğru çalıştığını doğrulamak için bir test ekliyoruz`site`Düzgün bir şekilde kaydedilmiş ve ona bir değer atayabiliriz.
@Test
fun `plugin registers extension`() {
val project = ProjectBuilder.builder().build()
project.plugins.apply("com.cheroliv.site-baker")
// Récupérer l'extension et lui affecter une valeur
project.extensions
.findByType(SiteExtension::class.java)!!
.configPath
.set("config.yml")
// Vérifier que la valeur a bien été prise en compte
assertEquals(
"config.yml",
project.extensions.findByType(SiteExtension::class.java)?.configPath?.get()
)
}
Bu test başarısız olur çünkü ne sınıf`SiteExtension`ni eklenti kaydı yok.
3.2. Ardından Kod
Biz sınıfı oluşturuyoruz.SiteBakerExtension.kt`ve güncelliyoruz`SiteBakerPlugin.kt:
// SiteBakerExtension.kt
open class SiteExtension @Inject constructor(objects: ObjectFactory) {
val configPath: Property<String> = objects.property(String::class.java)
}
// SiteBakerPlugin.kt
class SiteBakerPlugin: Plugin<Project> {
override fun apply(project: Project) {
// Enregistrer l'extension
val extension = project.extensions.create("site", SiteExtension::class.java)
project.tasks.register("printSiteConfig") { task ->
task.doLast {
// On utilisera l'extension plus tard
}
}
}
}
Testler yeniden geçiyor.
4. Fonksiyonel Test: Entegrasyonu doğrulamak
Birimler test edildikten sonra, tümünün gerçek bir derlemede birlikte çalıştığından emin olmamız gerekir. İşte işlevsel testin rolü içinde`SiteBakerPluginFunctionalTest.kt`.
4.1. Entegrasyon Testi: Kontrollü Bir Ortam Oluşturma
Bu test eklentimizi kullanan gerçek bir projeyi simüle edecek. Güvenilir olması için, olmalıdırhava geçirmez, yani ki sistemdeki mevcut dosyalara bağımlı olmamalı. Çalıştırılması için gereken tüm koşulları kendisi oluşturmalı.
Test bu yüzden:)
-
Bir oluştur`build.gradle.kts`Plug‑in’ımızı kullanan ve DSL’sini içeren test
-
Yapılandırma dosyasını oluştur(
managed-jbake-context.yml) eklentisi tarafından okunması beklenen. Bu, testin güvenirliği için kritik bir adım. -
Görevi çalıştır`printSiteConfig`vasıtasıyla`GradleRunner`.
-
Derleme çıktısının doğru olduğunu kontrol edin.
Her yürütme sırasında bu yapılandırma dosyasını kopyalayarak ya da oluşturularak, testin olduğundan emin oluruz.tekrarlanabilirve dış bir duruma bağlı değildir. Bu, testlerimizi dosya okumasından kaynaklanabilecek regresyonlara karşı korur.
@Test fun `can run task with DSL`() {
// 1. Créer un build.gradle.kts de test
buildFile.writeText("""
plugins { id("com.cheroliv.site-baker") }
site { configPath = "managed-jbake-context.yml" }
""".trimIndent())
// 2. Créer le fichier de configuration pour un test contrôlé
val configFile = File(projectDir, "managed-jbake-context.yml")
configFile.writeText("site: { title: 'Mon Site de Test' }") // Contenu YAML simple
// 3. Exécuter la build
val runner = GradleRunner.create()
runner.withPluginClasspath()
runner.withArguments("printSiteConfig")
runner.withProjectDir(projectDir) // Spécifier le répertoire du projet de test
val result = runner.build()
// 4. Vérifier la sortie
assertTrue(result.output.contains("Site config path: managed-jbake-context.yml"))
}
Bu test görevi olduğu sürece başarısız olacaktır.`printSiteConfig`Gerçekten uzantı değerini kullanmayacak
4.2. Mantığı tamamla
Görevi içinde güncelliyoruz`SiteBakerPlugin.kt`ayarlanan değeri göstermek için:
project.tasks.register("printSiteConfig") { task ->
task.doLast {
println("Site config path: ${extension.configPath.get()}")
}
}
Tüm birim ve fonksiyonel testler artık geçiyor.
Sonuç
TDD yaklaşımını takip ederek bir eklenti artımlı ve güvenli şekilde yaptık. Her küçük özellik anında bir test tarafından doğrulanır; hızlı birim testlerinden, tam entegrasyonu doğrulayan fonksiyonel testlere kadar.
Testlerimizin işlevsel olmasını sağlamak için dikkat ederekhermetik— gerekli yapılandırma dosyalarını programatik olarak oluşturarak — güvenlik için çok güçlü bir ağ oluşturuyoruz. Bu hassaslık, regresyonlara karşı etkili bir koruma sağlar ve daha sonra YAML yapılandırma dosyasının ayrıştırılması gibi daha karmaşık özellikler eklemek için büyük bir güven verir.
Bu sağlam test tabanı, eklentinin bakımı ve gelecekteki gelişimi için en değerli varlıktır.