or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

boolean-assertions.mdcollection-assertions.mdequality-assertions.mdexception-testing.mdframework-integration.mdindex.mdtest-annotations.mdtest-utilities.mdtype-null-assertions.md

framework-integration.mddocs/

0

# Framework Integration

1

2

Core interfaces and utilities for integrating with different testing frameworks across Kotlin multiplatform targets. This system provides a pluggable architecture that allows the same test code to work with JUnit, TestNG, JavaScript testing frameworks, and native testing environments.

3

4

## Capabilities

5

6

### Asserter Interface

7

8

The core interface that abstracts assertion logic and provides integration points for different testing frameworks.

9

10

```kotlin { .api }

11

/**

12

* Interface that abstracts the assertion logic and can be implemented by

13

* any testing framework to provide consistent assertion behavior across platforms.

14

*/

15

interface Asserter {

16

/**

17

* Marks a test as failed with the specified message.

18

* @param message The failure message, or null for default message

19

* @return Nothing (this function never returns normally)

20

*/

21

fun fail(message: String?): Nothing

22

23

/**

24

* Marks a test as failed with the specified message and cause.

25

* @param message The failure message, or null for default message

26

* @param cause The underlying cause of the failure, or null if none

27

* @return Nothing (this function never returns normally)

28

*/

29

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

30

31

/**

32

* Asserts that the value is true.

33

* @param lazyMessage Lazy-evaluated message provider for failure cases

34

* @param actual The boolean value to test

35

*/

36

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

37

38

/**

39

* Asserts that the value is true.

40

* @param message The failure message, or null for default

41

* @param actual The boolean value to test

42

*/

43

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

44

45

/**

46

* Asserts that the expected and actual values are equal.

47

* @param message The failure message, or null for default

48

* @param expected The expected value

49

* @param actual The actual value to compare

50

*/

51

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

52

53

/**

54

* Asserts that the illegal and actual values are not equal.

55

* @param message The failure message, or null for default

56

* @param illegal The value that should not match

57

* @param actual The actual value to compare

58

*/

59

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

60

61

/**

62

* Asserts that the expected and actual references are the same instance.

63

* @param message The failure message, or null for default

64

* @param expected The expected object reference

65

* @param actual The actual object reference

66

*/

67

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

68

69

/**

70

* Asserts that the illegal and actual references are not the same instance.

71

* @param message The failure message, or null for default

72

* @param illegal The reference that should not match

73

* @param actual The actual object reference

74

*/

75

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

76

77

/**

78

* Asserts that the actual value is null.

79

* @param message The failure message, or null for default

80

* @param actual The value to test for null

81

*/

82

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

83

84

/**

85

* Asserts that the actual value is not null.

86

* @param message The failure message, or null for default

87

* @param actual The value to test for non-null

88

*/

89

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

90

}

91

```

92

93

### AsserterContributor Interface

94

95

Interface for providing custom Asserter implementations in a pluggable way.

96

97

```kotlin { .api }

98

/**

99

* Interface for providing Asserter instances. Implementations can be registered

100

* to contribute custom assertion behavior for specific testing frameworks.

101

*/

102

interface AsserterContributor {

103

/**

104

* Provides an Asserter instance for the current testing context.

105

* @return An Asserter implementation, or null if this contributor

106

* cannot provide one for the current context

107

*/

108

fun contribute(): Asserter?

109

}

110

```

111

112

### Global Asserter Property

113

114

The global asserter property that holds the current assertion implementation.

115

116

```kotlin { .api }

117

/**

118

* The current Asserter instance used by all assertion functions.

119

* This can be replaced to integrate with different testing frameworks.

120

* Defaults to DefaultAsserter if no framework-specific asserter is available.

121

*/

122

var asserter: Asserter

123

```

124

125

**Usage Examples:**

126

127

```kotlin

128

import kotlin.test.*

129

130

@Test

131

fun testCustomAsserterIntegration() {

132

// Save the original asserter

133

val originalAsserter = asserter

134

135

try {

136

// Install a custom asserter for specialized behavior

137

asserter = CustomTestAsserter()

138

139

// All assertions now use the custom asserter

140

assertEquals("expected", "actual") // Uses CustomTestAsserter.assertEquals()

141

assertTrue(false) // Uses CustomTestAsserter.assertTrue()

142

143

} finally {

144

// Restore original asserter

145

asserter = originalAsserter

146

}

147

}

148

149

class CustomTestAsserter : Asserter {

150

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

151

throw CustomAssertionError(message ?: "Assertion failed")

152

}

153

154

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

155

throw CustomAssertionError(message ?: "Assertion failed", cause)

156

}

157

158

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

159

if (!actual) {

160

fail(message ?: "Expected true but was false")

161

}

162

}

163

164

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

165

if (expected != actual) {

166

fail(message ?: "Expected <$expected> but was <$actual>")

167

}

168

}

169

170

// ... implement other methods

171

}

172

```

173

174

### DefaultAsserter Object

175

176

The default asserter implementation used when no framework-specific asserter is available.

177

178

```kotlin { .api }

179

/**

180

* Default Asserter implementation that provides basic assertion functionality

181

* without depending on any specific testing framework.

182

*/

183

object DefaultAsserter : Asserter {

184

/**

185

* Throws AssertionError with the specified message.

186

*/

187

override fun fail(message: String?): Nothing

188

189

/**

190

* Throws AssertionErrorWithCause with the specified message and cause.

191

*/

192

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

193

}

194

```

195

196

## Platform-Specific Integration Examples

197

198

### JVM Integration (JUnit)

199

200

```kotlin

201

// Custom JUnit asserter implementation

202

class JUnitAsserter : Asserter {

203

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

204

org.junit.Assert.fail(message)

205

throw AssertionError() // Never reached

206

}

207

208

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

209

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

210

}

211

212

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

213

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

214

}

215

216

// ... other implementations delegate to JUnit

217

}

218

219

// Register the asserter

220

class JUnitAsserterContributor : AsserterContributor {

221

override fun contribute(): Asserter? {

222

return if (isJUnitAvailable()) JUnitAsserter() else null

223

}

224

225

private fun isJUnitAvailable(): Boolean {

226

return try {

227

Class.forName("org.junit.Assert")

228

true

229

} catch (e: ClassNotFoundException) {

230

false

231

}

232

}

233

}

234

```

235

236

### JavaScript Integration

237

238

```kotlin

239

// Custom JavaScript asserter for Node.js environments

240

class NodeJSAsserter : Asserter {

241

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

242

js("throw new Error(message || 'Assertion failed')")

243

}

244

245

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

246

if (!actual) {

247

fail(message ?: "Expected true but was false")

248

}

249

}

250

251

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

252

js("""

253

const assert = require('assert');

254

assert.deepStrictEqual(actual, expected, message);

255

""")

256

}

257

258

// ... other implementations

259

}

260

```

261

262

### Native Integration

263

264

```kotlin

265

// Custom native asserter implementation

266

class NativeAsserter : Asserter {

267

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

268

// Native-specific error reporting

269

platform.posix.fprintf(platform.posix.stderr, "ASSERTION FAILED: %s\n", message ?: "")

270

platform.posix.exit(1)

271

throw AssertionError() // Never reached

272

}

273

274

// ... other implementations using native APIs

275

}

276

```

277

278

## Custom Framework Integration

279

280

### Creating a Custom Testing Framework Integration

281

282

```kotlin

283

import kotlin.test.*

284

285

// Step 1: Implement the Asserter interface

286

class MyFrameworkAsserter : Asserter {

287

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

288

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

289

throw MyFrameworkException(message)

290

}

291

292

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

293

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

294

throw MyFrameworkException(message, cause)

295

}

296

297

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

298

if (!actual) {

299

MyTestFramework.reportBooleanFailure(message, expected = true, actual = false)

300

fail(message ?: "Expected true but was false")

301

}

302

}

303

304

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

305

if (expected != actual) {

306

MyTestFramework.reportEqualityFailure(message, expected, actual)

307

fail(message ?: "Expected <$expected> but was <$actual>")

308

}

309

}

310

311

// Implement remaining methods...

312

}

313

314

// Step 2: Create an AsserterContributor

315

class MyFrameworkAsserterContributor : AsserterContributor {

316

override fun contribute(): Asserter? {

317

return if (MyTestFramework.isActive()) {

318

MyFrameworkAsserter()

319

} else {

320

null

321

}

322

}

323

}

324

325

// Step 3: Register the contributor (usually done during framework initialization)

326

fun initializeMyFramework() {

327

val contributor = MyFrameworkAsserterContributor()

328

val customAsserter = contributor.contribute()

329

if (customAsserter != null) {

330

asserter = customAsserter

331

}

332

}

333

```

334

335

### Advanced Integration Features

336

337

```kotlin

338

// Enhanced asserter with additional framework-specific features

339

class EnhancedFrameworkAsserter : Asserter {

340

private val testContext = MyFramework.getCurrentTestContext()

341

342

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

343

// Capture additional context

344

val stackTrace = Thread.currentThread().stackTrace

345

val testMethod = stackTrace.find { it.methodName.startsWith("test") }

346

347

MyFramework.reportDetailedFailure(

348

message = message,

349

testClass = testContext.testClass,

350

testMethod = testMethod?.methodName,

351

stackTrace = stackTrace

352

)

353

354

throw MyFrameworkException(message)

355

}

356

357

// Override other methods with enhanced reporting...

358

359

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

360

if (expected != actual) {

361

// Enhanced diff reporting

362

val diff = MyFramework.computeDiff(expected, actual)

363

MyFramework.reportEqualityFailure(

364

message = message,

365

expected = expected,

366

actual = actual,

367

diff = diff

368

)

369

fail(buildEqualityMessage(message, expected, actual, diff))

370

}

371

}

372

373

private fun buildEqualityMessage(

374

userMessage: String?,

375

expected: Any?,

376

actual: Any?,

377

diff: String

378

): String {

379

val base = userMessage ?: "Assertion failed"

380

return "$base\nExpected: $expected\nActual: $actual\nDiff:\n$diff"

381

}

382

}

383

```

384

385

## Error Handling and Framework Compatibility

386

387

The framework integration system handles various error scenarios gracefully:

388

389

- **Missing Framework**: Falls back to `DefaultAsserter` if no framework-specific asserter is available

390

- **Framework Conflicts**: Multiple asserter contributors can coexist; the first successful one is used

391

- **Runtime Switching**: The asserter can be changed during test execution for specialized testing scenarios

392

393

```kotlin

394

@Test

395

fun testFrameworkFallback() {

396

// This test works regardless of which testing framework is present

397

assertEquals("expected", computeValue())

398

assertTrue(isValid())

399

400

// The underlying asserter handles framework-specific reporting

401

}

402

```