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:)

  1. Bir oluştur`build.gradle.kts`Plug‑in’ımızı kullanan ve DSL’sini içeren test

  2. 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.

  3. Görevi çalıştır`printSiteConfig`vasıtasıyla`GradleRunner`.

  4. 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.

İlgili Makaleler