or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

actor-refs.mdconfiguration.mdcore-testing.mddispatchers.mdevent-filtering.mdindex.mdjava-dsl.mdpackage-functions.mdsynchronization.mdtest-actors.mdutilities.md

configuration.mddocs/

0

# Configuration and Extensions

1

2

TestKit configuration system and Akka extensions for customizing test behavior, timeouts, and environment settings.

3

4

## Capabilities

5

6

### TestKitExtension

7

8

Akka extension for accessing TestKit settings and configuration.

9

10

```scala { .api }

11

object TestKitExtension extends ExtensionId[TestKitSettings] with ExtensionIdProvider {

12

def apply(system: ActorSystem): TestKitSettings

13

def apply(system: ExtendedActorSystem): TestKitSettings

14

def createExtension(system: ExtendedActorSystem): TestKitSettings

15

def lookup(): ExtensionId[_ <: Extension] = TestKitExtension

16

}

17

```

18

19

### TestKitSettings

20

21

Configuration settings class for TestKit behavior and timeouts.

22

23

```scala { .api }

24

class TestKitSettings(val config: Config) extends Extension {

25

import TestKitSettings._

26

27

// Core timing settings

28

val TestTimeFactor: Double

29

val SingleExpectDefaultTimeout: FiniteDuration

30

val MultiExpectDefaultTimeout: FiniteDuration

31

val ExpectNoMessageDefaultTimeout: FiniteDuration

32

val TestEventFilterLeeway: FiniteDuration

33

val DefaultTimeout: Timeout

34

35

// Utility methods

36

def dilated(duration: FiniteDuration): FiniteDuration

37

}

38

39

object TestKitSettings {

40

def apply(system: ActorSystem): TestKitSettings = TestKitExtension(system)

41

}

42

```

43

44

## Configuration Reference

45

46

### Default Configuration Values

47

48

```hocon

49

akka.test {

50

# Time factor for dilating timeouts in tests

51

# Set higher for slow test environments (CI, etc.)

52

timefactor = 1.0

53

54

# Default timeout for single message expectations

55

single-expect-default = 3s

56

57

# Default timeout for multi-message expectations

58

multi-expect-default = 3s

59

60

# Default timeout for expectNoMessage calls

61

expect-no-message-default = 100ms

62

63

# Extra time to wait for expected log events in EventFilter

64

filter-leeway = 3s

65

66

# Default dispatcher for test actors

67

default-timeout = 5s

68

}

69

```

70

71

### Usage Examples

72

73

**Accessing Configuration:**

74

75

```scala

76

import akka.testkit.{TestKit, TestKitExtension}

77

78

class ConfigurationTest extends TestKit(ActorSystem("TestSystem")) {

79

val settings = TestKitExtension(system)

80

81

"TestKit configuration" should {

82

"provide access to timing settings" in {

83

settings.TestTimeFactor should be >= 1.0

84

settings.SingleExpectDefaultTimeout should be > Duration.Zero

85

settings.MultiExpectDefaultTimeout should be > Duration.Zero

86

settings.ExpectNoMessageDefaultTimeout should be > Duration.Zero

87

settings.TestEventFilterLeeway should be > Duration.Zero

88

settings.DefaultTimeout.duration should be > Duration.Zero

89

}

90

91

"dilate durations correctly" in {

92

val original = 1.second

93

val dilated = settings.dilated(original)

94

95

dilated should be >= original

96

dilated should equal(Duration.fromNanos((original.toNanos * settings.TestTimeFactor).toLong))

97

}

98

99

"be accessible through extension" in {

100

val settingsViaExtension = TestKitExtension(system)

101

val settingsViaApply = TestKitSettings(system)

102

103

settingsViaExtension should be theSameInstanceAs settingsViaApply

104

}

105

}

106

}

107

```

108

109

### Custom Configuration

110

111

**Override Default Values:**

112

113

```scala

114

// Custom configuration in application.conf or test configuration

115

val customConfig = ConfigFactory.parseString("""

116

akka.test {

117

timefactor = 2.0

118

single-expect-default = 5s

119

multi-expect-default = 10s

120

expect-no-message-default = 200ms

121

filter-leeway = 5s

122

default-timeout = 30s

123

}

124

""")

125

126

val system = ActorSystem("CustomTestSystem", customConfig)

127

128

class CustomConfigTest extends TestKit(system) {

129

"Custom configuration" should {

130

"use overridden values" in {

131

val settings = TestKitExtension(system)

132

133

settings.TestTimeFactor should equal(2.0)

134

settings.SingleExpectDefaultTimeout should equal(5.seconds)

135

settings.MultiExpectDefaultTimeout should equal(10.seconds)

136

settings.ExpectNoMessageDefaultTimeout should equal(200.millis)

137

settings.TestEventFilterLeeway should equal(5.seconds)

138

settings.DefaultTimeout.duration should equal(30.seconds)

139

}

140

}

141

}

142

```

143

144

**Environment-Specific Configuration:**

145

146

```scala

147

// Different configurations for different environments

148

object TestConfigurations {

149

val ciConfig = ConfigFactory.parseString("""

150

akka.test {

151

timefactor = 3.0 # Slower CI environment

152

single-expect-default = 10s

153

filter-leeway = 10s

154

}

155

""")

156

157

val localConfig = ConfigFactory.parseString("""

158

akka.test {

159

timefactor = 1.0 # Fast local development

160

single-expect-default = 3s

161

filter-leeway = 3s

162

}

163

""")

164

165

val loadTestConfig = ConfigFactory.parseString("""

166

akka.test {

167

timefactor = 5.0 # Very slow load testing environment

168

single-expect-default = 30s

169

multi-expect-default = 60s

170

filter-leeway = 15s

171

}

172

""")

173

174

def getConfig(environment: String): Config = environment match {

175

case "ci" => ciConfig

176

case "local" => localConfig

177

case "load" => loadTestConfig

178

case _ => ConfigFactory.empty()

179

}

180

}

181

182

// Usage in tests

183

class EnvironmentConfigTest {

184

val environment = sys.env.getOrElse("TEST_ENV", "local")

185

val config = TestConfigurations.getConfig(environment)

186

val system = ActorSystem("EnvTestSystem", config)

187

188

// Tests will use environment-appropriate timeouts

189

}

190

```

191

192

### Integration with TestKit Features

193

194

**Automatic Timeout Usage:**

195

196

```scala

197

class TimeoutIntegrationTest extends TestKit(ActorSystem("TestSystem")) with DefaultTimeout {

198

"TestKit with configuration" should {

199

"use configured timeouts automatically" in {

200

val actor = system.actorOf(Props(new Actor {

201

def receive = {

202

case msg =>

203

Thread.sleep(100) // Simulate work

204

sender() ! s"processed: $msg"

205

}

206

}))

207

208

// Uses SingleExpectDefaultTimeout from configuration

209

actor ! "test"

210

expectMsg("processed: test") // No explicit timeout needed

211

212

// Uses ExpectNoMessageDefaultTimeout from configuration

213

expectNoMessage() // Uses configured default

214

}

215

216

"respect time dilation" in {

217

import akka.testkit._

218

219

// All dilated timeouts use TestTimeFactor

220

within(2.seconds.dilated) {

221

// Code that might run slowly in some environments

222

Thread.sleep(100)

223

expectNoMessage(100.millis.dilated)

224

}

225

}

226

}

227

}

228

```

229

230

**Event Filter Configuration Integration:**

231

232

```scala

233

class EventFilterConfigTest extends TestKit(ActorSystem("TestSystem")) {

234

"Event filters with configuration" should {

235

"use configured filter leeway" in {

236

val settings = TestKitExtension(system)

237

238

// EventFilter internally uses TestEventFilterLeeway for timeout

239

EventFilter.info(message = "test message").intercept {

240

// Simulate slow logging

241

Future {

242

Thread.sleep(settings.TestEventFilterLeeway.toMillis / 2)

243

log.info("test message")

244

}

245

246

// Filter waits up to filter-leeway time for the event

247

}

248

}

249

}

250

}

251

```

252

253

### Advanced Configuration Patterns

254

255

**Dynamic Configuration:**

256

257

```scala

258

class DynamicConfigTest {

259

def createSystemWithTimeoutFactor(factor: Double): ActorSystem = {

260

val config = ConfigFactory.parseString(s"""

261

akka.test.timefactor = $factor

262

""")

263

ActorSystem("DynamicTestSystem", config)

264

}

265

266

"Dynamic configuration" should {

267

"allow runtime configuration changes" in {

268

val fastSystem = createSystemWithTimeoutFactor(1.0)

269

val slowSystem = createSystemWithTimeoutFactor(5.0)

270

271

val fastKit = new TestKit(fastSystem)

272

val slowKit = new TestKit(slowSystem)

273

274

import fastKit._

275

val fastSettings = TestKitExtension(fastSystem)

276

fastSettings.TestTimeFactor should equal(1.0)

277

278

import slowKit._

279

val slowSettings = TestKitExtension(slowSystem)

280

slowSettings.TestTimeFactor should equal(5.0)

281

282

fastSystem.terminate()

283

slowSystem.terminate()

284

}

285

}

286

}

287

```

288

289

**Configuration Validation:**

290

291

```scala

292

class ConfigValidationTest extends TestKit(ActorSystem("TestSystem")) {

293

"Configuration validation" should {

294

"ensure reasonable timeout values" in {

295

val settings = TestKitExtension(system)

296

297

// Validate timeout values are reasonable

298

settings.SingleExpectDefaultTimeout should be >= 100.millis

299

settings.MultiExpectDefaultTimeout should be >= settings.SingleExpectDefaultTimeout

300

settings.TestEventFilterLeeway should be >= 1.second

301

settings.TestTimeFactor should be >= 1.0

302

303

// Validate dilated timeouts don't exceed reasonable bounds

304

val dilated = settings.dilated(1.minute)

305

dilated should be <= 10.minutes // Reasonable upper bound

306

}

307

308

"provide consistent configuration access" in {

309

// Multiple ways to access should return same instance

310

val settings1 = TestKitExtension(system)

311

val settings2 = TestKitSettings(system)

312

313

settings1 should be theSameInstanceAs settings2

314

settings1.TestTimeFactor should equal(settings2.TestTimeFactor)

315

}

316

}

317

}

318

```

319

320

### Best Practices

321

322

1. **Environment-Specific Configuration**: Use different time factors for different environments

323

2. **Reasonable Defaults**: Start with default configuration and adjust based on test performance

324

3. **Consistent Access**: Use TestKitExtension for consistent settings access

325

4. **Time Dilation**: Always use dilated timeouts for environment independence

326

5. **Configuration Testing**: Validate your configuration settings in tests

327

328

```scala

329

// Good: Environment-aware configuration

330

val timeFactor = if (sys.env.contains("CI")) 3.0 else 1.0

331

val config = ConfigFactory.parseString(s"akka.test.timefactor = $timeFactor")

332

333

// Good: Consistent settings access

334

val settings = TestKitExtension(system)

335

val timeout = settings.SingleExpectDefaultTimeout

336

337

// Good: Use dilated timeouts everywhere

338

expectMsg(5.seconds.dilated, expectedMessage)

339

within(10.seconds.dilated) { /* test code */ }

340

341

// Good: Validate configuration in tests

342

assert(settings.TestTimeFactor >= 1.0, "Time factor should be at least 1.0")

343

assert(settings.DefaultTimeout.duration > Duration.Zero, "Default timeout must be positive")

344

```

345

346

### Common Configuration Issues

347

348

**Performance Issues:**

349

```scala

350

// Problem: Time factor too high for local development

351

akka.test.timefactor = 10.0 // Makes tests unnecessarily slow locally

352

353

// Solution: Environment-specific factors

354

akka.test.timefactor = ${?TEST_TIME_FACTOR} // Override via environment variable

355

```

356

357

**Timeout Issues:**

358

```scala

359

// Problem: Timeouts too short for slow operations

360

akka.test.single-expect-default = 100ms // Too short for most operations

361

362

// Solution: Reasonable defaults with dilation

363

akka.test.single-expect-default = 3s

364

// Then use .dilated in tests for environment adaptation

365

```

366

367

**Filter Issues:**

368

```scala

369

// Problem: Filter leeway too short for async logging

370

akka.test.filter-leeway = 100ms // May miss async log events

371

372

// Solution: Adequate leeway for async operations

373

akka.test.filter-leeway = 3s

374

```