Comprehensive testing toolkit for Akka actor-based systems with synchronous testing utilities, event filtering, and deterministic execution control
npx @tessl/cli install tessl/maven-com-typesafe-akka--akka-testkit_2-11@2.5.00
# Akka TestKit
1
2
Akka TestKit is a comprehensive testing toolkit designed specifically for testing actor-based concurrent and distributed systems built with the Akka framework. It provides essential testing utilities including synchronous message sending and receiving, controllable test actors, event filtering, and deterministic execution control for reliable testing of complex actor interactions and system behaviors.
3
4
## Package Information
5
6
- **Package Name**: akka-testkit
7
- **Package Type**: maven
8
- **Language**: Scala (with Java API)
9
- **Installation**: `libraryDependencies += "com.typesafe.akka" %% "akka-testkit" % "2.5.32" % Test`
10
11
## Core Imports
12
13
```scala
14
import akka.testkit._
15
import akka.actor.ActorSystem
16
import akka.actor.Props
17
```
18
19
For implicit conversions and utilities:
20
21
```scala
22
import akka.testkit.TestDuration._
23
import scala.concurrent.duration._
24
```
25
26
Java API imports:
27
28
```scala
29
import akka.testkit.javadsl.TestKit
30
import akka.testkit.javadsl.EventFilter
31
```
32
33
## Basic Usage
34
35
```scala
36
import akka.testkit.{TestKit, ImplicitSender}
37
import akka.actor.{ActorSystem, Actor, Props}
38
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike}
39
40
class MyActorSpec extends TestKit(ActorSystem("TestSystem"))
41
with ImplicitSender
42
with WordSpecLike
43
with Matchers
44
with BeforeAndAfterAll {
45
46
override def afterAll: Unit = {
47
TestKit.shutdownActorSystem(system)
48
}
49
50
"MyActor" must {
51
"respond to ping with pong" in {
52
val actor = system.actorOf(Props[MyActor])
53
actor ! "ping"
54
expectMsg("pong")
55
}
56
}
57
}
58
```
59
60
## Architecture
61
62
Akka TestKit provides several layers of testing infrastructure:
63
64
- **TestKit Framework**: Core testing classes with assertion methods and timing control
65
- **Specialized Actor References**: TestActorRef and TestFSMRef for synchronous testing access
66
- **Test Utilities**: Probes, barriers, latches, and common test actor patterns
67
- **Deterministic Execution**: Custom dispatchers and schedulers for predictable testing
68
- **Event System**: Comprehensive logging event filtering and interception
69
- **Java Compatibility**: Full Java API with modern Java 8+ features
70
71
## Core Testing Framework
72
73
The foundational testing infrastructure provides synchronous message handling, timing control, and comprehensive assertion methods for actor system testing.
74
75
### TestKit and TestKitBase { .api }
76
77
```scala
78
class TestKit(_system: ActorSystem) extends TestKitBase
79
80
trait TestKitBase {
81
implicit val system: ActorSystem
82
val testKitSettings: TestKitSettings
83
val testActor: ActorRef
84
def lastSender: ActorRef
85
86
// Message expectations
87
def expectMsg[T](obj: T): T
88
def expectMsg[T](max: FiniteDuration, obj: T): T
89
def expectMsg[T](max: FiniteDuration, hint: String, obj: T): T
90
def expectMsgType[T](implicit t: ClassTag[T]): T
91
def expectMsgType[T](max: FiniteDuration)(implicit t: ClassTag[T]): T
92
def expectMsgClass[C](c: Class[C]): C
93
def expectMsgClass[C](max: FiniteDuration, c: Class[C]): C
94
def expectMsgAnyOf[T](objs: T*): T
95
def expectMsgAnyOf[T](max: FiniteDuration, objs: T*): T
96
def expectMsgAllOf[T](objs: T*): immutable.Seq[T]
97
def expectMsgAllOf[T](max: FiniteDuration, objs: T*): immutable.Seq[T]
98
def expectMsgPF[T](max: Duration = Duration.Undefined, hint: String = "")(f: PartialFunction[Any, T]): T
99
def expectTerminated(target: ActorRef, max: Duration = Duration.Undefined): Terminated
100
101
// No message expectations
102
@deprecated("Use expectNoMessage instead", "2.5.5")
103
def expectNoMsg(): Unit
104
@deprecated("Use expectNoMessage instead", "2.5.5")
105
def expectNoMsg(max: FiniteDuration): Unit
106
def expectNoMessage(): Unit
107
def expectNoMessage(max: FiniteDuration): Unit
108
109
// Message reception
110
def receiveOne(max: Duration): AnyRef
111
def receiveN(n: Int): immutable.Seq[AnyRef]
112
def receiveN(n: Int, max: FiniteDuration): immutable.Seq[AnyRef]
113
def receiveWhile[T](max: Duration = Duration.Undefined, idle: Duration = Duration.Inf, messages: Int = Int.MaxValue)(f: PartialFunction[AnyRef, T]): immutable.Seq[T]
114
def fishForMessage(max: Duration = Duration.Undefined, hint: String = "")(fisher: PartialFunction[Any, Boolean]): Any
115
def fishForSpecificMessage[T](max: Duration = Duration.Undefined, hint: String = "")(f: PartialFunction[Any, T]): T
116
117
// Timing control
118
def within[T](min: FiniteDuration, max: FiniteDuration)(f: => T): T
119
def within[T](max: FiniteDuration)(f: => T): T
120
def awaitCond(p: => Boolean, max: Duration = Duration.Undefined, interval: Duration = 100.millis, message: String = ""): Unit
121
def awaitAssert[A](a: => A, max: Duration = Duration.Undefined, interval: Duration = 100.millis): A
122
def remaining: FiniteDuration
123
def remainingOr(duration: FiniteDuration): FiniteDuration
124
def remainingOrDefault: FiniteDuration
125
126
// Actor lifecycle
127
def watch(ref: ActorRef): ActorRef
128
def unwatch(ref: ActorRef): ActorRef
129
def childActorOf(props: Props): ActorRef
130
def childActorOf(props: Props, name: String): ActorRef
131
def childActorOf(props: Props, supervisorStrategy: SupervisorStrategy): ActorRef
132
def childActorOf(props: Props, name: String, supervisorStrategy: SupervisorStrategy): ActorRef
133
134
// Message control
135
def ignoreMsg(f: PartialFunction[Any, Boolean]): Unit
136
def ignoreNoMsg(): Unit
137
def setAutoPilot(pilot: TestActor.AutoPilot): Unit
138
}
139
```
140
141
### TestProbe { .api }
142
143
```scala
144
class TestProbe(_application: ActorSystem, name: String) extends TestKitBase {
145
def ref: ActorRef
146
def send(actor: ActorRef, msg: Any): Unit
147
def forward(actor: ActorRef, msg: Any): Unit
148
def sender(): ActorRef
149
def reply(msg: Any): Unit
150
}
151
152
object TestProbe {
153
def apply()(implicit system: ActorSystem): TestProbe
154
def apply(name: String)(implicit system: ActorSystem): TestProbe
155
}
156
```
157
158
[Core Testing Framework](./core-testing.md)
159
160
## Specialized Actor References
161
162
Specialized actor references that provide synchronous access to actor internals and state for detailed testing scenarios.
163
164
### TestActorRef { .api }
165
166
```scala
167
class TestActorRef[T <: Actor](_system: ActorSystem, _props: Props, _supervisor: ActorRef, name: String) extends InternalActorRef {
168
def receive(o: Any): Unit
169
def receive(o: Any, sender: ActorRef): Unit
170
def underlyingActor: T
171
def watch(subject: ActorRef): ActorRef
172
def unwatch(subject: ActorRef): ActorRef
173
}
174
175
object TestActorRef {
176
def apply[T <: Actor](props: Props)(implicit system: ActorSystem): TestActorRef[T]
177
def apply[T <: Actor](props: Props, name: String)(implicit system: ActorSystem): TestActorRef[T]
178
def apply[T <: Actor](props: Props, supervisor: ActorRef)(implicit system: ActorSystem): TestActorRef[T]
179
def apply[T <: Actor](props: Props, supervisor: ActorRef, name: String)(implicit system: ActorSystem): TestActorRef[T]
180
}
181
```
182
183
### TestFSMRef { .api }
184
185
```scala
186
class TestFSMRef[S, D, T <: Actor](system: ActorSystem, props: Props, supervisor: ActorRef, name: String) extends TestActorRef[T] {
187
def stateName: S
188
def stateData: D
189
def setState(stateName: S, stateData: D, timeout: FiniteDuration, stopReason: Option[FSM.Reason]): Unit
190
def setTimer(name: String, msg: Any, timeout: FiniteDuration, repeat: Boolean): Unit
191
def cancelTimer(name: String): Unit
192
def isTimerActive(name: String): Boolean
193
def isStateTimerActive: Boolean
194
}
195
196
object TestFSMRef {
197
def apply[S, D, T <: Actor: ClassTag](factory: => T)(implicit ev: T <:< FSM[S, D], system: ActorSystem): TestFSMRef[S, D, T]
198
def apply[S, D, T <: Actor: ClassTag](factory: => T, name: String)(implicit ev: T <:< FSM[S, D], system: ActorSystem): TestFSMRef[S, D, T]
199
def apply[S, D, T <: Actor: ClassTag](factory: => T, supervisor: ActorRef)(implicit ev: T <:< FSM[S, D], system: ActorSystem): TestFSMRef[S, D, T]
200
def apply[S, D, T <: Actor: ClassTag](factory: => T, supervisor: ActorRef, name: String)(implicit ev: T <:< FSM[S, D], system: ActorSystem): TestFSMRef[S, D, T]
201
}
202
```
203
204
[Specialized Actor References](./actor-references.md)
205
206
## Test Utilities and Coordination
207
208
Helper classes and utilities for test coordination, synchronization, and common testing patterns.
209
210
### TestActors { .api }
211
212
```scala
213
object TestActors {
214
val echoActorProps: Props
215
val blackholeProps: Props
216
def forwardActorProps(ref: ActorRef): Props
217
}
218
```
219
220
### TestBarrier { .api }
221
222
```scala
223
class TestBarrier(count: Int) {
224
def await()(implicit system: ActorSystem): Unit
225
def await(timeout: FiniteDuration)(implicit system: ActorSystem): Unit
226
def reset(): Unit
227
}
228
229
object TestBarrier {
230
val DefaultTimeout: Duration
231
def apply(count: Int): TestBarrier
232
}
233
```
234
235
### TestLatch { .api }
236
237
```scala
238
class TestLatch(count: Int)(implicit system: ActorSystem) extends Awaitable[Unit] {
239
def countDown(): Unit
240
def isOpen: Boolean
241
def open(): Unit
242
def reset(): Unit
243
def ready(atMost: Duration)(implicit permit: CanAwait): TestLatch
244
def result(atMost: Duration)(implicit permit: CanAwait): Unit
245
}
246
247
object TestLatch {
248
val DefaultTimeout: Duration
249
def apply(count: Int)(implicit system: ActorSystem): TestLatch
250
}
251
```
252
253
[Test Utilities and Coordination](./test-utilities.md)
254
255
## Deterministic Execution Control
256
257
Components for controlling timing and execution order in tests to ensure deterministic, reproducible test runs.
258
259
### CallingThreadDispatcher { .api }
260
261
```scala
262
class CallingThreadDispatcher(_configurator: MessageDispatcherConfigurator) extends MessageDispatcher
263
264
object CallingThreadDispatcher {
265
val Id: String = "akka.test.calling-thread-dispatcher"
266
}
267
```
268
269
### ExplicitlyTriggeredScheduler { .api }
270
271
```scala
272
class ExplicitlyTriggeredScheduler(config: Config, log: LoggingAdapter, tf: ThreadFactory) extends Scheduler {
273
def timePasses(amount: FiniteDuration): Unit
274
def schedule(initialDelay: FiniteDuration, interval: FiniteDuration, runnable: Runnable)(implicit executor: ExecutionContext): Cancellable
275
def scheduleOnce(delay: FiniteDuration, runnable: Runnable)(implicit executor: ExecutionContext): Cancellable
276
def maxFrequency: Double
277
}
278
```
279
280
[Deterministic Execution Control](./deterministic-execution.md)
281
282
## Event Filtering and Testing
283
284
Comprehensive system for intercepting, filtering, and testing logging events and system messages during test execution.
285
286
### EventFilter { .api }
287
288
```scala
289
abstract class EventFilter(occurrences: Int) {
290
def awaitDone(max: Duration): Boolean
291
def assertDone(max: Duration): Unit
292
def intercept[T](code: => T)(implicit system: ActorSystem): T
293
}
294
295
object EventFilter {
296
// Exception-based filters
297
def apply[A <: Throwable: ClassTag](
298
message: String = null,
299
source: String = null,
300
start: String = "",
301
pattern: String = null,
302
occurrences: Int = Int.MaxValue): EventFilter
303
304
// Message-based filters with three matching modes
305
def error(
306
message: String = null,
307
source: String = null,
308
start: String = "",
309
pattern: String = null,
310
occurrences: Int = Int.MaxValue): EventFilter
311
def warning(
312
message: String = null,
313
source: String = null,
314
start: String = "",
315
pattern: String = null,
316
occurrences: Int = Int.MaxValue): EventFilter
317
def info(
318
message: String = null,
319
source: String = null,
320
start: String = "",
321
pattern: String = null,
322
occurrences: Int = Int.MaxValue): EventFilter
323
def debug(
324
message: String = null,
325
source: String = null,
326
start: String = "",
327
pattern: String = null,
328
occurrences: Int = Int.MaxValue): EventFilter
329
330
// Custom filter
331
def custom(test: PartialFunction[LogEvent, Boolean], occurrences: Int = Int.MaxValue): EventFilter
332
}
333
```
334
335
### Package-level filtering functions { .api }
336
337
```scala
338
// In akka.testkit package object
339
def filterEvents[T](eventFilters: Iterable[EventFilter])(block: => T)(implicit system: ActorSystem): T
340
def filterEvents[T](eventFilters: EventFilter*)(block: => T)(implicit system: ActorSystem): T
341
def filterException[T <: Throwable](block: => Unit)(implicit system: ActorSystem, t: ClassTag[T]): Unit
342
```
343
344
[Event Filtering and Testing](./event-filtering.md)
345
346
## Java API
347
348
Modern Java 8+ compatible API providing the same functionality as the Scala API with Java-friendly method signatures and types.
349
350
### javadsl.TestKit { .api }
351
352
```scala
353
class TestKit(system: ActorSystem) {
354
// Java Duration-based methods
355
def expectMsg(duration: java.time.Duration, obj: AnyRef): AnyRef
356
def expectMsgClass(duration: java.time.Duration, clazz: Class[_]): AnyRef
357
def expectNoMessage(duration: java.time.Duration): Unit
358
def within(duration: java.time.Duration, supplier: Supplier[_]): AnyRef
359
}
360
```
361
362
### javadsl.EventFilter { .api }
363
364
```scala
365
class EventFilter(clazz: Class[_], system: ActorSystem) {
366
def message(pattern: String): EventFilter
367
def source(source: String): EventFilter
368
def occurrences(count: Int): EventFilter
369
def intercept[T](supplier: Supplier[T]): T
370
}
371
```
372
373
[Java API](./java-api.md)
374
375
## Utility Classes and Configuration
376
377
Supporting classes for configuration, serialization, networking, and timing utilities.
378
379
### TestKitExtension and Settings { .api }
380
381
```scala
382
object TestKitExtension extends ExtensionId[TestKitSettings] {
383
def get(system: ActorSystem): TestKitSettings
384
def get(system: ClassicActorSystemProvider): TestKitSettings
385
}
386
387
class TestKitSettings(config: Config) {
388
val TestTimeFactor: Double
389
val SingleExpectDefaultTimeout: FiniteDuration
390
val TestEventFilterLeeway: FiniteDuration
391
val DefaultTimeout: Timeout
392
}
393
```
394
395
### SocketUtil { .api }
396
397
```scala
398
object SocketUtil {
399
def temporaryLocalPort(udp: Boolean = false): Int
400
def temporaryLocalPort(protocol: Protocol): Int
401
def temporaryServerAddress(address: String = "127.0.0.1", udp: Boolean = false): InetSocketAddress
402
def temporaryServerAddresses(numberOfAddresses: Int, hostname: String, udp: Boolean): immutable.IndexedSeq[InetSocketAddress]
403
404
sealed trait Protocol
405
case object Tcp extends Protocol
406
case object Udp extends Protocol
407
case object Both extends Protocol
408
}
409
```
410
411
### TestDuration (implicit class) { .api }
412
413
```scala
414
// In akka.testkit package object
415
implicit class TestDuration(val duration: FiniteDuration) extends AnyVal {
416
def dilated(implicit system: ActorSystem): FiniteDuration
417
}
418
```
419
420
[Utility Classes and Configuration](./utilities-config.md)