Ensure tests verify both basic functionality and edge cases. Tests that only cover the happy path can miss critical bugs in boundary conditions and special scenarios.
For each feature:
Example:
@Sample
fun contains() {
// Basic functionality
val string = "Kotlin 1.4.0"
assertPrints(string.contains("K"), "true")
assertPrints(string.contains("k"), "false")
// Edge cases
assertPrints("".contains(""), "true") // Empty receiver and parameter
assertPrints("Kotlin".contains(""), "true") // Empty parameter
assertPrints("".contains("Kotlin"), "false") // Empty receiver
assertPrints("Kotlin".contains("Kotlin"), "true") // Identical strings
assertPrints("Kotlin 2.0.0".contains("Kotlin"), "true") // Receiver contains parameter
assertPrints("Kotlin".contains("Kotlin 2.0.0"), "false") // Parameter contains receiver
}
Include specific tests for error conditions using explicit assertions rather than try/catch blocks:
// Incorrect: Test passes even if cast doesn't fail
try {
BNativeHeir as A.Companion
} catch (e: Exception) {
assertTrue(e is ClassCastException)
}
// Correct: Test only passes if cast fails with expected exception
assertFailsWith<ClassCastException> {
BNativeHeir as A.Companion
}
Comprehensive testing prevents code from “rotting” and ensures reliability across all usage scenarios.
Enter the URL of a public GitHub repository