CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-kotlin--kotlin-test-common

Common test assertions and utilities for Kotlin multiplatform projects

Pending
Overview
Eval results
Files

test-utilities.mddocs/

Test Utilities

Core utility functions for test execution and expectation validation. These functions provide additional testing capabilities beyond standard assertions, including expectation validation, test failure marking, and placeholder test implementation.

Capabilities

expect

Validates that a code block returns an expected value, providing a concise way to test function results.

/**
 * Asserts that the given function block returns the expected value.
 * @param expected The value that the block should return
 * @param block The function to execute and validate
 * @throws AssertionError if the block returns a different value
 */
fun <T> expect(expected: T, block: () -> T)

/**
 * Asserts that the given function block returns the expected value with a custom message.
 * @param expected The value that the block should return
 * @param message Optional message to show if assertion fails
 * @param block The function to execute and validate
 * @throws AssertionError if the block returns a different value
 */
fun <T> expect(expected: T, message: String?, block: () -> T)

Usage Examples:

import kotlin.test.expect

@Test
fun testExpectFunction() {
    // Basic expectation testing
    expect(10) { 5 + 5 }
    expect("hello") { "hel" + "lo" }
    expect(true) { 10 > 5 }
    
    // Complex function testing
    expect(42) { 
        val calculator = Calculator()
        calculator.add(40, 2)
    }
    
    // With custom messages
    expect(100, "Score calculation should return 100") {
        gameLogic.calculateFinalScore()
    }
    
    // Testing object methods
    val user = User("Alice", 25)
    expect("Alice") { user.getName() }
    expect(25) { user.getAge() }
    
    // Collection operations
    expect(3) { listOf(1, 2, 3).size }
    expect("HELLO") { "hello".uppercase() }
}

@Test
fun testComplexExpectations() {
    // Testing with side effects
    val counter = Counter()
    expect(1) { counter.increment() }
    expect(2) { counter.increment() }
    expect(0) { counter.reset(); counter.getValue() }
    
    // API call testing
    val apiClient = TestApiClient()
    expect(200) { apiClient.getStatus("/health").statusCode }
    expect("OK") { apiClient.getStatus("/health").message }
    
    // Conditional logic testing
    expect("adult") {
        val person = Person(age = 25)
        if (person.age >= 18) "adult" else "minor"
    }
}

fail

Explicitly marks a test as failed with an optional message and cause.

/**
 * Marks a test as failed with the specified message.
 * This function never returns normally - it always throws.
 * @param message Optional failure message
 * @return Nothing (this function never returns)
 * @throws AssertionError always
 */
fun fail(message: String? = null): Nothing

/**
 * Marks a test as failed with the specified message and underlying cause.
 * This function never returns normally - it always throws.
 * @param message Optional failure message
 * @param cause Optional underlying cause of the failure
 * @return Nothing (this function never returns)
 * @throws AssertionError always
 * @since Kotlin 1.4
 */
fun fail(message: String? = null, cause: Throwable? = null): Nothing

Usage Examples:

import kotlin.test.fail

@Test
fun testFailFunction() {
    val condition = checkSomeCondition()
    
    if (!condition) {
        fail("Expected condition to be true but it was false")
    }
    
    // Unreachable code after fail()
    println("This will never execute")
}

@Test
fun testConditionalFailure() {
    val result = performComplexOperation()
    
    when (result.status) {
        Status.SUCCESS -> {
            // Test passes, continue validation
            assertTrue(result.data.isNotEmpty())
        }
        Status.ERROR -> {
            fail("Operation failed with error: ${result.errorMessage}")
        }
        Status.UNKNOWN -> {
            fail("Operation returned unknown status")
        }
    }
}

@Test
fun testFailWithCause() {
    try {
        val service = ExternalService()
        service.performOperation()
    } catch (e: ServiceException) {
        fail("Service operation should not throw exception", e)
    } catch (e: Exception) {
        fail("Unexpected exception occurred", e)
    }
}

@Test
fun testValidationFailure() {
    val data = loadTestData()
    
    // Explicit validation with meaningful failure messages
    if (data.isEmpty()) {
        fail("Test data should not be empty")
    }
    
    if (data.size < 10) {
        fail("Test data should contain at least 10 items, but got ${data.size}")
    }
    
    // Continue with normal test logic
    assertTrue(data.all { it.isValid() })
}

todo

Marks a test as a TODO placeholder that should not be executed yet.

/**
 * Takes a block of test code and doesn't execute it.
 * Used to mark tests that are not yet implemented or should be skipped.
 * This is an expect declaration that has platform-specific implementations.
 * @param block The test code that should not be executed
 */
fun todo(block: () -> Unit)

Usage Examples:

import kotlin.test.todo
import kotlin.test.Test

class UserServiceTest {
    
    @Test
    fun testCreateUser() {
        // Implemented test
        val service = UserService()
        val user = service.createUser("Alice", "alice@example.com")
        assertEquals("Alice", user.name)
    }
    
    @Test
    fun testUpdateUser() {
        todo {
            // This test is not yet implemented
            // The block won't execute but the test will be reported as TODO
            val service = UserService()
            val user = service.updateUser(1, "Bob", "bob@example.com")
            assertEquals("Bob", user.name)
        }
    }
    
    @Test
    fun testDeleteUser() {
        todo {
            // Placeholder for future test implementation
            val service = UserService()
            service.deleteUser(1)
            assertNull(service.findUser(1))
        }
    }
    
    @Test
    fun testComplexUserOperation() {
        todo {
            // This test requires complex setup that's not ready yet
            val service = UserService()
            val database = TestDatabase.setup()
            val cache = TestCache.setup()
            
            // Complex test logic here...
            val result = service.performComplexOperation()
            assertTrue(result.isSuccess)
        }
    }
}

class IntegrationTest {
    
    @Test
    fun testBasicIntegration() {
        // Working integration test
        val client = ApiClient()
        val response = client.ping()
        assertEquals(200, response.status)
    }
    
    @Test
    fun testAdvancedIntegration() {
        todo {
            // This integration test needs external service setup
            val client = ApiClient()
            val externalService = ExternalService.connect()
            
            val result = client.performIntegration(externalService)
            assertTrue(result.isSuccess)
        }
    }
}

Usage Patterns and Best Practices

expect vs assertEquals

Use expect for concise single-expression testing, assertEquals for explicit value comparison:

// Use expect for concise testing
expect(5) { list.size }
expect("result") { processor.process(input) }

// Use assertEquals for explicit comparison
val actual = processor.process(input)
assertEquals("result", actual)

fail for Custom Validation

Use fail when standard assertions don't provide appropriate validation:

@Test
fun testCustomValidation() {
    val result = complexOperation()
    
    // Custom business logic validation
    if (!result.isValid() || result.score < 0) {
        fail("Result failed business validation: $result")
    }
    
    // Additional standard assertions
    assertTrue(result.isComplete())
}

todo for Development Workflow

Use todo to maintain test structure during development:

class NewFeatureTest {
    
    @Test
    fun testImplementedPart() {
        // Already working
        assertTrue(newFeature.basicFunctionality())
    }
    
    @Test
    fun testAdvancedPart() {
        todo {
            // Will implement after basic part is stable
            assertTrue(newFeature.advancedFunctionality())
        }
    }
}

Error Handling

  • expect: Throws AssertionError when the block result doesn't match the expected value
  • fail: Always throws AssertionError with the provided message and optional cause
  • todo: Platform-specific behavior - typically marks the test as skipped or pending

Error messages provide clear context for debugging:

// This will throw: AssertionError: Expected <5>, actual <3>.
expect(5) { listOf(1, 2, 3).size }

// This will throw: AssertionError: Custom validation failed
fail("Custom validation failed")

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-kotlin--kotlin-test-common

docs

boolean-assertions.md

collection-assertions.md

equality-assertions.md

exception-testing.md

framework-integration.md

index.md

test-annotations.md

test-utilities.md

type-null-assertions.md

tile.json