or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# KotlinTest Runner JUnit5

1

2

KotlinTest Runner JUnit5 is a JUnit Platform TestEngine implementation that integrates the KotlinTest testing framework with JUnit 5 ecosystem. It enables KotlinTest specifications to be discovered and executed by JUnit Platform launchers, allowing KotlinTest's expressive testing styles to work seamlessly with JUnit 5 tooling including IDEs, build tools like Gradle and Maven, and CI/CD systems.

3

4

## Package Information

5

6

- **Package Name**: kotlintest-runner-junit5

7

- **Package Type**: maven

8

- **Language**: Kotlin

9

- **Group ID**: io.kotlintest

10

- **Artifact ID**: kotlintest-runner-junit5

11

- **Installation**: Add to build.gradle: `testImplementation 'io.kotlintest:kotlintest-runner-junit5:3.4.2'`

12

13

## Core Imports

14

15

```kotlin

16

import io.kotlintest.runner.junit5.KotlinTestEngine

17

import io.kotlintest.specs.*

18

```

19

20

For test specifications, extend from the spec classes:

21

22

```kotlin

23

import io.kotlintest.specs.StringSpec

24

import io.kotlintest.specs.FunSpec

25

import io.kotlintest.specs.BehaviorSpec

26

// ... other spec types

27

```

28

29

## Basic Usage

30

31

```kotlin

32

// Example test using StringSpec with JUnit 5 integration

33

import io.kotlintest.specs.StringSpec

34

import io.kotlintest.shouldBe

35

36

class CalculatorTest : StringSpec({

37

"addition should work correctly" {

38

val result = 2 + 2

39

result shouldBe 4

40

}

41

42

"multiplication should work correctly" {

43

val result = 3 * 4

44

result shouldBe 12

45

}

46

})

47

```

48

49

The engine is automatically discovered by JUnit Platform through service loading, so no explicit configuration is needed beyond adding the dependency.

50

51

## Architecture

52

53

The integration works through several key components:

54

55

- **TestEngine Implementation**: `KotlinTestEngine` implements JUnit Platform's TestEngine interface

56

- **Test Discovery**: Converts JUnit discovery requests to KotlinTest's internal format

57

- **Execution Bridging**: Translates KotlinTest's test execution model to JUnit Platform's execution lifecycle

58

- **IDE Integration**: IntelliJ-compatible spec classes for better development experience

59

- **Thread Safety**: Synchronized execution listeners to handle concurrent test execution

60

61

## Capabilities

62

63

### Test Engine Implementation

64

65

Core JUnit Platform TestEngine that discovers and executes KotlinTest specifications.

66

67

```kotlin { .api }

68

class KotlinTestEngine : TestEngine {

69

companion object {

70

const val EngineId = "kotlintest"

71

}

72

73

override fun getId(): String

74

override fun discover(

75

request: EngineDiscoveryRequest,

76

uniqueId: UniqueId

77

): KotlinTestEngineDescriptor

78

override fun execute(request: ExecutionRequest)

79

80

class KotlinTestEngineDescriptor(

81

id: UniqueId,

82

val classes: List<KClass<out Spec>>

83

) : EngineDescriptor {

84

override fun mayRegisterTests(): Boolean

85

}

86

}

87

```

88

89

### Test Execution Listener

90

91

JUnit Platform execution listener that bridges KotlinTest's execution events to JUnit Platform's reporting model.

92

93

```kotlin { .api }

94

class JUnitTestRunnerListener(

95

private val listener: EngineExecutionListener,

96

val root: EngineDescriptor

97

) : TestEngineListener {

98

99

data class ResultState(val testCase: TestCase, val result: TestResult)

100

101

override fun engineStarted(classes: List<KClass<out Spec>>)

102

override fun engineFinished(t: Throwable?)

103

override fun beforeSpecClass(klass: KClass<out Spec>)

104

override fun afterSpecClass(klass: KClass<out Spec>, t: Throwable?)

105

override fun enterTestCase(testCase: TestCase)

106

override fun invokingTestCase(testCase: TestCase, k: Int)

107

override fun exitTestCase(testCase: TestCase, result: TestResult)

108

override fun specInitialisationFailed(klass: KClass<out Spec>, t: Throwable)

109

}

110

```

111

112

### Thread-Safe Execution Listener

113

114

Synchronized wrapper around EngineExecutionListener to handle concurrent test execution safely.

115

116

```kotlin { .api }

117

class SynchronizedEngineExecutionListener(

118

val listener: EngineExecutionListener

119

) : EngineExecutionListener {

120

121

override fun executionFinished(

122

testDescriptor: TestDescriptor?,

123

testExecutionResult: TestExecutionResult?

124

)

125

override fun reportingEntryPublished(

126

testDescriptor: TestDescriptor?,

127

entry: ReportEntry?

128

)

129

override fun executionSkipped(

130

testDescriptor: TestDescriptor?,

131

reason: String?

132

)

133

override fun executionStarted(testDescriptor: TestDescriptor?)

134

override fun dynamicTestRegistered(testDescriptor: TestDescriptor?)

135

}

136

```

137

138

### Discovery Request Conversion

139

140

Utility function that converts JUnit Platform discovery requests to KotlinTest's internal discovery format.

141

142

```kotlin { .api }

143

/**

144

* Returns a KotlinTest [DiscoveryRequest] built from the selectors and filters present

145

* in the JUnit [EngineDiscoveryRequest].

146

*

147

* Supported selectors are:

148

* - [ClassSelector] - used to specify a single class by fully qualified name

149

* - [DirectorySelector] - classes are scanned in the given directory

150

* - [UriSelector] - classes are scanned from the given uri

151

* - [PackageSelector] - classes are scanned on the default classpath for the given package name

152

*

153

* Support filters are:

154

* - [ClassNameFilter] - filters out specs based on a classname

155

* - [PackageNameFilter] - filters out specs based on package names

156

*

157

* Unsupported selectors are:

158

* - [MethodSelector] - not supported because kotlintest does not define tests as methods/functions

159

*/

160

internal fun discoveryRequest(request: EngineDiscoveryRequest): DiscoveryRequest

161

```

162

163

### IntelliJ IDE Integration Specs

164

165

Abstract spec classes that provide better IntelliJ IDEA integration through marker interface and annotations.

166

167

```kotlin { .api }

168

interface IntelliMarker {

169

@EnabledIfSystemProperty(named = "wibble", matches = "wobble")

170

@TestFactory

171

fun primer() {

172

}

173

}

174

175

abstract class AnnotationSpec(

176

body: AbstractAnnotationSpec.() -> Unit = {}

177

) : AbstractAnnotationSpec(body), IntelliMarker

178

179

abstract class BehaviorSpec(

180

body: AbstractBehaviorSpec.() -> Unit = {}

181

) : AbstractBehaviorSpec(body), IntelliMarker

182

183

abstract class DescribeSpec(

184

body: AbstractDescribeSpec.() -> Unit = {}

185

) : AbstractDescribeSpec(body), IntelliMarker

186

187

abstract class ExpectSpec(

188

body: AbstractExpectSpec.() -> Unit = {}

189

) : AbstractExpectSpec(body), IntelliMarker

190

191

abstract class FeatureSpec(

192

body: AbstractFeatureSpec.() -> Unit = {}

193

) : AbstractFeatureSpec(body), IntelliMarker

194

195

abstract class FreeSpec(

196

body: AbstractFreeSpec.() -> Unit = {}

197

) : AbstractFreeSpec(body), IntelliMarker

198

199

abstract class FunSpec(

200

body: AbstractFunSpec.() -> Unit = {}

201

) : AbstractFunSpec(body), IntelliMarker

202

203

abstract class ShouldSpec(

204

body: AbstractShouldSpec.() -> Unit = {}

205

) : AbstractShouldSpec(body), IntelliMarker {

206

infix fun String.should(matcher: Matcher<String>): Unit

207

}

208

209

abstract class StringSpec(

210

body: AbstractStringSpec.() -> Unit = {}

211

) : AbstractStringSpec(body), IntelliMarker

212

213

abstract class WordSpec(

214

body: AbstractWordSpec.() -> Unit = {}

215

) : AbstractWordSpec(body), IntelliMarker {

216

infix fun String?.should(matcher: Matcher<String?>): Unit

217

}

218

```

219

220

### Debug Utilities

221

222

Extension functions for debugging JUnit Platform discovery requests.

223

224

```kotlin { .api }

225

fun EngineDiscoveryRequest.string(): String

226

fun LauncherDiscoveryRequest.string(): String

227

```

228

229

### UniqueId Extensions

230

231

Extension function for creating spec-specific unique IDs in the JUnit Platform descriptor hierarchy.

232

233

```kotlin { .api }

234

fun UniqueId.appendSpec(description: Description): UniqueId

235

```

236

237

## Types

238

239

```kotlin { .api }

240

// From KotlinTest framework (imported dependencies)

241

interface Spec

242

interface TestEngineListener

243

interface TestCase

244

interface TestResult

245

interface TestStatus

246

interface Description

247

class Matcher<T>

248

249

// From JUnit Platform (imported dependencies)

250

interface TestEngine

251

interface EngineDiscoveryRequest

252

interface ExecutionRequest

253

interface TestDescriptor

254

interface EngineExecutionListener

255

interface TestExecutionResult

256

interface ReportEntry

257

class UniqueId

258

class EngineDescriptor

259

260

```

261

262

## Service Registration

263

264

The engine is automatically registered with JUnit Platform through Java's ServiceLoader mechanism:

265

266

- **Service File**: `META-INF/services/org.junit.platform.engine.TestEngine`

267

- **Implementation**: `io.kotlintest.runner.junit5.KotlinTestEngine`

268

269

This allows JUnit Platform to automatically discover and use the KotlinTest engine without explicit configuration.

270

271

## Error Handling

272

273

The engine handles various error scenarios:

274

275

- **Spec Initialization Failures**: Reported as test failures in JUnit Platform

276

- **Test Execution Failures**: Converted to JUnit Platform's TestExecutionResult format

277

- **Discovery Errors**: Logged and result in empty test descriptor sets

278

- **Thread Safety**: All listener notifications are synchronized to prevent race conditions

279

280

## Integration Notes

281

282

- **Gradle Integration**: Works with Gradle's JUnit Platform support

283

- **Maven Integration**: Compatible with Maven Surefire plugin's JUnit Platform support

284

- **IDE Support**: IntelliJ IDEA can discover and run KotlinTest specifications

285

- **CI/CD**: Works with any CI/CD system that supports JUnit Platform

286

- **Filtering**: Supports JUnit Platform's test filtering mechanisms (packages, classes, etc.)

287

- **Parallel Execution**: Respects KotlinTest's parallelism configuration