or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdasserter.mdbasic-assertions.mdcollection-assertions.mdexception-testing.mdindex.mdtype-null-assertions.md

asserter.mddocs/

0

# Asserter Interface

1

2

The core assertion interface that can be customized for different testing frameworks and platforms. The Asserter interface provides the foundation for all assertion operations in Kotlin Test.

3

4

## Capabilities

5

6

### Asserter Interface

7

8

The main interface for implementing custom assertion backends.

9

10

```kotlin { .api }

11

/**

12

* Abstracts the logic for performing assertions. Specific implementations can use

13

* JUnit, TestNG, or other assertion facilities.

14

*/

15

interface Asserter {

16

/**

17

* Fails the current test with the specified message

18

* @param message - The message to report

19

* @return Nothing (function never returns)

20

*/

21

fun fail(message: String?): Nothing

22

23

/**

24

* Fails the current test with the specified message and cause exception

25

* @param message - The message to report

26

* @param cause - The exception to set as the root cause of the reported failure

27

* @return Nothing (function never returns)

28

*/

29

fun fail(message: String?, cause: Throwable?): Nothing

30

31

/**

32

* Asserts that the specified value is true

33

* @param lazyMessage - Function to return a message to report if the assertion fails

34

* @param actual - Boolean value to check

35

*/

36

fun assertTrue(lazyMessage: () -> String?, actual: Boolean): Unit

37

38

/**

39

* Asserts that the specified value is true

40

* @param message - The message to report if the assertion fails

41

* @param actual - Boolean value to check

42

*/

43

fun assertTrue(message: String?, actual: Boolean): Unit

44

45

/**

46

* Asserts that the specified values are equal

47

* @param message - The message to report if the assertion fails

48

* @param expected - Expected value

49

* @param actual - Actual value

50

*/

51

fun assertEquals(message: String?, expected: Any?, actual: Any?): Unit

52

53

/**

54

* Asserts that the specified values are not equal

55

* @param message - The message to report if the assertion fails

56

* @param illegal - Value that should not match

57

* @param actual - Actual value

58

*/

59

fun assertNotEquals(message: String?, illegal: Any?, actual: Any?): Unit

60

61

/**

62

* Asserts that the specified values are the same instance

63

* @param message - The message to report if the assertion fails

64

* @param expected - Expected object reference

65

* @param actual - Actual object reference

66

*/

67

fun assertSame(message: String?, expected: Any?, actual: Any?): Unit

68

69

/**

70

* Asserts that the specified values are not the same instance

71

* @param message - The message to report if the assertion fails

72

* @param illegal - Object reference that should not match

73

* @param actual - Actual object reference

74

*/

75

fun assertNotSame(message: String?, illegal: Any?, actual: Any?): Unit

76

77

/**

78

* Asserts that the specified value is null

79

* @param message - The message to report if the assertion fails

80

* @param actual - Value to check for nullness

81

*/

82

fun assertNull(message: String?, actual: Any?): Unit

83

84

/**

85

* Asserts that the specified value is not null

86

* @param message - The message to report if the assertion fails

87

* @param actual - Value to check for non-nullness

88

*/

89

fun assertNotNull(message: String?, actual: Any?): Unit

90

}

91

```

92

93

### AsserterContributor Interface

94

95

Interface for providing Asserter instances based on context.

96

97

```kotlin { .api }

98

/**

99

* Checks applicability and provides Asserter instance

100

*/

101

interface AsserterContributor {

102

/**

103

* Provides Asserter instance or null depending on the current context

104

* @return Asserter instance or null if not applicable

105

*/

106

fun contribute(): Asserter?

107

}

108

```

109

110

### DefaultAsserter Object

111

112

Default implementation of the Asserter interface.

113

114

```kotlin { .api }

115

/**

116

* Default Asserter implementation to avoid dependency on JUnit or TestNG

117

*/

118

object DefaultAsserter : Asserter

119

```

120

121

### Current Asserter Property

122

123

Global property to access the current asserter instance.

124

125

```kotlin { .api }

126

/**

127

* Current adapter providing assertion implementations

128

* Gets the current asserter or looks up an available one

129

*/

130

val asserter: Asserter

131

```

132

133

## Usage Examples

134

135

### Using the Global Asserter

136

137

```kotlin

138

import kotlin.test.*

139

140

@Test

141

fun testUsingGlobalAsserter() {

142

// The global asserter is used automatically by assertion functions

143

val result = performCalculation()

144

145

// These functions delegate to the current asserter

146

assertTrue(result > 0)

147

assertEquals(42, result)

148

assertNotNull(result)

149

150

// You can also use the asserter directly (though not typically needed)

151

asserter.assertTrue("Result should be positive", result > 0)

152

asserter.assertEquals("Should equal 42", 42, result)

153

}

154

```

155

156

### Creating Custom Asserter

157

158

```kotlin

159

class CustomAsserter(private val testName: String) : Asserter {

160

override fun fail(message: String?): Nothing {

161

val fullMessage = "[$testName] ${message ?: "Test failed"}"

162

throw AssertionError(fullMessage)

163

}

164

165

override fun fail(message: String?, cause: Throwable?): Nothing {

166

val fullMessage = "[$testName] ${message ?: "Test failed"}"

167

throw AssertionError(fullMessage, cause)

168

}

169

170

override fun assertTrue(message: String?, actual: Boolean) {

171

if (!actual) {

172

fail(message ?: "Expected value to be true")

173

}

174

}

175

176

override fun assertEquals(message: String?, expected: Any?, actual: Any?) {

177

if (expected != actual) {

178

fail("${message ?: "Values should be equal"}: expected <$expected>, actual <$actual>")

179

}

180

}

181

182

override fun assertNotEquals(message: String?, illegal: Any?, actual: Any?) {

183

if (illegal == actual) {

184

fail("${message ?: "Values should not be equal"}: illegal value <$actual>")

185

}

186

}

187

188

override fun assertSame(message: String?, expected: Any?, actual: Any?) {

189

if (expected !== actual) {

190

fail("${message ?: "References should be same"}: expected <$expected>, actual <$actual>")

191

}

192

}

193

194

override fun assertNotSame(message: String?, illegal: Any?, actual: Any?) {

195

if (illegal === actual) {

196

fail("${message ?: "References should not be same"}: illegal reference <$actual>")

197

}

198

}

199

200

override fun assertNull(message: String?, actual: Any?) {

201

if (actual != null) {

202

fail("${message ?: "Value should be null"}: actual <$actual>")

203

}

204

}

205

206

override fun assertNotNull(message: String?, actual: Any?) {

207

if (actual == null) {

208

fail(message ?: "Value should not be null")

209

}

210

}

211

}

212

```

213

214

### Creating Custom AsserterContributor

215

216

```kotlin

217

class LoggingAsserterContributor : AsserterContributor {

218

override fun contribute(): Asserter? {

219

// Only provide the logging asserter in debug mode

220

return if (isDebugMode()) {

221

LoggingAsserter()

222

} else {

223

null

224

}

225

}

226

}

227

228

class LoggingAsserter : Asserter {

229

private fun log(operation: String, message: String?) {

230

println("[ASSERT] $operation: ${message ?: "no message"}")

231

}

232

233

override fun fail(message: String?): Nothing {

234

log("FAIL", message)

235

throw AssertionError(message)

236

}

237

238

override fun fail(message: String?, cause: Throwable?): Nothing {

239

log("FAIL", "$message (caused by: ${cause?.message})")

240

throw AssertionError(message, cause)

241

}

242

243

override fun assertTrue(message: String?, actual: Boolean) {

244

log("ASSERT_TRUE", message)

245

if (!actual) {

246

throw AssertionError(message ?: "Expected true")

247

}

248

}

249

250

override fun assertEquals(message: String?, expected: Any?, actual: Any?) {

251

log("ASSERT_EQUALS", "$message: expected=$expected, actual=$actual")

252

if (expected != actual) {

253

throw AssertionError("Expected <$expected>, actual <$actual>")

254

}

255

}

256

257

// ... implement other methods with logging

258

}

259

```

260

261

## Platform-Specific Asserter Implementations

262

263

### JUnit Asserter Integration

264

265

```kotlin

266

// This is how kotlin-test integrates with JUnit internally

267

class JUnitAsserter : Asserter {

268

override fun fail(message: String?): Nothing {

269

org.junit.Assert.fail(message)

270

throw AssertionError() // Never reached, but needed for Nothing return type

271

}

272

273

override fun assertTrue(message: String?, actual: Boolean) {

274

org.junit.Assert.assertTrue(message, actual)

275

}

276

277

override fun assertEquals(message: String?, expected: Any?, actual: Any?) {

278

org.junit.Assert.assertEquals(message, expected, actual)

279

}

280

281

// ... other methods delegate to JUnit assertions

282

}

283

```

284

285

### TestNG Asserter Integration

286

287

```kotlin

288

class TestNGAsserter : Asserter {

289

override fun fail(message: String?): Nothing {

290

org.testng.Assert.fail(message)

291

throw AssertionError() // Never reached

292

}

293

294

override fun assertTrue(message: String?, actual: Boolean) {

295

org.testng.Assert.assertTrue(actual, message)

296

}

297

298

override fun assertEquals(message: String?, expected: Any?, actual: Any?) {

299

org.testng.Assert.assertEquals(actual, expected, message)

300

}

301

302

// ... other methods delegate to TestNG assertions

303

}

304

```

305

306

### Custom Test Framework Integration

307

308

```kotlin

309

class MyFrameworkAsserter : Asserter {

310

override fun fail(message: String?): Nothing {

311

MyTestFramework.reportFailure(message ?: "Test failed")

312

throw MyTestFramework.TestFailedException(message)

313

}

314

315

override fun assertTrue(message: String?, actual: Boolean) {

316

if (!actual) {

317

MyTestFramework.reportAssertion("assertTrue", message, false)

318

fail(message ?: "Expected true")

319

} else {

320

MyTestFramework.reportAssertion("assertTrue", message, true)

321

}

322

}

323

324

// ... implement other methods to integrate with your framework

325

}

326

```

327

328

## Advanced Usage Patterns

329

330

### Temporary Asserter Override

331

332

```kotlin

333

@Test

334

fun testWithCustomAsserter() {

335

val originalAsserter = asserter

336

val customAsserter = CustomAsserter("MyTest")

337

338

try {

339

// Temporarily override the asserter

340

overrideAsserter(customAsserter)

341

342

// All assertions now use the custom asserter

343

assertTrue(true) // Will use CustomAsserter

344

assertEquals(42, 42) // Will use CustomAsserter

345

346

} finally {

347

// Restore original asserter

348

overrideAsserter(originalAsserter)

349

}

350

}

351

352

// Helper function to override asserter (internal API)

353

fun overrideAsserter(newAsserter: Asserter): Asserter {

354

// This uses internal kotlin-test API

355

return kotlin.test.overrideAsserter(newAsserter) ?: DefaultAsserter

356

}

357

```

358

359

### Asserter Chain

360

361

```kotlin

362

class ChainedAsserter(private val asserters: List<Asserter>) : Asserter {

363

override fun fail(message: String?): Nothing {

364

// Fail using the first asserter in the chain

365

asserters.firstOrNull()?.fail(message) ?: throw AssertionError(message)

366

}

367

368

override fun assertTrue(message: String?, actual: Boolean) {

369

// Execute assertion on all asserters in chain

370

for (asserter in asserters) {

371

asserter.assertTrue(message, actual)

372

}

373

}

374

375

// ... implement other methods to delegate to all asserters

376

}

377

378

@Test

379

fun testWithChainedAsserters() {

380

val loggingAsserter = LoggingAsserter()

381

val junitAsserter = JUnitAsserter()

382

val chainedAsserter = ChainedAsserter(listOf(loggingAsserter, junitAsserter))

383

384

overrideAsserter(chainedAsserter)

385

386

// This will both log the assertion AND use JUnit's assertion

387

assertTrue(5 > 3)

388

}

389

```

390

391

## Platform-Specific Utilities

392

393

### currentStackTrace Function (JVM Only)

394

395

**⚠️ JVM Platform Only** - This function is only available when running tests on the JVM platform.

396

397

Returns the current stack trace as an array of stack trace elements for debugging and diagnostic purposes.

398

399

```kotlin { .api }

400

/**

401

* Returns an array of stack trace elements, each representing one stack frame

402

* The first element represents the top of the stack (where currentStackTrace was called)

403

* @return Array of StackTraceElement representing the call stack

404

*/

405

inline fun currentStackTrace(): Array<StackTraceElement>

406

```

407

408

**Usage Examples:**

409

410

```kotlin

411

import kotlin.test.*

412

413

@Test

414

fun testStackTraceCapture() {

415

// Capture stack trace at current location

416

val stackTrace = currentStackTrace()

417

418

// Examine the top frame (where currentStackTrace was called)

419

val topFrame = stackTrace[0]

420

println("Called from: ${topFrame.fileName}:${topFrame.lineNumber}")

421

println("Method: ${topFrame.methodName}")

422

println("Class: ${topFrame.className}")

423

424

// Verify we captured the right location

425

assertEquals("AssertionTests.kt", topFrame.fileName)

426

assertTrue(topFrame.lineNumber > 0)

427

}

428

429

// Custom diagnostic assertion using stack trace

430

fun assertWithLocation(condition: Boolean, message: String) {

431

if (!condition) {

432

val location = currentStackTrace()[0]

433

fail("$message at ${location.fileName}:${location.lineNumber}")

434

}

435

}

436

437

@Test

438

fun testCustomDiagnosticAssertion() {

439

val value = 42

440

441

// This will provide detailed location info if it fails

442

assertWithLocation(value == 42, "Value should be 42")

443

444

// Example of failure (commented out)

445

// assertWithLocation(value == 99, "This will show exact location")

446

}

447

448

// Advanced: Custom test framework integration

449

class DetailedAsserter : Asserter {

450

override fun fail(message: String?): Nothing {

451

val location = currentStackTrace()[1] // Skip this frame

452

throw AssertionError("$message\n at ${location.className}.${location.methodName}(${location.fileName}:${location.lineNumber})")

453

}

454

455

override fun assertTrue(message: String?, actual: Boolean) {

456

if (!actual) {

457

fail(message ?: "Assertion failed")

458

}

459

}

460

461

// ... implement other Asserter methods

462

}

463

464

@Test

465

fun testDetailedStackTraceDiagnostics() {

466

// This custom asserter will provide detailed location info

467

val detailedAsserter = DetailedAsserter()

468

469

try {

470

detailedAsserter.assertTrue("This should pass", true)

471

detailedAsserter.assertTrue("This will fail with location", false)

472

} catch (e: AssertionError) {

473

// The error message will include precise location information

474

assertContains(e.message ?: "", "AssertionTests.kt")

475

}

476

}

477

```

478

479

**Platform Notes:**

480

- **Availability**: Only available on JVM platform

481

- **Performance**: Minimal overhead as it uses Java's built-in stack trace mechanism

482

- **Use Cases**: Debugging, custom error reporting, diagnostic utilities

483

- **Stack Frame Structure**: First element [0] is the location where `currentStackTrace()` was called

484

- **Integration**: Used internally by the `todo()` function for location reporting

485

486

This function is particularly useful for building custom assertion utilities, debugging test failures, and creating diagnostic tools that need to report precise location information.