0
# Test Utilities
1
2
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.
3
4
## Capabilities
5
6
### expect
7
8
Validates that a code block returns an expected value, providing a concise way to test function results.
9
10
```kotlin { .api }
11
/**
12
* Asserts that the given function block returns the expected value.
13
* @param expected The value that the block should return
14
* @param block The function to execute and validate
15
* @throws AssertionError if the block returns a different value
16
*/
17
fun <T> expect(expected: T, block: () -> T)
18
19
/**
20
* Asserts that the given function block returns the expected value with a custom message.
21
* @param expected The value that the block should return
22
* @param message Optional message to show if assertion fails
23
* @param block The function to execute and validate
24
* @throws AssertionError if the block returns a different value
25
*/
26
fun <T> expect(expected: T, message: String?, block: () -> T)
27
```
28
29
**Usage Examples:**
30
31
```kotlin
32
import kotlin.test.expect
33
34
@Test
35
fun testExpectFunction() {
36
// Basic expectation testing
37
expect(10) { 5 + 5 }
38
expect("hello") { "hel" + "lo" }
39
expect(true) { 10 > 5 }
40
41
// Complex function testing
42
expect(42) {
43
val calculator = Calculator()
44
calculator.add(40, 2)
45
}
46
47
// With custom messages
48
expect(100, "Score calculation should return 100") {
49
gameLogic.calculateFinalScore()
50
}
51
52
// Testing object methods
53
val user = User("Alice", 25)
54
expect("Alice") { user.getName() }
55
expect(25) { user.getAge() }
56
57
// Collection operations
58
expect(3) { listOf(1, 2, 3).size }
59
expect("HELLO") { "hello".uppercase() }
60
}
61
62
@Test
63
fun testComplexExpectations() {
64
// Testing with side effects
65
val counter = Counter()
66
expect(1) { counter.increment() }
67
expect(2) { counter.increment() }
68
expect(0) { counter.reset(); counter.getValue() }
69
70
// API call testing
71
val apiClient = TestApiClient()
72
expect(200) { apiClient.getStatus("/health").statusCode }
73
expect("OK") { apiClient.getStatus("/health").message }
74
75
// Conditional logic testing
76
expect("adult") {
77
val person = Person(age = 25)
78
if (person.age >= 18) "adult" else "minor"
79
}
80
}
81
```
82
83
### fail
84
85
Explicitly marks a test as failed with an optional message and cause.
86
87
```kotlin { .api }
88
/**
89
* Marks a test as failed with the specified message.
90
* This function never returns normally - it always throws.
91
* @param message Optional failure message
92
* @return Nothing (this function never returns)
93
* @throws AssertionError always
94
*/
95
fun fail(message: String? = null): Nothing
96
97
/**
98
* Marks a test as failed with the specified message and underlying cause.
99
* This function never returns normally - it always throws.
100
* @param message Optional failure message
101
* @param cause Optional underlying cause of the failure
102
* @return Nothing (this function never returns)
103
* @throws AssertionError always
104
* @since Kotlin 1.4
105
*/
106
fun fail(message: String? = null, cause: Throwable? = null): Nothing
107
```
108
109
**Usage Examples:**
110
111
```kotlin
112
import kotlin.test.fail
113
114
@Test
115
fun testFailFunction() {
116
val condition = checkSomeCondition()
117
118
if (!condition) {
119
fail("Expected condition to be true but it was false")
120
}
121
122
// Unreachable code after fail()
123
println("This will never execute")
124
}
125
126
@Test
127
fun testConditionalFailure() {
128
val result = performComplexOperation()
129
130
when (result.status) {
131
Status.SUCCESS -> {
132
// Test passes, continue validation
133
assertTrue(result.data.isNotEmpty())
134
}
135
Status.ERROR -> {
136
fail("Operation failed with error: ${result.errorMessage}")
137
}
138
Status.UNKNOWN -> {
139
fail("Operation returned unknown status")
140
}
141
}
142
}
143
144
@Test
145
fun testFailWithCause() {
146
try {
147
val service = ExternalService()
148
service.performOperation()
149
} catch (e: ServiceException) {
150
fail("Service operation should not throw exception", e)
151
} catch (e: Exception) {
152
fail("Unexpected exception occurred", e)
153
}
154
}
155
156
@Test
157
fun testValidationFailure() {
158
val data = loadTestData()
159
160
// Explicit validation with meaningful failure messages
161
if (data.isEmpty()) {
162
fail("Test data should not be empty")
163
}
164
165
if (data.size < 10) {
166
fail("Test data should contain at least 10 items, but got ${data.size}")
167
}
168
169
// Continue with normal test logic
170
assertTrue(data.all { it.isValid() })
171
}
172
```
173
174
### todo
175
176
Marks a test as a TODO placeholder that should not be executed yet.
177
178
```kotlin { .api }
179
/**
180
* Takes a block of test code and doesn't execute it.
181
* Used to mark tests that are not yet implemented or should be skipped.
182
* This is an expect declaration that has platform-specific implementations.
183
* @param block The test code that should not be executed
184
*/
185
fun todo(block: () -> Unit)
186
```
187
188
**Usage Examples:**
189
190
```kotlin
191
import kotlin.test.todo
192
import kotlin.test.Test
193
194
class UserServiceTest {
195
196
@Test
197
fun testCreateUser() {
198
// Implemented test
199
val service = UserService()
200
val user = service.createUser("Alice", "alice@example.com")
201
assertEquals("Alice", user.name)
202
}
203
204
@Test
205
fun testUpdateUser() {
206
todo {
207
// This test is not yet implemented
208
// The block won't execute but the test will be reported as TODO
209
val service = UserService()
210
val user = service.updateUser(1, "Bob", "bob@example.com")
211
assertEquals("Bob", user.name)
212
}
213
}
214
215
@Test
216
fun testDeleteUser() {
217
todo {
218
// Placeholder for future test implementation
219
val service = UserService()
220
service.deleteUser(1)
221
assertNull(service.findUser(1))
222
}
223
}
224
225
@Test
226
fun testComplexUserOperation() {
227
todo {
228
// This test requires complex setup that's not ready yet
229
val service = UserService()
230
val database = TestDatabase.setup()
231
val cache = TestCache.setup()
232
233
// Complex test logic here...
234
val result = service.performComplexOperation()
235
assertTrue(result.isSuccess)
236
}
237
}
238
}
239
240
class IntegrationTest {
241
242
@Test
243
fun testBasicIntegration() {
244
// Working integration test
245
val client = ApiClient()
246
val response = client.ping()
247
assertEquals(200, response.status)
248
}
249
250
@Test
251
fun testAdvancedIntegration() {
252
todo {
253
// This integration test needs external service setup
254
val client = ApiClient()
255
val externalService = ExternalService.connect()
256
257
val result = client.performIntegration(externalService)
258
assertTrue(result.isSuccess)
259
}
260
}
261
}
262
```
263
264
## Usage Patterns and Best Practices
265
266
### expect vs assertEquals
267
Use `expect` for concise single-expression testing, `assertEquals` for explicit value comparison:
268
269
```kotlin
270
// Use expect for concise testing
271
expect(5) { list.size }
272
expect("result") { processor.process(input) }
273
274
// Use assertEquals for explicit comparison
275
val actual = processor.process(input)
276
assertEquals("result", actual)
277
```
278
279
### fail for Custom Validation
280
Use `fail` when standard assertions don't provide appropriate validation:
281
282
```kotlin
283
@Test
284
fun testCustomValidation() {
285
val result = complexOperation()
286
287
// Custom business logic validation
288
if (!result.isValid() || result.score < 0) {
289
fail("Result failed business validation: $result")
290
}
291
292
// Additional standard assertions
293
assertTrue(result.isComplete())
294
}
295
```
296
297
### todo for Development Workflow
298
Use `todo` to maintain test structure during development:
299
300
```kotlin
301
class NewFeatureTest {
302
303
@Test
304
fun testImplementedPart() {
305
// Already working
306
assertTrue(newFeature.basicFunctionality())
307
}
308
309
@Test
310
fun testAdvancedPart() {
311
todo {
312
// Will implement after basic part is stable
313
assertTrue(newFeature.advancedFunctionality())
314
}
315
}
316
}
317
```
318
319
## Error Handling
320
321
- **expect**: Throws `AssertionError` when the block result doesn't match the expected value
322
- **fail**: Always throws `AssertionError` with the provided message and optional cause
323
- **todo**: Platform-specific behavior - typically marks the test as skipped or pending
324
325
Error messages provide clear context for debugging:
326
327
```kotlin
328
// This will throw: AssertionError: Expected <5>, actual <3>.
329
expect(5) { listOf(1, 2, 3).size }
330
331
// This will throw: AssertionError: Custom validation failed
332
fail("Custom validation failed")
333
```