0
# Test Runners
1
2
This document covers the platform-specific test runners that execute ZIO tests within the SBT ecosystem.
3
4
## BaseTestTask
5
6
The shared base class for all ZIO test tasks across platforms.
7
8
```scala { .api }
9
abstract class BaseTestTask[T](
10
taskDef0: sbt.testing.TaskDef,
11
testClassLoader: ClassLoader,
12
sendSummary: SendSummary,
13
args: zio.test.TestArgs,
14
spec: zio.test.ZIOSpecAbstract,
15
runtime: zio.Runtime[T],
16
console: zio.Console
17
) extends sbt.testing.Task {
18
19
final def taskDef(): sbt.testing.TaskDef
20
def execute(eventHandler: sbt.testing.EventHandler, loggers: Array[sbt.testing.Logger]): Array[sbt.testing.Task]
21
def tags(): Array[String]
22
23
// Protected methods for subclass customization
24
protected def sharedFilledTestLayer(implicit trace: zio.Trace): zio.ZLayer[Any, Nothing, zio.test.TestEnvironment with zio.ZIOAppArgs with zio.Scope]
25
}
26
```
27
28
### Constructor Parameters
29
30
- `taskDef0`: SBT task definition containing test class information
31
- `testClassLoader`: ClassLoader for loading test classes
32
- `sendSummary`: Function for sending test summaries
33
- `args`: ZIO test arguments and configuration
34
- `spec`: The ZIO test specification to execute
35
- `runtime`: ZIO runtime for test execution
36
- `console`: Console implementation for test output
37
38
### Methods
39
40
#### taskDef
41
42
Returns the SBT task definition.
43
44
```scala
45
baseTask.taskDef()
46
// Returns: sbt.testing.TaskDef
47
```
48
49
#### execute
50
51
Executes the test task and returns any subtasks.
52
53
**Parameters:**
54
- `eventHandler`: SBT event handler for test result reporting
55
- `loggers`: Array of SBT loggers for output
56
57
**Returns:** Array of additional tasks (typically empty)
58
59
#### tags
60
61
Returns task tags for SBT categorization.
62
63
```scala
64
baseTask.tags()
65
// Returns: Array[String] (empty array)
66
```
67
68
## JVM Test Runner
69
70
The full-featured JVM test runner with advanced capabilities.
71
72
```scala { .api }
73
final class ZTestRunnerJVM(
74
val args: Array[String],
75
val remoteArgs: Array[String],
76
testClassLoader: ClassLoader
77
) extends sbt.testing.Runner {
78
79
var renderer: zio.test.render.TestRenderer
80
var shutdownHook: Option[() => Unit]
81
val summaries: java.util.concurrent.atomic.AtomicReference[Vector[zio.test.Summary]]
82
83
def sendSummary(implicit trace: zio.Trace): SendSummary
84
def done(): String
85
def tasks(defs: Array[sbt.testing.TaskDef]): Array[sbt.testing.Task]
86
def tasksZ(defs: Array[sbt.testing.TaskDef], console: zio.Console)(implicit trace: zio.Trace): Array[ZTestTask[zio.test.TestOutput]]
87
}
88
```
89
90
### Properties
91
92
- `renderer`: Configurable test output renderer (default: `ConsoleRenderer`)
93
- `shutdownHook`: Optional cleanup function executed when tests complete
94
- `summaries`: Thread-safe collection of test summaries from all executed tasks
95
96
### Methods
97
98
#### sendSummary
99
100
Creates a summary sender that collects results for final reporting.
101
102
```scala
103
implicit val trace: zio.Trace = zio.Trace.empty
104
val sender = runner.sendSummary
105
// Returns: SendSummary
106
```
107
108
#### done
109
110
Completes test execution and returns formatted summary.
111
112
```scala
113
val result = runner.done()
114
// Returns: String with formatted test results
115
```
116
117
**Behavior:**
118
- Aggregates all collected summaries
119
- Renders final results using the configured renderer
120
- Prints results directly to console (workaround for SBT forked JVM bug)
121
- Executes shutdown hooks for cleanup
122
123
#### tasks
124
125
Creates SBT tasks from task definitions.
126
127
```scala
128
val tasks = runner.tasks(taskDefs)
129
// Returns: Array[sbt.testing.Task]
130
```
131
132
#### tasksZ
133
134
ZIO-native version of task creation with enhanced configuration.
135
136
**Parameters:**
137
- `defs`: Array of SBT task definitions
138
- `console`: ZIO Console implementation
139
140
**Returns:** Array of `ZTestTask[TestOutput]` with shared runtime and layers
141
142
### JVM ZTestTask
143
144
Enhanced task implementation with signal handling.
145
146
```scala { .api }
147
final class ZTestTask[T](
148
taskDef: sbt.testing.TaskDef,
149
testClassLoader: ClassLoader,
150
sendSummary: SendSummary,
151
testArgs: zio.test.TestArgs,
152
spec: zio.test.ZIOSpecAbstract,
153
runtime: zio.Runtime[T],
154
console: zio.Console
155
) extends BaseTestTask(taskDef, testClassLoader, sendSummary, testArgs, spec, runtime, console)
156
```
157
158
#### Signal Handling
159
160
The JVM implementation includes signal handlers for debugging:
161
162
```scala
163
// Install handlers for fiber dumping
164
// Windows: SIGINT (Ctrl+C)
165
// Unix: SIGINFO, SIGUSR1
166
private def installSignalHandlers(): Unit
167
```
168
169
## JavaScript Test Runners
170
171
JavaScript platform runners support distributed testing patterns.
172
173
### Master Runner
174
175
```scala { .api }
176
final class ZMasterTestRunnerJS(
177
args: Array[String],
178
remoteArgs: Array[String],
179
testClassLoader: ClassLoader
180
) extends ZTestRunnerJS(args, remoteArgs, testClassLoader, "master")
181
```
182
183
Used for single-process test execution.
184
185
### Slave Runner
186
187
```scala { .api }
188
final class ZSlaveTestRunnerJS(
189
args: Array[String],
190
remoteArgs: Array[String],
191
testClassLoader: ClassLoader,
192
sendSummary: SendSummary
193
) extends ZTestRunnerJS(args, remoteArgs, testClassLoader, "slave")
194
```
195
196
Used in distributed testing scenarios with custom summary handling.
197
198
### Base JavaScript Runner
199
200
```scala { .api }
201
sealed abstract class ZTestRunnerJS(
202
val args: Array[String],
203
val remoteArgs: Array[String],
204
testClassLoader: ClassLoader,
205
runnerType: String
206
) extends sbt.testing.Runner {
207
208
def sendSummary: SendSummary
209
val summaries: scala.collection.mutable.Buffer[zio.test.Summary]
210
211
def done(): String
212
def tasks(defs: Array[sbt.testing.TaskDef]): Array[sbt.testing.Task]
213
def receiveMessage(summary: String): Option[String]
214
def serializeTask(task: sbt.testing.Task, serializer: sbt.testing.TaskDef => String): String
215
def deserializeTask(task: String, deserializer: String => sbt.testing.TaskDef): sbt.testing.Task
216
}
217
```
218
219
## Native Test Runners
220
221
Native platform runners with optimized concurrency primitives.
222
223
### Master Runner
224
225
```scala { .api }
226
final class ZMasterTestRunner(
227
args: Array[String],
228
remoteArgs: Array[String],
229
testClassLoader: ClassLoader
230
) extends ZTestRunnerNative(args, remoteArgs, testClassLoader, "master")
231
```
232
233
### Slave Runner
234
235
```scala { .api }
236
final class ZSlaveTestRunner(
237
args: Array[String],
238
remoteArgs: Array[String],
239
testClassLoader: ClassLoader,
240
sendSummary: SendSummary
241
) extends ZTestRunnerNative(args, remoteArgs, testClassLoader, "slave")
242
```
243
244
### Base Native Runner
245
246
```scala { .api }
247
sealed abstract class ZTestRunnerNative(
248
val args: Array[String],
249
remoteArgs0: Array[String],
250
testClassLoader: ClassLoader,
251
runnerType: String
252
) extends sbt.testing.Runner {
253
254
def remoteArgs(): Array[String]
255
def sendSummary: SendSummary
256
val summaries: java.util.concurrent.ConcurrentLinkedQueue[zio.test.Summary]
257
258
def done(): String
259
def tasks(defs: Array[sbt.testing.TaskDef]): Array[sbt.testing.Task]
260
def receiveMessage(summary: String): Option[String]
261
def serializeTask(task: sbt.testing.Task, serializer: sbt.testing.TaskDef => String): String
262
def deserializeTask(task: String, deserializer: String => sbt.testing.TaskDef): sbt.testing.Task
263
}
264
```
265
266
## Usage Examples
267
268
### Creating Custom Runners
269
270
```scala
271
import zio.test.sbt._
272
273
// JVM runner with custom configuration
274
val jvmRunner = new ZTestRunnerJVM(
275
args = Array("--testSearchTerms", "MyTest"),
276
remoteArgs = Array(),
277
testClassLoader = getClass.getClassLoader
278
)
279
280
// Configure custom renderer
281
jvmRunner.renderer = zio.test.render.LogAnnotationRenderer()
282
283
// Add shutdown hook
284
jvmRunner.shutdownHook = Some(() => println("Tests completed"))
285
```
286
287
### Task Execution
288
289
```scala
290
// Create tasks from test definitions
291
val tasks = runner.tasks(taskDefs)
292
293
// Execute tasks with event handling
294
val eventHandler: sbt.testing.EventHandler = ???
295
val loggers: Array[sbt.testing.Logger] = Array()
296
297
tasks.foreach { task =>
298
val subtasks = task.execute(eventHandler, loggers)
299
// Process any returned subtasks
300
}
301
302
// Get final results
303
val summary = runner.done()
304
println(summary)
305
```
306
307
### Cross-Platform Runner Selection
308
309
```scala
310
// Platform-specific runner creation
311
val runner = scala.util.Properties.isJavaAtLeastVersion("1.8") match {
312
case true => new ZTestRunnerJVM(args, remoteArgs, classLoader)
313
case false => ??? // Handle other platforms
314
}
315
```