Best fit
- Kotest, MockK, coroutine testi, property-based testing ve Kover coverage ile Kotlin test kalıpları. İdiomatic Kotlin uygulamalarıyla TDD metodolojisini takip eder.
affaan-m/ECC
Kotest, MockK, coroutine testi, property-based testing ve Kover coverage ile Kotlin test kalıpları. İdiomatic Kotlin uygulamalarıyla TDD metodolojisini takip eder.
npx skills add https://github.com/affaan-m/ECC --skill "docs/tr/skills/kotlin-testing"Source checked Jul 28, 2026·Refresh due Oct 26, 2026
Reorganized from the pinned upstream SKILL.md
According to the pinned SKILL.md from affaan-m/ECC: Kotest ve MockK ile TDD metodolojisini takip ederek güvenilir, sürdürülebilir testler yazmak için kapsamlı Kotlin test kalıpları.
npx skills add https://github.com/affaan-m/ECC --skill "docs/tr/skills/kotlin-testing"Best fit
Bring this context
Expected outputs
Key source sections
Sections are extracted automatically from the pinned SKILL.md and link back to the source.
Yeni Kotlin fonksiyonları veya class'lar yazarken
1. Hedef kodu belirle — Test edilecek fonksiyon, class veya modülü bul 2. Kotest spec yaz — Test scope'una uygun bir spec stili seç (StringSpec, FunSpec, BehaviorSpec) 3. Bağımlılıkları mock'la — Test edilen birimi izole etmek için MockK kullan 4. Testleri çalıştır (RED) — Testi…
Review the “TDD İş Akışı for Kotlin” section in the pinned source before continuing.
Review the “RED-GREEN-REFACTOR Döngüsü” section in the pinned source before continuing.
Review the “Kotlin'de Adım Adım TDD” section in the pinned source before continuing.
SkillSignal prompt templates
These prompts were written by SkillSignal from the source structure; they are not upstream text.
Task-start prompt
Confirm source fit, inputs, and outputs before acting.
Use kotlin-testing to help me with: [specific task]. Context: [files, data, or background]. Constraints: [environment, scope, and prohibited actions]. Before acting, check the pinned SKILL.md and explain which sections apply, what inputs are still missing, and what you will deliver.
Source-guided execution
Make the Agent explicitly follow the key extracted sections.
Apply the pinned kotlin-testing source to [task]. Pay particular attention to these source sections: “Ne Zaman Kullanılır”, “Nasıl Çalışır”, “TDD İş Akışı for Kotlin”, “RED-GREEN-REFACTOR Döngüsü”, “Kotlin'de Adım Adım TDD”. Preserve the important decision at each step. Mark facts not covered by the source as “needs confirmation” instead of inventing them. Then verify the result against my acceptance criteria: [criteria].
Result-review prompt
Check omissions, permissions, and source drift before delivery.
Review the current kotlin-testing result: (1) does it satisfy the original task; (2) were any applicable steps or limits in the pinned SKILL.md missed; (3) did it perform any unauthorized file, command, network, or data action; and (4) which conclusions remain unverified? List issues first, then fix only what the source or user authorization supports.
Output checklist
The task matches the purpose documented in the SKILL.md.
The source section “Ne Zaman Kullanılır” has been checked.
The source section “Nasıl Çalışır” has been checked.
The source section “TDD İş Akışı for Kotlin” has been checked.
The source section “RED-GREEN-REFACTOR Döngüsü” has been checked.
Inputs, constraints, and acceptance criteria are explicit.
Unverified facts, compatibility, and outcome claims are clearly marked.
Any file, command, network, or data action has been reviewed.
Choose a different workflow
Kotlin testing patterns with Kotest, MockK, coroutine testing, property-based testing, and Kover coverage. Follows TDD methodology with idiomatic Kotlin practices.
A separate implementation from affaan-m/ECC; compare its source, maintenance signals, and permission requirements.
Open source detail使用Kotest、MockK、协程测试、基于属性的测试和Kover覆盖率的Kotlin测试模式。遵循TDD方法论和地道的Kotlin实践。
A separate implementation from affaan-m/ECC; compare its source, maintenance signals, and permission requirements.
Open source detailPatrones de pruebas Kotlin con Kotest, MockK, pruebas de coroutines, pruebas basadas en propiedades y cobertura con Kover. Sigue la metodología TDD con prácticas idiomáticas de Kotlin.
A separate implementation from affaan-m/ECC; compare its source, maintenance signals, and permission requirements.
Open source detailFAQ
Kotest ve MockK ile TDD metodolojisini takip ederek güvenilir, sürdürülebilir testler yazmak için kapsamlı Kotlin test kalıpları.
The catalog detected this source-specific install command: npx skills add https://github.com/affaan-m/ECC --skill "docs/tr/skills/kotlin-testing". Inspect the command and pinned source before running it.
No dedicated Agent platform is declared in the pinned source record.
Quality breakdown
Based on traceable docs and repository signals; stars are not treated as quality.
Compare before choosing
These links are selected from shared tasks, functions, stacks, platforms, and same-name variants. Compare the source owner, documentation, permissions, and maintenance signals.
Kotlin testing patterns with Kotest, MockK, coroutine testing, property-based testing, and Kover coverage. Follows TDD methodology with idiomatic Kotlin practices.
使用Kotest、MockK、协程测试、基于属性的测试和Kover覆盖率的Kotlin测试模式。遵循TDD方法论和地道的Kotlin实践。
Patrones de pruebas Kotlin con Kotest, MockK, pruebas de coroutines, pruebas basadas en propiedades y cobertura con Kover. Sigue la metodología TDD con prácticas idiomáticas de Kotlin.
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
Use BEFORE writing/changing tests, adding mocks, or test-only methods on production classes — vs mocking-the-mock, production pollution, partial mocks, and overfit/tautological assertions
Kotest ve MockK ile TDD metodolojisini takip ederek güvenilir, sürdürülebilir testler yazmak için kapsamlı Kotlin test kalıpları.
./gradlew koverHtmlReport çalıştır ve %80+ coverage'ı doğrulaRED -> Önce başarısız bir test yaz
GREEN -> Testi geçmek için minimal kod yaz
REFACTOR -> Testleri yeşil tutarken kodu iyileştir
REPEAT -> Sonraki gereksinimle devam et
// Adım 1: Interface/signature tanımla
// EmailValidator.kt
package com.example.validator
fun validateEmail(email: String): Result<String> {
TODO("not implemented")
}
// Adım 2: Başarısız test yaz (RED)
// EmailValidatorTest.kt
package com.example.validator
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.result.shouldBeFailure
import io.kotest.matchers.result.shouldBeSuccess
class EmailValidatorTest : StringSpec({
"valid email returns success" {
validateEmail("user@example.com").shouldBeSuccess("user@example.com")
}
"empty email returns failure" {
validateEmail("").shouldBeFailure()
}
"email without @ returns failure" {
validateEmail("userexample.com").shouldBeFailure()
}
})
// Adım 3: Testleri çalıştır - FAIL doğrula
// $ ./gradlew test
// EmailValidatorTest > valid email returns success FAILED
// kotlin.NotImplementedError: An operation is not implemented
// Adım 4: Minimal kodu uygula (GREEN)
fun validateEmail(email: String): Result<String> {
if (email.isBlank()) return Result.failure(IllegalArgumentException("Email cannot be blank"))
if ('@' !in email) return Result.failure(IllegalArgumentException("Email must contain @"))
val regex = Regex("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$")
if (!regex.matches(email)) return Result.failure(IllegalArgumentException("Invalid email format"))
return Result.success(email)
}
// Adım 5: Testleri çalıştır - PASS doğrula
// $ ./gradlew test
// EmailValidatorTest > valid email returns success PASSED
// EmailValidatorTest > empty email returns failure PASSED
// EmailValidatorTest > email without @ returns failure PASSED
// Adım 6: Gerekirse refactor et, testlerin hala geçtiğini doğrula
class CalculatorTest : StringSpec({
"add two positive numbers" {
Calculator.add(2, 3) shouldBe 5
}
"add negative numbers" {
Calculator.add(-1, -2) shouldBe -3
}
"add zero" {
Calculator.add(0, 5) shouldBe 5
}
})
class UserServiceTest : FunSpec({
val repository = mockk<UserRepository>()
val service = UserService(repository)
test("getUser returns user when found") {
val expected = User(id = "1", name = "Alice")
coEvery { repository.findById("1") } returns expected
val result = service.getUser("1")
result shouldBe expected
}
test("getUser throws when not found") {
coEvery { repository.findById("999") } returns null
shouldThrow<UserNotFoundException> {
service.getUser("999")
}
}
})
class OrderServiceTest : BehaviorSpec({
val repository = mockk<OrderRepository>()
val paymentService = mockk<PaymentService>()
val service = OrderService(repository, paymentService)
Given("a valid order request") {
val request = CreateOrderRequest(
userId = "user-1",
items = listOf(OrderItem("product-1", quantity = 2)),
)
When("the order is placed") {
coEvery { paymentService.charge(any()) } returns PaymentResult.Success
coEvery { repository.save(any()) } answers { firstArg() }
val result = service.placeOrder(request)
Then("it should return a confirmed order") {
result.status shouldBe OrderStatus.CONFIRMED
}
Then("it should charge payment") {
coVerify(exactly = 1) { paymentService.charge(any()) }
}
}
When("payment fails") {
coEvery { paymentService.charge(any()) } returns PaymentResult.Declined
Then("it should throw PaymentException") {
shouldThrow<PaymentException> {
service.placeOrder(request)
}
}
}
}
})
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.string.*
import io.kotest.matchers.collections.*
import io.kotest.matchers.nulls.*
// Eşitlik
result shouldBe expected
result shouldNotBe unexpected
// String'ler
name shouldStartWith "Al"
name shouldEndWith "ice"
name shouldContain "lic"
name shouldMatch Regex("[A-Z][a-z]+")
name.shouldBeBlank()
// Koleksiyonlar
list shouldContain "item"
list shouldHaveSize 3
list.shouldBeSorted()
list.shouldContainAll("a", "b", "c")
list.shouldBeEmpty()
// Null'lar
result.shouldNotBeNull()
result.shouldBeNull()
// Tipler
result.shouldBeInstanceOf<User>()
// Sayılar
count shouldBeGreaterThan 0
price shouldBeInRange 1.0..100.0
// Exception'lar
shouldThrow<IllegalArgumentException> {
validateAge(-1)
}.message shouldBe "Age must be positive"
shouldNotThrow<Exception> {
validateAge(25)
}
class UserServiceTest : FunSpec({
val repository = mockk<UserRepository>()
val logger = mockk<Logger>(relaxed = true) // Relaxed: varsayılanları döndürür
val service = UserService(repository, logger)
beforeTest {
clearMocks(repository, logger)
}
test("findUser delegates to repository") {
val expected = User(id = "1", name = "Alice")
every { repository.findById("1") } returns expected
val result = service.findUser("1")
result shouldBe expected
verify(exactly = 1) { repository.findById("1") }
}
test("findUser returns null for unknown id") {
every { repository.findById(any()) } returns null
val result = service.findUser("unknown")
result.shouldBeNull()
}
})
class AsyncUserServiceTest : FunSpec({
val repository = mockk<UserRepository>()
val service = UserService(repository)
test("getUser suspending function") {
coEvery { repository.findById("1") } returns User(id = "1", name = "Alice")
val result = service.getUser("1")
result.name shouldBe "Alice"
coVerify { repository.findById("1") }
}
test("getUser with delay") {
coEvery { repository.findById("1") } coAnswers {
delay(100) // Async çalışmayı simüle et
User(id = "1", name = "Alice")
}
val result = service.getUser("1")
result.name shouldBe "Alice"
}
})
import kotlinx.coroutines.test.runTest
class CoroutineServiceTest : FunSpec({
test("concurrent fetches complete together") {
runTest {
val service = DataService(testScope = this)
val result = service.fetchAllData()
result.users.shouldNotBeEmpty()
result.products.shouldNotBeEmpty()
}
}
test("timeout after delay") {
runTest {
val service = SlowService()
shouldThrow<TimeoutCancellationException> {
withTimeout(100) {
service.slowOperation() // > 100ms sürer
}
}
}
}
})
import io.kotest.matchers.collections.shouldContainInOrder
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runTest
class FlowServiceTest : FunSpec({
test("observeUsers emits updates") {
runTest {
val service = UserFlowService()
val emissions = service.observeUsers()
.take(3)
.toList()
emissions shouldHaveSize 3
emissions.last().shouldNotBeEmpty()
}
}
test("searchUsers debounces input") {
runTest {
val service = SearchService()
val queries = MutableSharedFlow<String>()
val results = mutableListOf<List<User>>()
val job = launch {
service.searchUsers(queries).collect { results.add(it) }
}
queries.emit("a")
queries.emit("ab")
queries.emit("abc") // Sadece bu aramayı tetiklemeli
advanceTimeBy(500)
results shouldHaveSize 1
job.cancel()
}
}
})
import io.kotest.core.spec.style.FunSpec
import io.kotest.property.Arb
import io.kotest.property.arbitrary.*
import io.kotest.property.forAll
import io.kotest.property.checkAll
class PropertyTest : FunSpec({
test("string reverse is involutory") {
forAll<String> { s ->
s.reversed().reversed() == s
}
}
test("list sort is idempotent") {
forAll(Arb.list(Arb.int())) { list ->
list.sorted() == list.sorted().sorted()
}
}
test("serialization roundtrip preserves data") {
checkAll(Arb.bind(Arb.string(1..50), Arb.string(5..100)) { name, email ->
User(name = name, email = "$email@test.com")
}) { user ->
val json = Json.encodeToString(user)
val decoded = Json.decodeFromString<User>(json)
decoded shouldBe user
}
}
})
// build.gradle.kts
plugins {
id("org.jetbrains.kotlinx.kover") version "0.9.7"
}
kover {
reports {
total {
html { onCheck = true }
xml { onCheck = true }
}
filters {
excludes {
classes("*.generated.*", "*.config.*")
}
}
verify {
rule {
minBound(80) // %80 coverage'ın altında build başarısız
}
}
}
}
# Testleri coverage ile çalıştır
./gradlew koverHtmlReport
# Coverage eşiklerini doğrula
./gradlew koverVerify
# CI için XML raporu
./gradlew koverXmlReport
# HTML raporunu görüntüle (OS'nize göre komutu kullanın)
# macOS: open build/reports/kover/html/index.html
# Linux: xdg-open build/reports/kover/html/index.html
# Windows: start build/reports/kover/html/index.html
| Kod Tipi | Hedef |
|---|---|
| Kritik business mantığı | %100 |
| Public API'ler | %90+ |
| Genel kod | %80+ |
| Generated / config kodu | Hariç tut |
class ApiRoutesTest : FunSpec({
test("GET /users returns list") {
testApplication {
application {
configureRouting()
configureSerialization()
}
val response = client.get("/users")
response.status shouldBe HttpStatusCode.OK
val users = response.body<List<UserResponse>>()
users.shouldNotBeEmpty()
}
}
test("POST /users creates user") {
testApplication {
application {
configureRouting()
configureSerialization()
}
val response = client.post("/users") {
contentType(ContentType.Application.Json)
setBody(CreateUserRequest("Alice", "alice@example.com"))
}
response.status shouldBe HttpStatusCode.Created
}
}
})
# Tüm testleri çalıştır
./gradlew test
# Belirli test class'ını çalıştır
./gradlew test --tests "com.example.UserServiceTest"
# Belirli testi çalıştır
./gradlew test --tests "com.example.UserServiceTest.getUser returns user when found"
# Verbose çıktı ile çalıştır
./gradlew test --info
# Coverage ile çalıştır
./gradlew koverHtmlReport
# Detekt çalıştır (statik analiz)
./gradlew detekt
# Ktlint çalıştır (formatlama kontrolü)
./gradlew ktlintCheck
# Sürekli test
./gradlew test --continuous
YAPILMASI GEREKENLER:
coEvery/coVerify'ını kullanrunTest kullandata class test fixture'ları kullanYAPILMAMASI GEREKENLER:
Thread.sleep() kullanma (advanceTimeBy kullan)# GitHub Actions örneği
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
- name: Run tests with coverage
run: ./gradlew test koverXmlReport
- name: Verify coverage
run: ./gradlew koverVerify
- name: Upload coverage
uses: codecov/codecov-action@v5
with:
files: build/reports/kover/report.xml
token: ${{ secrets.CODECOV_TOKEN }}
Hatırla: Testler dokümantasyondur. Kotlin kodunuzun nasıl kullanılması gerektiğini gösterirler. Testleri okunabilir yapmak için Kotest'in açıklayıcı matcher'larını ve bağımlılıkları temiz mock'lamak için MockK kullanın.