or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cross-platform-communication.mdevent-handling.mdframework-integration.mdindex.mdtest-execution.md

test-execution.mddocs/

0

# Test Execution

1

2

The test execution system runs ZIO test specifications and handles platform-specific execution models. It bridges ZIO's effect-based testing system with SBT's imperative test execution model, managing ZIO runtime lifecycle and test result collection.

3

4

## Capabilities

5

6

### BaseTestTask

7

8

Abstract base class that provides the core test execution logic shared across all platforms. It handles ZIO runtime management, test specification loading, and result reporting.

9

10

```scala { .api }

11

/**

12

* Base implementation for ZIO test task execution

13

* Provides core functionality shared across all platforms

14

*/

15

abstract class BaseTestTask(

16

taskDef0: sbt.testing.TaskDef,

17

val testClassLoader: ClassLoader,

18

val sendSummary: SendSummary,

19

val args: zio.test.TestArgs

20

) extends sbt.testing.Task {

21

22

/** Returns the task definition provided by SBT */

23

final def taskDef(): sbt.testing.TaskDef

24

25

/** The class loader used for loading test specifications */

26

val testClassLoader: ClassLoader

27

28

/** Function for transmitting test summaries */

29

val sendSummary: SendSummary

30

31

/** Parsed test arguments from command line */

32

val args: zio.test.TestArgs

33

34

/**

35

* Executes the test task (JVM platforms)

36

* @param eventHandler Handles test events for SBT reporting

37

* @param loggers Array of SBT loggers for output

38

* @return Array of additional tasks to run (typically empty)

39

*/

40

def execute(

41

eventHandler: sbt.testing.EventHandler,

42

loggers: Array[sbt.testing.Logger]

43

): Array[sbt.testing.Task]

44

45

/** Returns empty array - ZIO tests don't use tags */

46

def tags(): Array[String]

47

}

48

```

49

50

**Protected Members:**

51

52

```scala { .api }

53

/**

54

* Lazily loaded test specification instance

55

* Uses reflection to load the object specified by taskDef

56

*/

57

protected lazy val specInstance: zio.test.AbstractRunnableSpec

58

59

/**

60

* Core test execution logic as a ZIO effect

61

* @param eventHandler SBT event handler for reporting results

62

* @return ZIO effect that runs the test and reports results

63

*/

64

protected def run(

65

eventHandler: sbt.testing.EventHandler

66

): zio.ZIO[zio.test.TestLogger with zio.clock.Clock, Throwable, Unit]

67

68

/**

69

* Creates ZIO layer with test logging and clock services

70

* @param loggers SBT loggers to integrate with ZIO's TestLogger

71

* @return ZIO layer providing TestLogger and Clock services

72

*/

73

protected def sbtTestLayer(

74

loggers: Array[sbt.testing.Logger]

75

): zio.Layer[Nothing, zio.test.TestLogger with zio.clock.Clock]

76

```

77

78

### ZTestRunner (JVM Platform)

79

80

JVM-specific test runner implementation that provides synchronous test execution with thread-safe summary collection.

81

82

```scala { .api }

83

/**

84

* JVM-specific test runner with synchronous execution

85

* Collects summaries in thread-safe manner for final reporting

86

*/

87

class ZTestRunner(

88

val args: Array[String],

89

val remoteArgs: Array[String],

90

testClassLoader: ClassLoader

91

) extends sbt.testing.Runner {

92

93

/** Command line arguments passed to the test framework */

94

val args: Array[String]

95

96

/** Remote arguments for distributed testing */

97

val remoteArgs: Array[String]

98

99

/** Thread-safe collection of test summaries */

100

val summaries: java.util.concurrent.atomic.AtomicReference[Vector[zio.test.Summary]]

101

102

/** Summary transmission function that collects summaries locally */

103

val sendSummary: SendSummary

104

105

/**

106

* Creates test tasks from task definitions

107

* @param defs Array of task definitions discovered by SBT

108

* @return Array of ZTestTask instances ready for execution

109

*/

110

def tasks(defs: Array[sbt.testing.TaskDef]): Array[sbt.testing.Task]

111

112

/**

113

* Returns final test execution summary

114

* Called by SBT after all tests complete

115

* @return Formatted summary string with test results

116

*/

117

def done(): String

118

}

119

```

120

121

**Usage Example:**

122

123

```scala

124

// Automatically created by ZTestFramework - not used directly

125

// When SBT runs tests, it:

126

// 1. Calls ZTestFramework.runner() to create ZTestRunner

127

// 2. Calls runner.tasks() to get test tasks

128

// 3. Executes each task via task.execute()

129

// 4. Calls runner.done() for final summary

130

131

// Example test task execution flow:

132

val runner = new ZTestRunner(args, remoteArgs, classLoader)

133

val tasks = runner.tasks(discoveredTaskDefs)

134

tasks.foreach(_.execute(eventHandler, loggers))

135

val summary = runner.done()

136

```

137

138

### ZTestTask (JVM Platform)

139

140

JVM-specific test task implementation that extends `BaseTestTask` with synchronous execution.

141

142

```scala { .api }

143

/**

144

* JVM-specific test task implementation

145

* Provides synchronous test execution using ZIO runtime

146

*/

147

class ZTestTask(

148

taskDef: sbt.testing.TaskDef,

149

testClassLoader: ClassLoader,

150

sendSummary: SendSummary,

151

testArgs: zio.test.TestArgs

152

) extends BaseTestTask(taskDef, testClassLoader, sendSummary, testArgs)

153

```

154

155

### ZTestRunner (JavaScript/Native Platforms)

156

157

Base runner implementation for JavaScript and Native platforms that supports asynchronous execution and inter-process communication.

158

159

```scala { .api }

160

/**

161

* Base runner for JS/Native platforms with async execution support

162

* Handles serialization for inter-process communication

163

*/

164

sealed abstract class ZTestRunner(

165

val args: Array[String],

166

val remoteArgs: Array[String],

167

testClassLoader: ClassLoader,

168

runnerType: String

169

) extends sbt.testing.Runner {

170

171

/** Abstract summary transmission function - implemented by subclasses */

172

def sendSummary: SendSummary

173

174

/** Mutable buffer for collecting test summaries */

175

val summaries: scala.collection.mutable.Buffer[zio.test.Summary]

176

177

/**

178

* Creates test tasks from task definitions

179

* @param defs Array of task definitions discovered by SBT

180

* @return Array of ZTestTask instances for async execution

181

*/

182

def tasks(defs: Array[sbt.testing.TaskDef]): Array[sbt.testing.Task]

183

184

/**

185

* Returns final test execution summary

186

* @return Formatted summary string with test results

187

*/

188

def done(): String

189

190

/**

191

* Handles serialized summary messages from slave processes

192

* @param summary Serialized summary string

193

* @return Optional response message

194

*/

195

def receiveMessage(summary: String): Option[String]

196

197

/**

198

* Serializes a task for inter-process communication

199

* @param task Task to serialize

200

* @param serializer Function to serialize TaskDef

201

* @return Serialized task string

202

*/

203

def serializeTask(task: sbt.testing.Task, serializer: sbt.testing.TaskDef => String): String

204

205

/**

206

* Deserializes a task from inter-process communication

207

* @param task Serialized task string

208

* @param deserializer Function to deserialize TaskDef

209

* @return Deserialized task instance

210

*/

211

def deserializeTask(task: String, deserializer: String => sbt.testing.TaskDef): sbt.testing.Task

212

}

213

```

214

215

### ZMasterTestRunner

216

217

Master runner implementation for multi-process test execution on JS/Native platforms.

218

219

```scala { .api }

220

/**

221

* Master runner for multi-process execution

222

* Collects summaries locally when running single-process tests

223

*/

224

class ZMasterTestRunner(

225

args: Array[String],

226

remoteArgs: Array[String],

227

testClassLoader: ClassLoader

228

) extends ZTestRunner(args, remoteArgs, testClassLoader, "master") {

229

230

/** Local summary collection implementation */

231

val sendSummary: SendSummary

232

}

233

```

234

235

### ZSlaveTestRunner

236

237

Slave runner implementation that transmits results to master process.

238

239

```scala { .api }

240

/**

241

* Slave runner for distributed execution

242

* Transmits summaries to master process via provided send function

243

*/

244

class ZSlaveTestRunner(

245

args: Array[String],

246

remoteArgs: Array[String],

247

testClassLoader: ClassLoader,

248

val sendSummary: SendSummary

249

) extends ZTestRunner(args, remoteArgs, testClassLoader, "slave")

250

```

251

252

### ZTestTask (JavaScript/Native Platforms)

253

254

Asynchronous test task implementation for JS/Native platforms with continuation-based execution.

255

256

```scala { .api }

257

/**

258

* Asynchronous test task for JS/Native platforms

259

* Uses continuation-based execution model

260

*/

261

class ZTestTask(

262

taskDef: sbt.testing.TaskDef,

263

testClassLoader: ClassLoader,

264

runnerType: String,

265

sendSummary: SendSummary,

266

testArgs: zio.test.TestArgs

267

) extends BaseTestTask(taskDef, testClassLoader, sendSummary, testArgs) {

268

269

/**

270

* Executes test asynchronously with continuation

271

* @param eventHandler SBT event handler for reporting

272

* @param loggers Array of SBT loggers

273

* @param continuation Callback invoked when execution completes

274

*/

275

def execute(

276

eventHandler: sbt.testing.EventHandler,

277

loggers: Array[sbt.testing.Logger],

278

continuation: Array[sbt.testing.Task] => Unit

279

): Unit

280

}

281

```

282

283

### ZTestTaskPolicy

284

285

Policy interface for customizing test task execution and merging behavior.

286

287

```scala { .api }

288

/**

289

* Abstract policy for merging and customizing test tasks

290

* Allows customization of test execution behavior

291

*/

292

abstract class ZTestTaskPolicy {

293

/**

294

* Merges ZIO test tasks according to policy

295

* @param zioTasks Array of ZIO test tasks to merge

296

* @return Array of tasks to execute (may be modified or filtered)

297

*/

298

def merge(zioTasks: Array[ZTestTask]): Array[sbt.testing.Task]

299

}

300

301

/**

302

* Default policy implementation that passes through tasks unchanged

303

*/

304

class ZTestTaskPolicyDefaultImpl extends ZTestTaskPolicy {

305

def merge(zioTasks: Array[ZTestTask]): Array[sbt.testing.Task] = zioTasks.toArray

306

}

307

```

308

309

**Custom Policy Example:**

310

311

```scala

312

// Custom policy that groups tests for batch execution

313

class BatchingTestPolicy extends ZTestTaskPolicy {

314

def merge(zioTasks: Array[ZTestTask]): Array[sbt.testing.Task] = {

315

// Custom logic to group or filter tasks

316

// Could implement parallel execution, test ordering, etc.

317

zioTasks.toArray

318

}

319

}

320

321

// Usage via system property or test args

322

// -Dzio.test.sbt.testTaskPolicy=com.example.BatchingTestPolicy

323

```

324

325

## Test Execution Flow

326

327

The test execution process follows these steps:

328

329

1. **Task Creation**: SBT creates `TaskDef` instances for discovered test specifications

330

2. **Runner Creation**: Framework creates appropriate runner (JVM/Master/Slave) based on platform

331

3. **Task Generation**: Runner creates `ZTestTask` instances from `TaskDef`s

332

4. **Policy Application**: Task policy merges/filters tasks as needed

333

5. **Test Execution**: Each task:

334

- Loads the test specification using reflection

335

- Creates ZIO runtime with test logger layer

336

- Executes the ZIO test specification

337

- Converts results to SBT events

338

- Transmits summary via `SendSummary`

339

6. **Summary Collection**: Runner collects summaries from all tasks

340

7. **Final Reporting**: Runner returns formatted summary via `done()`

341

342

The system handles platform differences transparently while maintaining consistent behavior across JVM, JavaScript, and Native platforms.