0
# JVM Test Execution
1
2
JVM-specific test runner implementation with advanced features including signal handling, shared runtime management, and comprehensive test lifecycle control. The JVM platform provides the most feature-rich implementation of ZIO Test SBT integration.
3
4
## Capabilities
5
6
### ZTestRunnerJVM
7
8
Main JVM test runner that manages the complete test execution lifecycle, including runtime creation, task coordination, and result aggregation.
9
10
```scala { .api }
11
/**
12
* JVM-specific test runner with advanced lifecycle management
13
* Extends sbt.testing.Runner
14
*/
15
class ZTestRunnerJVM(
16
val args: Array[String],
17
val remoteArgs: Array[String],
18
testClassLoader: ClassLoader
19
) extends Runner {
20
/** Current test renderer (mutable, updated based on test args) */
21
@volatile var renderer: TestRenderer
22
23
/** Optional cleanup hook for runtime shutdown */
24
@volatile var shutdownHook: Option[() => Unit]
25
26
/** Thread-safe collection of test execution summaries */
27
val summaries: AtomicReference[Vector[Summary]]
28
29
/** Creates test tasks from SBT task definitions */
30
def tasks(defs: Array[TaskDef]): Array[Task]
31
32
/** Returns final aggregated test results and performs cleanup */
33
def done(): String
34
35
/** Internal task creation with ZIO Console integration */
36
def tasksZ(
37
defs: Array[TaskDef],
38
console: zio.Console
39
): Array[ZTestTask[TestOutput]]
40
}
41
```
42
43
**Usage Example:**
44
45
The runner is created automatically by the framework, but you can observe its behavior:
46
47
```scala
48
// The runner processes all discovered test classes
49
// and creates individual tasks for execution
50
sbt test // Triggers runner.tasks() -> task.execute() -> runner.done()
51
```
52
53
### ZTestTask for JVM
54
55
JVM-specific test task implementation that extends the base task with signal handling capabilities for debugging and monitoring.
56
57
```scala { .api }
58
/**
59
* JVM test task with signal handling support
60
* Extends BaseTestTask with JVM-specific features
61
*/
62
class ZTestTask[T](
63
taskDef: TaskDef,
64
testClassLoader: ClassLoader,
65
sendSummary: SendSummary,
66
testArgs: TestArgs,
67
spec: ZIOSpecAbstract,
68
runtime: zio.Runtime[T],
69
console: zio.Console
70
) extends BaseTestTask(
71
taskDef, testClassLoader, sendSummary, testArgs, spec, runtime, console
72
) {
73
/** Enhanced test execution with signal handler installation */
74
private[zio] def run(eventHandlerZ: ZTestEventHandler)(implicit trace: Trace): ZIO[Any, Throwable, Unit]
75
76
/** Installs signal handlers for fiber debugging (JVM-specific) */
77
private def installSignalHandlers()(implicit trace: Trace): Unit
78
}
79
```
80
81
**Signal Handling:**
82
83
The JVM implementation installs signal handlers for debugging:
84
- **Windows**: `INT` signal dumps fiber information
85
- **Unix/Linux**: `INFO` and `USR1` signals dump fiber information
86
87
```bash
88
# Send signal to dump running fibers (Unix/Linux)
89
kill -USR1 <pid>
90
91
# On Windows, Ctrl+C triggers fiber dump
92
```
93
94
### Runtime and Resource Management
95
96
The JVM runner creates sophisticated runtime environments with proper resource management:
97
98
```scala { .api }
99
/**
100
* Creates scoped runtime with shared layers and proper cleanup
101
*/
102
val runtime: Runtime.Scoped[TestOutput] =
103
zio.Runtime.unsafe.fromLayer(sharedLayer)(Trace.empty, Unsafe.unsafe)
104
105
val shutdownHook: Option[() => Unit] =
106
Some(() => runtime.unsafe.shutdown()(Unsafe.unsafe))
107
```
108
109
**Resource Lifecycle:**
110
111
1. **Initialization**: Creates shared `ZLayer` combining all test spec bootstrap layers
112
2. **Execution**: Runs tests within the scoped runtime context
113
3. **Cleanup**: Automatically shuts down runtime and releases resources via shutdown hook
114
115
### Test Argument Processing
116
117
The JVM runner processes and applies test arguments for filtering and configuration:
118
119
```scala { .api }
120
/**
121
* Processes command-line arguments into structured TestArgs
122
*/
123
val testArgs: TestArgs = TestArgs.parse(args)
124
125
// Updates renderer based on arguments
126
renderer = testArgs.testRenderer
127
128
// Creates event printer layer with specified renderer
129
val sharedTestOutputLayer =
130
ExecutionEventPrinter.live(console, testArgs.testEventRenderer) >>>
131
TestOutput.live
132
```
133
134
**Common Test Arguments:**
135
136
```bash
137
# Run tests with specific renderer
138
sbt "test -- --format pretty"
139
140
# Run tests matching pattern
141
sbt "test -- --grep 'user login'"
142
143
# Run tests with tags
144
sbt "test -- --tags integration"
145
```
146
147
### Summary Collection and Reporting
148
149
The JVM runner collects and aggregates test results with comprehensive reporting:
150
151
```scala { .api }
152
/**
153
* Thread-safe summary collection
154
*/
155
val summaries: AtomicReference[Vector[Summary]] =
156
new AtomicReference(Vector.empty)
157
158
def sendSummary: SendSummary = SendSummary.fromSendZIO { summary =>
159
ZIO.succeed {
160
summaries.updateAndGet(_ :+ summary)
161
()
162
}
163
}
164
165
/**
166
* Generates final test report with colored output
167
*/
168
def done(): String = {
169
val allSummaries = summaries.get
170
val total = allSummaries.map(_.total).sum
171
val ignore = allSummaries.map(_.ignore).sum
172
173
val compositeSummary = allSummaries.foldLeft(Summary.empty)(_.add(_))
174
val renderedSummary = renderer.renderSummary(compositeSummary)
175
176
// Returns colored summary or appropriate message for no tests
177
if (allSummaries.nonEmpty && total != ignore)
178
colored(renderedSummary)
179
else if (ignore > 0)
180
s"${Console.YELLOW}All eligible tests are currently ignored${Console.RESET}"
181
else
182
s"${Console.YELLOW}No tests were executed${Console.RESET}"
183
}
184
```
185
186
### Platform-Specific Optimizations
187
188
The JVM implementation includes several optimizations specific to the JVM platform:
189
190
- **Shared Runtime**: Single runtime instance shared across all test tasks for efficiency
191
- **Signal Handlers**: Debug support via OS signals for fiber inspection
192
- **Thread Safety**: Atomic operations for summary collection across concurrent test execution
193
- **Memory Management**: Proper shutdown hooks to prevent resource leaks
194
- **Class Loading**: Sophisticated reflection-based spec loading with portable Scala reflection