or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cross-platform-execution.mdevent-handling.mdframework-integration.mdindex.mdjvm-execution.md

cross-platform-execution.mddocs/

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

```