0
# Cross-Platform Test Execution
1
2
JavaScript and Scala Native test runners with distributed execution support for running tests across multiple processes or workers. These platforms support master/slave execution patterns for parallel test execution and memory isolation.
3
4
## Capabilities
5
6
### JavaScript Platform Runners
7
8
JavaScript platform provides distributed test execution with master/slave coordination for running tests in browser environments or Node.js workers.
9
10
#### ZTestRunnerJS Base Class
11
12
```scala { .api }
13
/**
14
* Abstract base class for JavaScript test runners
15
* Extends sbt.testing.Runner
16
*/
17
abstract class ZTestRunnerJS(
18
val args: Array[String],
19
val remoteArgs: Array[String],
20
testClassLoader: ClassLoader,
21
runnerType: String
22
) extends Runner {
23
/** Abstract summary transmission function */
24
def sendSummary: SendSummary
25
26
/** Mutable buffer for collecting test summaries */
27
val summaries: mutable.Buffer[Summary]
28
29
/** Creates test tasks from task definitions */
30
def tasks(defs: Array[TaskDef]): Array[Task]
31
32
/** Returns final aggregated test results */
33
def done(): String
34
35
/** Handles summary messages in distributed execution */
36
def receiveMessage(summary: String): Option[String]
37
38
/** Serializes tasks for distributed execution */
39
def serializeTask(task: Task, serializer: TaskDef => String): String
40
41
/** Deserializes tasks from distributed execution */
42
def deserializeTask(task: String, deserializer: String => TaskDef): Task
43
}
44
```
45
46
#### ZMasterTestRunnerJS
47
48
Master runner for JavaScript platform that coordinates local test execution.
49
50
```scala { .api }
51
/**
52
* Master runner for JavaScript platform
53
* Handles local test execution and summary collection
54
*/
55
class ZMasterTestRunnerJS(
56
args: Array[String],
57
remoteArgs: Array[String],
58
testClassLoader: ClassLoader
59
) extends ZTestRunnerJS(args, remoteArgs, testClassLoader, "master") {
60
/** Local summary collection implementation */
61
val sendSummary: SendSummary = SendSummary.fromSend { summary =>
62
summaries += summary
63
()
64
}
65
}
66
```
67
68
#### ZSlaveTestRunnerJS
69
70
Slave runner for distributed JavaScript test execution that sends results back to the master.
71
72
```scala { .api }
73
/**
74
* Slave runner for distributed JavaScript test execution
75
* Sends results back to master process
76
*/
77
class ZSlaveTestRunnerJS(
78
args: Array[String],
79
remoteArgs: Array[String],
80
testClassLoader: ClassLoader,
81
val sendSummary: SendSummary
82
) extends ZTestRunnerJS(args, remoteArgs, testClassLoader, "slave")
83
```
84
85
**Usage Example:**
86
87
```javascript
88
// In a web worker or separate Node.js process
89
// Slave runner sends serialized summaries to master
90
const slaveRunner = new ZSlaveTestRunnerJS(args, remoteArgs, classLoader, sendSummary);
91
```
92
93
### Scala Native Platform Runners
94
95
Scala Native platform provides similar distributed execution capabilities optimized for native binary execution.
96
97
#### ZTestRunnerNative Base Class
98
99
```scala { .api }
100
/**
101
* Abstract base class for Scala Native test runners
102
* Extends sbt.testing.Runner
103
*/
104
abstract class ZTestRunnerNative(
105
val args: Array[String],
106
remoteArgs0: Array[String],
107
testClassLoader: ClassLoader,
108
runnerType: String
109
) extends Runner {
110
/** Remote arguments accessor */
111
def remoteArgs(): Array[String] = remoteArgs0
112
113
/** Abstract summary transmission function */
114
def sendSummary: SendSummary
115
116
/** Thread-safe queue for collecting test summaries */
117
val summaries: ConcurrentLinkedQueue[Summary]
118
119
/** Creates test tasks from task definitions */
120
def tasks(defs: Array[TaskDef]): Array[Task]
121
122
/** Returns final aggregated test results with optimized string building */
123
def done(): String
124
125
/** Handles summary messages in distributed execution */
126
def receiveMessage(summary: String): Option[String]
127
128
/** Serializes/deserializes tasks for distributed execution */
129
def serializeTask(task: Task, serializer: TaskDef => String): String
130
def deserializeTask(task: String, deserializer: String => TaskDef): Task
131
}
132
```
133
134
#### Native Platform Implementations
135
136
```scala { .api }
137
/**
138
* Master runner for Scala Native platform
139
*/
140
class ZMasterTestRunner(
141
args: Array[String],
142
remoteArgs: Array[String],
143
testClassLoader: ClassLoader
144
) extends ZTestRunnerNative {
145
/** Local summary collection with thread-safe queue */
146
val sendSummary: SendSummary = SendSummary.fromSend { summary =>
147
summaries.offer(summary)
148
()
149
}
150
}
151
152
/**
153
* Slave runner for distributed Scala Native test execution
154
*/
155
class ZSlaveTestRunner(
156
args: Array[String],
157
remoteArgs: Array[String],
158
testClassLoader: ClassLoader,
159
val sendSummary: SendSummary
160
) extends ZTestRunnerNative
161
```
162
163
### Cross-Platform Test Tasks
164
165
Both JavaScript and Native platforms use similar task implementations that extend the shared `BaseTestTask`.
166
167
#### JavaScript Test Task
168
169
```scala { .api }
170
/**
171
* JavaScript platform test task
172
* Executes tests asynchronously with continuation-based completion
173
*/
174
class ZTestTask(
175
taskDef: TaskDef,
176
testClassLoader: ClassLoader,
177
runnerType: String,
178
sendSummary: SendSummary,
179
testArgs: TestArgs,
180
spec: ZIOSpecAbstract
181
) extends BaseTestTask(
182
taskDef, testClassLoader, sendSummary, testArgs, spec,
183
Runtime.default, zio.Console.ConsoleLive
184
) {
185
/** Asynchronous execution with fiber-based completion handling */
186
def execute(
187
eventHandler: EventHandler,
188
loggers: Array[Logger],
189
continuation: Array[Task] => Unit
190
): Unit
191
}
192
```
193
194
#### Native Test Task
195
196
```scala { .api }
197
/**
198
* Scala Native platform test task
199
* Executes tests synchronously with blocking completion
200
*/
201
class ZTestTask(
202
taskDef: TaskDef,
203
testClassLoader: ClassLoader,
204
runnerType: String,
205
sendSummary: SendSummary,
206
testArgs: TestArgs,
207
spec: ZIOSpecAbstract
208
) extends BaseTestTask(
209
taskDef, testClassLoader, sendSummary, testArgs, spec,
210
zio.Runtime.default, zio.Console.ConsoleLive
211
) {
212
/** Synchronous execution with blocking result waiting */
213
override def execute(
214
eventHandler: EventHandler,
215
loggers: Array[Logger]
216
): Array[sbt.testing.Task]
217
}
218
```
219
220
### Summary Serialization Protocol
221
222
Cross-platform execution requires serializing test summaries for transmission between processes.
223
224
```scala { .api }
225
/**
226
* Serialization protocol for test summaries
227
* Used in JavaScript and Native distributed execution
228
*/
229
object SummaryProtocol {
230
/** Converts Summary to tab-separated string representation */
231
def serialize(summary: Summary): String
232
233
/** Parses string back to Summary object */
234
def deserialize(s: String): Option[Summary]
235
236
/** Escapes tab characters in string tokens for serialization */
237
private def escape(token: String): String
238
239
/** Unescapes tab characters in deserialized tokens */
240
private def unescape(token: String): String
241
}
242
```
243
244
**Usage Example:**
245
246
```scala
247
// Master process receiving results from slave
248
override def receiveMessage(summary: String): Option[String] = {
249
SummaryProtocol.deserialize(summary).foreach { s =>
250
summaries += s // JavaScript: mutable.Buffer
251
// or
252
summaries.offer(s) // Native: ConcurrentLinkedQueue
253
}
254
None
255
}
256
```
257
258
### Platform Differences
259
260
| Feature | JavaScript | Scala Native | JVM |
261
|---------|------------|--------------|-----|
262
| **Execution Model** | Async with continuations | Sync with blocking | Sync with advanced features |
263
| **Summary Storage** | `mutable.Buffer` | `ConcurrentLinkedQueue` | `AtomicReference[Vector]` |
264
| **Distributed Support** | Master/Slave | Master/Slave | Single process |
265
| **Signal Handling** | No | No | Yes (USR1, INFO, INT) |
266
| **Runtime Sharing** | Default runtime | Default runtime | Shared scoped runtime |
267
| **Resource Cleanup** | Basic | Basic | Advanced with shutdown hooks |
268
269
### Configuration Examples
270
271
**JavaScript (Node.js):**
272
```scala
273
// build.sbt
274
scalaJSUseMainModuleInitializer := true
275
testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")
276
```
277
278
**Scala Native:**
279
```scala
280
// build.sbt
281
nativeConfig ~= { _.withMode(Mode.debug) }
282
testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")
283
```